sdread.c revision 1.3
1/*	$NetBSD: sdread.c,v 1.3 2010/02/17 20:43:35 pooka Exp $	*/
2
3/*
4 * Copyright (c) 2009 Antti Kantee.  All Rights Reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
9 * 1. Redistributions of source code must retain the above copyright
10 *    notice, this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 *    notice, this list of conditions and the following disclaimer in the
13 *    documentation and/or other materials provided with the distribution.
14 *
15 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
16 * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
17 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
18 * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
19 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
21 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
25 * SUCH DAMAGE.
26 */
27
28#include <sys/types.h>
29#include <sys/dirent.h>
30#include <sys/mount.h>
31
32#include <ufs/ufs/ufsmount.h>
33#include <msdosfs/msdosfsmount.h>
34#include <isofs/cd9660/cd9660_mount.h>
35
36#include <rump/rump.h>
37#include <rump/rump_syscalls.h>
38
39#include <err.h>
40#include <errno.h>
41#include <fcntl.h>
42#include <stdio.h>
43#include <stdlib.h>
44#include <string.h>
45#include <unistd.h>
46
47/*
48 * Proof-of-concept program:
49 *
50 * Mount rump file system from device driver stack included in the
51 * rump kernel.  Optionally copy a file out of the mounted file system.
52 */
53
54int
55main(int argc, char *argv[])
56{
57	char buf[2048];
58	struct msdosfs_args args;
59	struct ufs_args uargs;
60	struct iso_args iargs;
61	struct dirent *dp;
62	const char *msg = NULL;
63	int fd, n, fd_h, sverrno;
64	int probeonly = 0;
65
66	if (argc > 1) {
67		if (argc == 2 && strcmp(argv[1], "probe") == 0) {
68			probeonly = 1;
69		} else if (argc != 3) {
70			fprintf(stderr, "usage: a.out [src hostdest]\n");
71			exit(1);
72		}
73	}
74
75	memset(&args, 0, sizeof(args));
76	args.fspec = strdup("/dev/sd0e");
77	args.version = MSDOSFSMNT_VERSION;
78
79	memset(&uargs, 0, sizeof(uargs));
80	uargs.fspec = strdup("/dev/sd0e");
81
82	memset(&iargs, 0, sizeof(iargs));
83	iargs.fspec = strdup("/dev/cd0a");
84
85	if (probeonly)
86		rump_boot_sethowto(RUMP_AB_VERBOSE);
87	rump_init();
88	if (probeonly) {
89		exit(0);
90	}
91
92	if (rump_sys_mkdir("/mp", 0777) == -1)
93		err(1, "mkdir");
94	if (rump_sys_mount(MOUNT_MSDOS, "/mp", MNT_RDONLY,
95	    &args, sizeof(args)) == -1) {
96		if (rump_sys_mount(MOUNT_FFS, "/mp", MNT_RDONLY,
97		    &uargs, sizeof(uargs)) == -1) {
98			printf("Trying CD.  This might fail with "
99			    "\"media not present\".\n");
100			printf("If that happens, wait a while without "
101			    "unplugging the device and re-run.\n");
102			printf("Some devices apparently need a long time "
103			    "to settle after they are initialized.\n\n");
104
105			if (rump_sys_mount(MOUNT_CD9660, "/mp", MNT_RDONLY,
106			    &iargs, sizeof(iargs)) == -1) {
107				err(1, "mount");
108			}
109		}
110	}
111
112	fd = rump_sys_open("/mp", O_RDONLY, 0);
113	if (fd == -1) {
114		msg = "open dir";
115		goto out;
116	}
117
118	while ((n = rump_sys_getdents(fd, buf, sizeof(buf))) > 0) {
119		for (dp = (struct dirent *)buf;
120		    (char *)dp - buf < n;
121		    dp = _DIRENT_NEXT(dp)) {
122			printf("%" PRIu64 ": %s\n", dp->d_fileno, dp->d_name);
123		}
124	}
125	rump_sys_close(fd);
126	if (argc == 1)
127		goto out;
128
129	rump_sys_chdir("/mp");
130	fd = rump_sys_open(argv[1], O_RDONLY, 0);
131	if (fd == -1) {
132		msg = "open fs file";
133		goto out;
134	}
135
136	fd_h = open(argv[2], O_RDWR | O_CREAT, 0777);
137	if (fd_h == -1) {
138		msg = "open host file";
139		goto out;
140	}
141
142	while ((n = rump_sys_read(fd, buf, sizeof(buf))) == sizeof(buf)) {
143		if (write(fd_h, buf, sizeof(buf)) != sizeof(buf)) {
144			msg = "write host file";
145			goto out;
146		}
147	}
148	if (n == -1) {
149		msg = "read fs file";
150		goto out;
151	}
152
153	if (n > 0) {
154		if (write(fd_h, buf, n) == -1)
155			msg = "write tail";
156	}
157
158 out:
159	sverrno = errno;
160	rump_sys_chdir("/");
161	rump_sys_close(fd);
162	close(fd_h);
163	if (rump_sys_unmount("/mp", 0) == -1)
164		err(1, "unmount");
165
166	if (msg) {
167		errno = sverrno;
168		err(1, "%s", msg);
169	}
170
171	return 0;
172}
173