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