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