xref: /netbsd-src/share/examples/rump/sdread/sdread.c (revision 7fb0f92c04844032d93e4861786a3caa0d753621)
1*7fb0f92cSpooka /*	$NetBSD: sdread.c,v 1.6 2010/03/25 15:00:20 pooka Exp $	*/
227fd3f65Spooka 
327fd3f65Spooka /*
427fd3f65Spooka  * Copyright (c) 2009 Antti Kantee.  All Rights Reserved.
527fd3f65Spooka  *
627fd3f65Spooka  * Redistribution and use in source and binary forms, with or without
727fd3f65Spooka  * modification, are permitted provided that the following conditions
827fd3f65Spooka  * are met:
927fd3f65Spooka  * 1. Redistributions of source code must retain the above copyright
1027fd3f65Spooka  *    notice, this list of conditions and the following disclaimer.
1127fd3f65Spooka  * 2. Redistributions in binary form must reproduce the above copyright
1227fd3f65Spooka  *    notice, this list of conditions and the following disclaimer in the
1327fd3f65Spooka  *    documentation and/or other materials provided with the distribution.
1427fd3f65Spooka  *
1527fd3f65Spooka  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
1627fd3f65Spooka  * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
1727fd3f65Spooka  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
1827fd3f65Spooka  * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
1927fd3f65Spooka  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
2027fd3f65Spooka  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
2127fd3f65Spooka  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
2227fd3f65Spooka  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
2327fd3f65Spooka  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
2427fd3f65Spooka  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
2527fd3f65Spooka  * SUCH DAMAGE.
2627fd3f65Spooka  */
2727fd3f65Spooka 
2827fd3f65Spooka #include <sys/types.h>
2927fd3f65Spooka #include <sys/dirent.h>
3027fd3f65Spooka #include <sys/mount.h>
3107cd2d7fSpooka #include <sys/dkio.h>
3227fd3f65Spooka 
33f75f5aaeSpooka #include <ufs/ufs/ufsmount.h>
3427fd3f65Spooka #include <msdosfs/msdosfsmount.h>
3501ce72ceSpooka #include <isofs/cd9660/cd9660_mount.h>
3627fd3f65Spooka 
3727fd3f65Spooka #include <rump/rump.h>
3827fd3f65Spooka #include <rump/rump_syscalls.h>
3927fd3f65Spooka 
4027fd3f65Spooka #include <err.h>
4127fd3f65Spooka #include <errno.h>
4227fd3f65Spooka #include <fcntl.h>
4327fd3f65Spooka #include <stdio.h>
4427fd3f65Spooka #include <stdlib.h>
4527fd3f65Spooka #include <string.h>
4627fd3f65Spooka #include <unistd.h>
4727fd3f65Spooka 
4827fd3f65Spooka /*
4927fd3f65Spooka  * Proof-of-concept program:
5027fd3f65Spooka  *
5127fd3f65Spooka  * Mount rump file system from device driver stack included in the
5227fd3f65Spooka  * rump kernel.  Optionally copy a file out of the mounted file system.
5327fd3f65Spooka  */
5427fd3f65Spooka 
5507cd2d7fSpooka /* recent -current, appease 5.0 etc. userland */
5607cd2d7fSpooka #ifndef DIOCTUR
5707cd2d7fSpooka #define DIOCTUR _IOR('d', 128, int)
5807cd2d7fSpooka #endif
5907cd2d7fSpooka 
6007cd2d7fSpooka static void
waitcd(void)6107cd2d7fSpooka waitcd(void)
6207cd2d7fSpooka {
6307cd2d7fSpooka 	int fd, val = 0, rounds = 0;
6407cd2d7fSpooka 
6507cd2d7fSpooka 	fd = rump_sys_open("/dev/rcd0d", O_RDWR);
66*7fb0f92cSpooka 	if (fd == -1)
67*7fb0f92cSpooka 		return;
68*7fb0f92cSpooka 
6907cd2d7fSpooka 	do {
7007cd2d7fSpooka 		if (rounds > 0) {
7107cd2d7fSpooka 			if (rounds == 1) {
7207cd2d7fSpooka 				printf("Waiting for CD device to settle ");
7307cd2d7fSpooka 			} else {
7407cd2d7fSpooka 				printf(".");
7507cd2d7fSpooka 			}
7607cd2d7fSpooka 			fflush(stdout);
7707cd2d7fSpooka 			sleep(1);
7807cd2d7fSpooka 		}
7907cd2d7fSpooka 		if (rump_sys_ioctl(fd, DIOCTUR, &val) == -1)
8007cd2d7fSpooka 			err(1, "DIOCTUR");
8107cd2d7fSpooka 		rounds++;
8207cd2d7fSpooka 	} while (val == 0 || rounds >= 30);
8307cd2d7fSpooka 
8407cd2d7fSpooka 	if (!val)
8507cd2d7fSpooka 		printf(" giving up\n");
8607cd2d7fSpooka 	else
8707cd2d7fSpooka 		printf(" done!\n");
88*7fb0f92cSpooka 
89*7fb0f92cSpooka 	rump_sys_close(fd);
9007cd2d7fSpooka }
9107cd2d7fSpooka 
9227fd3f65Spooka int
main(int argc,char * argv[])9327fd3f65Spooka main(int argc, char *argv[])
9427fd3f65Spooka {
9527fd3f65Spooka 	char buf[2048];
9627fd3f65Spooka 	struct msdosfs_args args;
97f75f5aaeSpooka 	struct ufs_args uargs;
9801ce72ceSpooka 	struct iso_args iargs;
9927fd3f65Spooka 	struct dirent *dp;
10027fd3f65Spooka 	const char *msg = NULL;
10127fd3f65Spooka 	int fd, n, fd_h, sverrno;
10201ce72ceSpooka 	int probeonly = 0;
10327fd3f65Spooka 
10401ce72ceSpooka 	if (argc > 1) {
10501ce72ceSpooka 		if (argc == 2 && strcmp(argv[1], "probe") == 0) {
10601ce72ceSpooka 			probeonly = 1;
10701ce72ceSpooka 		} else if (argc != 3) {
10827fd3f65Spooka 			fprintf(stderr, "usage: a.out [src hostdest]\n");
10927fd3f65Spooka 			exit(1);
11027fd3f65Spooka 		}
11101ce72ceSpooka 	}
11227fd3f65Spooka 
11327fd3f65Spooka 	memset(&args, 0, sizeof(args));
11427fd3f65Spooka 	args.fspec = strdup("/dev/sd0e");
11527fd3f65Spooka 	args.version = MSDOSFSMNT_VERSION;
11627fd3f65Spooka 
117f75f5aaeSpooka 	memset(&uargs, 0, sizeof(uargs));
118f75f5aaeSpooka 	uargs.fspec = strdup("/dev/sd0e");
119f75f5aaeSpooka 
12001ce72ceSpooka 	memset(&iargs, 0, sizeof(iargs));
12101ce72ceSpooka 	iargs.fspec = strdup("/dev/cd0a");
12201ce72ceSpooka 
12301ce72ceSpooka 	if (probeonly)
12401ce72ceSpooka 		rump_boot_sethowto(RUMP_AB_VERBOSE);
12527fd3f65Spooka 	rump_init();
12601ce72ceSpooka 	if (probeonly) {
12728ef056fSpooka 		pause();
12801ce72ceSpooka 		exit(0);
12901ce72ceSpooka 	}
13027fd3f65Spooka 
13127fd3f65Spooka 	if (rump_sys_mkdir("/mp", 0777) == -1)
13227fd3f65Spooka 		err(1, "mkdir");
13327fd3f65Spooka 	if (rump_sys_mount(MOUNT_MSDOS, "/mp", MNT_RDONLY,
134f75f5aaeSpooka 	    &args, sizeof(args)) == -1) {
135f75f5aaeSpooka 		if (rump_sys_mount(MOUNT_FFS, "/mp", MNT_RDONLY,
136f75f5aaeSpooka 		    &uargs, sizeof(uargs)) == -1) {
13707cd2d7fSpooka 			/*
13807cd2d7fSpooka 			 * Wait for CD media to settle.  In the end,
13907cd2d7fSpooka 			 * just try to do it anyway and see if we fail.
14007cd2d7fSpooka 			 */
14107cd2d7fSpooka 			waitcd();
14201ce72ceSpooka 			if (rump_sys_mount(MOUNT_CD9660, "/mp", MNT_RDONLY,
14301ce72ceSpooka 			    &iargs, sizeof(iargs)) == -1) {
14427fd3f65Spooka 				err(1, "mount");
145f75f5aaeSpooka 			}
146f75f5aaeSpooka 		}
14701ce72ceSpooka 	}
14827fd3f65Spooka 
14927fd3f65Spooka 	fd = rump_sys_open("/mp", O_RDONLY, 0);
15027fd3f65Spooka 	if (fd == -1) {
15127fd3f65Spooka 		msg = "open dir";
15227fd3f65Spooka 		goto out;
15327fd3f65Spooka 	}
15427fd3f65Spooka 
15527fd3f65Spooka 	while ((n = rump_sys_getdents(fd, buf, sizeof(buf))) > 0) {
15627fd3f65Spooka 		for (dp = (struct dirent *)buf;
15727fd3f65Spooka 		    (char *)dp - buf < n;
15827fd3f65Spooka 		    dp = _DIRENT_NEXT(dp)) {
15927fd3f65Spooka 			printf("%" PRIu64 ": %s\n", dp->d_fileno, dp->d_name);
16027fd3f65Spooka 		}
16127fd3f65Spooka 	}
16227fd3f65Spooka 	rump_sys_close(fd);
16327fd3f65Spooka 	if (argc == 1)
16427fd3f65Spooka 		goto out;
16527fd3f65Spooka 
16627fd3f65Spooka 	rump_sys_chdir("/mp");
16727fd3f65Spooka 	fd = rump_sys_open(argv[1], O_RDONLY, 0);
16827fd3f65Spooka 	if (fd == -1) {
16927fd3f65Spooka 		msg = "open fs file";
17027fd3f65Spooka 		goto out;
17127fd3f65Spooka 	}
17227fd3f65Spooka 
17327fd3f65Spooka 	fd_h = open(argv[2], O_RDWR | O_CREAT, 0777);
17427fd3f65Spooka 	if (fd_h == -1) {
17527fd3f65Spooka 		msg = "open host file";
17627fd3f65Spooka 		goto out;
17727fd3f65Spooka 	}
17827fd3f65Spooka 
17927fd3f65Spooka 	while ((n = rump_sys_read(fd, buf, sizeof(buf))) == sizeof(buf)) {
18027fd3f65Spooka 		if (write(fd_h, buf, sizeof(buf)) != sizeof(buf)) {
18127fd3f65Spooka 			msg = "write host file";
18227fd3f65Spooka 			goto out;
18327fd3f65Spooka 		}
18427fd3f65Spooka 	}
18527fd3f65Spooka 	if (n == -1) {
18627fd3f65Spooka 		msg = "read fs file";
18727fd3f65Spooka 		goto out;
18827fd3f65Spooka 	}
18927fd3f65Spooka 
19027fd3f65Spooka 	if (n > 0) {
19127fd3f65Spooka 		if (write(fd_h, buf, n) == -1)
19227fd3f65Spooka 			msg = "write tail";
19327fd3f65Spooka 	}
19427fd3f65Spooka 
19527fd3f65Spooka  out:
19627fd3f65Spooka 	sverrno = errno;
19727fd3f65Spooka 	rump_sys_chdir("/");
19827fd3f65Spooka 	rump_sys_close(fd);
19927fd3f65Spooka 	close(fd_h);
20027fd3f65Spooka 	if (rump_sys_unmount("/mp", 0) == -1)
20127fd3f65Spooka 		err(1, "unmount");
20227fd3f65Spooka 
20327fd3f65Spooka 	if (msg) {
20427fd3f65Spooka 		errno = sverrno;
20527fd3f65Spooka 		err(1, "%s", msg);
20627fd3f65Spooka 	}
20727fd3f65Spooka 
20827fd3f65Spooka 	return 0;
20927fd3f65Spooka }
210