sdread.c revision 1.5
11.5Spooka/*	$NetBSD: sdread.c,v 1.5 2010/03/22 20:37:26 pooka Exp $	*/
21.1Spooka
31.1Spooka/*
41.1Spooka * Copyright (c) 2009 Antti Kantee.  All Rights Reserved.
51.1Spooka *
61.1Spooka * Redistribution and use in source and binary forms, with or without
71.1Spooka * modification, are permitted provided that the following conditions
81.1Spooka * are met:
91.1Spooka * 1. Redistributions of source code must retain the above copyright
101.1Spooka *    notice, this list of conditions and the following disclaimer.
111.1Spooka * 2. Redistributions in binary form must reproduce the above copyright
121.1Spooka *    notice, this list of conditions and the following disclaimer in the
131.1Spooka *    documentation and/or other materials provided with the distribution.
141.1Spooka *
151.1Spooka * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
161.1Spooka * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
171.1Spooka * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
181.1Spooka * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
191.1Spooka * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
201.1Spooka * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
211.1Spooka * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
221.1Spooka * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
231.1Spooka * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
241.1Spooka * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
251.1Spooka * SUCH DAMAGE.
261.1Spooka */
271.1Spooka
281.1Spooka#include <sys/types.h>
291.1Spooka#include <sys/dirent.h>
301.1Spooka#include <sys/mount.h>
311.5Spooka#include <sys/dkio.h>
321.1Spooka
331.2Spooka#include <ufs/ufs/ufsmount.h>
341.1Spooka#include <msdosfs/msdosfsmount.h>
351.3Spooka#include <isofs/cd9660/cd9660_mount.h>
361.1Spooka
371.1Spooka#include <rump/rump.h>
381.1Spooka#include <rump/rump_syscalls.h>
391.1Spooka
401.1Spooka#include <err.h>
411.1Spooka#include <errno.h>
421.1Spooka#include <fcntl.h>
431.1Spooka#include <stdio.h>
441.1Spooka#include <stdlib.h>
451.1Spooka#include <string.h>
461.1Spooka#include <unistd.h>
471.1Spooka
481.1Spooka/*
491.1Spooka * Proof-of-concept program:
501.1Spooka *
511.1Spooka * Mount rump file system from device driver stack included in the
521.1Spooka * rump kernel.  Optionally copy a file out of the mounted file system.
531.1Spooka */
541.1Spooka
551.5Spooka/* recent -current, appease 5.0 etc. userland */
561.5Spooka#ifndef DIOCTUR
571.5Spooka#define DIOCTUR _IOR('d', 128, int)
581.5Spooka#endif
591.5Spooka
601.5Spookastatic void
611.5Spookawaitcd(void)
621.5Spooka{
631.5Spooka	int fd, val = 0, rounds = 0;
641.5Spooka
651.5Spooka	fd = rump_sys_open("/dev/rcd0d", O_RDWR);
661.5Spooka	do {
671.5Spooka		if (rounds > 0) {
681.5Spooka			if (rounds == 1) {
691.5Spooka				printf("Waiting for CD device to settle ");
701.5Spooka			} else {
711.5Spooka				printf(".");
721.5Spooka			}
731.5Spooka			fflush(stdout);
741.5Spooka			sleep(1);
751.5Spooka		}
761.5Spooka		if (rump_sys_ioctl(fd, DIOCTUR, &val) == -1)
771.5Spooka			err(1, "DIOCTUR");
781.5Spooka		rounds++;
791.5Spooka	} while (val == 0 || rounds >= 30);
801.5Spooka
811.5Spooka	if (!val)
821.5Spooka		printf(" giving up\n");
831.5Spooka	else
841.5Spooka		printf(" done!\n");
851.5Spooka}
861.5Spooka
871.1Spookaint
881.1Spookamain(int argc, char *argv[])
891.1Spooka{
901.1Spooka	char buf[2048];
911.1Spooka	struct msdosfs_args args;
921.2Spooka	struct ufs_args uargs;
931.3Spooka	struct iso_args iargs;
941.1Spooka	struct dirent *dp;
951.1Spooka	const char *msg = NULL;
961.1Spooka	int fd, n, fd_h, sverrno;
971.3Spooka	int probeonly = 0;
981.1Spooka
991.3Spooka	if (argc > 1) {
1001.3Spooka		if (argc == 2 && strcmp(argv[1], "probe") == 0) {
1011.3Spooka			probeonly = 1;
1021.3Spooka		} else if (argc != 3) {
1031.3Spooka			fprintf(stderr, "usage: a.out [src hostdest]\n");
1041.3Spooka			exit(1);
1051.3Spooka		}
1061.1Spooka	}
1071.1Spooka
1081.1Spooka	memset(&args, 0, sizeof(args));
1091.1Spooka	args.fspec = strdup("/dev/sd0e");
1101.1Spooka	args.version = MSDOSFSMNT_VERSION;
1111.1Spooka
1121.2Spooka	memset(&uargs, 0, sizeof(uargs));
1131.2Spooka	uargs.fspec = strdup("/dev/sd0e");
1141.2Spooka
1151.3Spooka	memset(&iargs, 0, sizeof(iargs));
1161.3Spooka	iargs.fspec = strdup("/dev/cd0a");
1171.3Spooka
1181.3Spooka	if (probeonly)
1191.3Spooka		rump_boot_sethowto(RUMP_AB_VERBOSE);
1201.1Spooka	rump_init();
1211.3Spooka	if (probeonly) {
1221.4Spooka		pause();
1231.3Spooka		exit(0);
1241.3Spooka	}
1251.1Spooka
1261.1Spooka	if (rump_sys_mkdir("/mp", 0777) == -1)
1271.1Spooka		err(1, "mkdir");
1281.1Spooka	if (rump_sys_mount(MOUNT_MSDOS, "/mp", MNT_RDONLY,
1291.2Spooka	    &args, sizeof(args)) == -1) {
1301.2Spooka		if (rump_sys_mount(MOUNT_FFS, "/mp", MNT_RDONLY,
1311.2Spooka		    &uargs, sizeof(uargs)) == -1) {
1321.5Spooka			/*
1331.5Spooka			 * Wait for CD media to settle.  In the end,
1341.5Spooka			 * just try to do it anyway and see if we fail.
1351.5Spooka			 */
1361.5Spooka			waitcd();
1371.3Spooka			if (rump_sys_mount(MOUNT_CD9660, "/mp", MNT_RDONLY,
1381.3Spooka			    &iargs, sizeof(iargs)) == -1) {
1391.3Spooka				err(1, "mount");
1401.3Spooka			}
1411.2Spooka		}
1421.2Spooka	}
1431.1Spooka
1441.1Spooka	fd = rump_sys_open("/mp", O_RDONLY, 0);
1451.1Spooka	if (fd == -1) {
1461.1Spooka		msg = "open dir";
1471.1Spooka		goto out;
1481.1Spooka	}
1491.1Spooka
1501.1Spooka	while ((n = rump_sys_getdents(fd, buf, sizeof(buf))) > 0) {
1511.1Spooka		for (dp = (struct dirent *)buf;
1521.1Spooka		    (char *)dp - buf < n;
1531.1Spooka		    dp = _DIRENT_NEXT(dp)) {
1541.1Spooka			printf("%" PRIu64 ": %s\n", dp->d_fileno, dp->d_name);
1551.1Spooka		}
1561.1Spooka	}
1571.1Spooka	rump_sys_close(fd);
1581.1Spooka	if (argc == 1)
1591.1Spooka		goto out;
1601.1Spooka
1611.1Spooka	rump_sys_chdir("/mp");
1621.1Spooka	fd = rump_sys_open(argv[1], O_RDONLY, 0);
1631.1Spooka	if (fd == -1) {
1641.1Spooka		msg = "open fs file";
1651.1Spooka		goto out;
1661.1Spooka	}
1671.1Spooka
1681.1Spooka	fd_h = open(argv[2], O_RDWR | O_CREAT, 0777);
1691.1Spooka	if (fd_h == -1) {
1701.1Spooka		msg = "open host file";
1711.1Spooka		goto out;
1721.1Spooka	}
1731.1Spooka
1741.1Spooka	while ((n = rump_sys_read(fd, buf, sizeof(buf))) == sizeof(buf)) {
1751.1Spooka		if (write(fd_h, buf, sizeof(buf)) != sizeof(buf)) {
1761.1Spooka			msg = "write host file";
1771.1Spooka			goto out;
1781.1Spooka		}
1791.1Spooka	}
1801.1Spooka	if (n == -1) {
1811.1Spooka		msg = "read fs file";
1821.1Spooka		goto out;
1831.1Spooka	}
1841.1Spooka
1851.1Spooka	if (n > 0) {
1861.1Spooka		if (write(fd_h, buf, n) == -1)
1871.1Spooka			msg = "write tail";
1881.1Spooka	}
1891.1Spooka
1901.1Spooka out:
1911.1Spooka	sverrno = errno;
1921.1Spooka	rump_sys_chdir("/");
1931.1Spooka	rump_sys_close(fd);
1941.1Spooka	close(fd_h);
1951.1Spooka	if (rump_sys_unmount("/mp", 0) == -1)
1961.1Spooka		err(1, "unmount");
1971.1Spooka
1981.1Spooka	if (msg) {
1991.1Spooka		errno = sverrno;
2001.1Spooka		err(1, "%s", msg);
2011.1Spooka	}
2021.1Spooka
2031.1Spooka	return 0;
2041.1Spooka}
205