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