sdread.c revision 1.6
11.6Spooka/*	$NetBSD: sdread.c,v 1.6 2010/03/25 15:00:20 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.6Spooka	if (fd == -1)
671.6Spooka		return;
681.6Spooka
691.5Spooka	do {
701.5Spooka		if (rounds > 0) {
711.5Spooka			if (rounds == 1) {
721.5Spooka				printf("Waiting for CD device to settle ");
731.5Spooka			} else {
741.5Spooka				printf(".");
751.5Spooka			}
761.5Spooka			fflush(stdout);
771.5Spooka			sleep(1);
781.5Spooka		}
791.5Spooka		if (rump_sys_ioctl(fd, DIOCTUR, &val) == -1)
801.5Spooka			err(1, "DIOCTUR");
811.5Spooka		rounds++;
821.5Spooka	} while (val == 0 || rounds >= 30);
831.5Spooka
841.5Spooka	if (!val)
851.5Spooka		printf(" giving up\n");
861.5Spooka	else
871.5Spooka		printf(" done!\n");
881.6Spooka
891.6Spooka	rump_sys_close(fd);
901.5Spooka}
911.5Spooka
921.1Spookaint
931.1Spookamain(int argc, char *argv[])
941.1Spooka{
951.1Spooka	char buf[2048];
961.1Spooka	struct msdosfs_args args;
971.2Spooka	struct ufs_args uargs;
981.3Spooka	struct iso_args iargs;
991.1Spooka	struct dirent *dp;
1001.1Spooka	const char *msg = NULL;
1011.1Spooka	int fd, n, fd_h, sverrno;
1021.3Spooka	int probeonly = 0;
1031.1Spooka
1041.3Spooka	if (argc > 1) {
1051.3Spooka		if (argc == 2 && strcmp(argv[1], "probe") == 0) {
1061.3Spooka			probeonly = 1;
1071.3Spooka		} else if (argc != 3) {
1081.3Spooka			fprintf(stderr, "usage: a.out [src hostdest]\n");
1091.3Spooka			exit(1);
1101.3Spooka		}
1111.1Spooka	}
1121.1Spooka
1131.1Spooka	memset(&args, 0, sizeof(args));
1141.1Spooka	args.fspec = strdup("/dev/sd0e");
1151.1Spooka	args.version = MSDOSFSMNT_VERSION;
1161.1Spooka
1171.2Spooka	memset(&uargs, 0, sizeof(uargs));
1181.2Spooka	uargs.fspec = strdup("/dev/sd0e");
1191.2Spooka
1201.3Spooka	memset(&iargs, 0, sizeof(iargs));
1211.3Spooka	iargs.fspec = strdup("/dev/cd0a");
1221.3Spooka
1231.3Spooka	if (probeonly)
1241.3Spooka		rump_boot_sethowto(RUMP_AB_VERBOSE);
1251.1Spooka	rump_init();
1261.3Spooka	if (probeonly) {
1271.4Spooka		pause();
1281.3Spooka		exit(0);
1291.3Spooka	}
1301.1Spooka
1311.1Spooka	if (rump_sys_mkdir("/mp", 0777) == -1)
1321.1Spooka		err(1, "mkdir");
1331.1Spooka	if (rump_sys_mount(MOUNT_MSDOS, "/mp", MNT_RDONLY,
1341.2Spooka	    &args, sizeof(args)) == -1) {
1351.2Spooka		if (rump_sys_mount(MOUNT_FFS, "/mp", MNT_RDONLY,
1361.2Spooka		    &uargs, sizeof(uargs)) == -1) {
1371.5Spooka			/*
1381.5Spooka			 * Wait for CD media to settle.  In the end,
1391.5Spooka			 * just try to do it anyway and see if we fail.
1401.5Spooka			 */
1411.5Spooka			waitcd();
1421.3Spooka			if (rump_sys_mount(MOUNT_CD9660, "/mp", MNT_RDONLY,
1431.3Spooka			    &iargs, sizeof(iargs)) == -1) {
1441.3Spooka				err(1, "mount");
1451.3Spooka			}
1461.2Spooka		}
1471.2Spooka	}
1481.1Spooka
1491.1Spooka	fd = rump_sys_open("/mp", O_RDONLY, 0);
1501.1Spooka	if (fd == -1) {
1511.1Spooka		msg = "open dir";
1521.1Spooka		goto out;
1531.1Spooka	}
1541.1Spooka
1551.1Spooka	while ((n = rump_sys_getdents(fd, buf, sizeof(buf))) > 0) {
1561.1Spooka		for (dp = (struct dirent *)buf;
1571.1Spooka		    (char *)dp - buf < n;
1581.1Spooka		    dp = _DIRENT_NEXT(dp)) {
1591.1Spooka			printf("%" PRIu64 ": %s\n", dp->d_fileno, dp->d_name);
1601.1Spooka		}
1611.1Spooka	}
1621.1Spooka	rump_sys_close(fd);
1631.1Spooka	if (argc == 1)
1641.1Spooka		goto out;
1651.1Spooka
1661.1Spooka	rump_sys_chdir("/mp");
1671.1Spooka	fd = rump_sys_open(argv[1], O_RDONLY, 0);
1681.1Spooka	if (fd == -1) {
1691.1Spooka		msg = "open fs file";
1701.1Spooka		goto out;
1711.1Spooka	}
1721.1Spooka
1731.1Spooka	fd_h = open(argv[2], O_RDWR | O_CREAT, 0777);
1741.1Spooka	if (fd_h == -1) {
1751.1Spooka		msg = "open host file";
1761.1Spooka		goto out;
1771.1Spooka	}
1781.1Spooka
1791.1Spooka	while ((n = rump_sys_read(fd, buf, sizeof(buf))) == sizeof(buf)) {
1801.1Spooka		if (write(fd_h, buf, sizeof(buf)) != sizeof(buf)) {
1811.1Spooka			msg = "write host file";
1821.1Spooka			goto out;
1831.1Spooka		}
1841.1Spooka	}
1851.1Spooka	if (n == -1) {
1861.1Spooka		msg = "read fs file";
1871.1Spooka		goto out;
1881.1Spooka	}
1891.1Spooka
1901.1Spooka	if (n > 0) {
1911.1Spooka		if (write(fd_h, buf, n) == -1)
1921.1Spooka			msg = "write tail";
1931.1Spooka	}
1941.1Spooka
1951.1Spooka out:
1961.1Spooka	sverrno = errno;
1971.1Spooka	rump_sys_chdir("/");
1981.1Spooka	rump_sys_close(fd);
1991.1Spooka	close(fd_h);
2001.1Spooka	if (rump_sys_unmount("/mp", 0) == -1)
2011.1Spooka		err(1, "unmount");
2021.1Spooka
2031.1Spooka	if (msg) {
2041.1Spooka		errno = sverrno;
2051.1Spooka		err(1, "%s", msg);
2061.1Spooka	}
2071.1Spooka
2081.1Spooka	return 0;
2091.1Spooka}
210