/* * Copyright (c) 1999, 2000 University of Utah and the Flux Group. * All rights reserved. * * This file is part of the Flux OSKit. The OSKit is free software, also known * as "open source;" you can redistribute it and/or modify it under the terms * of the GNU General Public License (GPL), version 2, as published by the Free * Software Foundation (FSF). To explore alternate licensing terms, contact * the University of Utah at csl-dist@cs.utah.edu or +1-801-585-3271. * * The OSKit is distributed in the hope that it will be useful, but WITHOUT ANY * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS * FOR A PARTICULAR PURPOSE. See the GPL for more details. You should have * received a copy of the GPL along with the OSKit; see the file COPYING. If * not, write to the FSF, 59 Temple Place #330, Boston, MA 02111-1307, USA. */ /* * populate the bmod file system with a sub tree of the real file system. * The best way to use this code is by calling start_fs_native_bmod() in * the startup library. It will create a memory filesystem, and then pass * the root directory of that filesystem to: * * int * oskit_unix_bmod_copydir(oskit_dir_t *rootdir, const char *path) * * will create all the directories in the path, and then copy the directory * tree at the last component into the bmod fs at the equiv location. * * Of course, writes will end up in the bmodfs and hence be transient. */ #include #include #include #include #include #include #include "native.h" static int verbose; static void copy_dir(int, oskit_dir_t *); static oskit_dir_t *make_dir(oskit_dir_t *dir, const char *path); int oskit_unix_bmod_copydir(oskit_dir_t *rootdir, const char *path) { oskit_dir_t *dir; int fd; printf("unix/bmodfs: Creating %s\n", path); if (path[0] == '.' && path[1] == 0) dir = rootdir; else dir = make_dir(rootdir, path); fd = NATIVEOS(open)(path, O_RDONLY); if (fd == -1) { printf("unix/bmodfs: couldn't open %s, errno = %d\n", path, NATIVEOS(errno)); } else { if (NATIVEOS(fchdir)(fd) == 0) { copy_dir(fd, dir); NATIVEOS(close)(fd); /* XXX fchdir back to where we were */ } else { printf("unix/bmodfs: couldn't fchdir to %s/errno=%d\n", path, NATIVEOS(errno)); } } return 0; } static oskit_dir_t * make_dir(oskit_dir_t *dir, const char *path) { char buf[128], *dp = buf; const char *bp = path; oskit_dir_t *ddir, *ndir; oskit_file_t *dfile; while (*bp && *bp != '/') *dp++ = *bp++; *dp = '\0'; oskit_dir_mkdir(dir, buf, 666); oskit_dir_lookup(dir, buf, &dfile); oskit_file_query(dfile, &oskit_dir_iid, (void**)&ddir); oskit_file_release(dfile); if (*bp == '/') { bp++; ndir = make_dir(ddir, bp); oskit_dir_release(ddir); return ndir; } return ddir; } static void copy_dir(int dirfd, oskit_dir_t *dst) { static char absname[4096] = "/"; char buf[1024]; long base = 0; int r; while ((r = NATIVEOS(getdirentries)(dirfd, buf, sizeof buf, &base)) > 0) { struct dirent *d = (struct dirent *)buf; while ((void*)d < (void*)(buf + r)) { char *name = (char *)malloc(DIRENTNAMLEN(d) + 1); struct stat stb; int rs; memcpy(name, d->d_name, DIRENTNAMLEN(d)); name[DIRENTNAMLEN(d)] = 0; if (!strcmp(name, ".") || !strcmp(name, "..")) goto next; rs = NATIVEOS(stat)(name, &stb); if (rs == -1) { printf("unix/bmodfs: can't stat %s/errno = %d, skipping\n", name, NATIVEOS(errno)); goto next; } if (S_ISDIR(stb.st_mode)) { oskit_dir_t *ddir; oskit_file_t *dfile; int oldlen = strlen(absname); int fd = NATIVEOS(open)(name, 0 /* don't use O_RDONLY! */); strcat(absname, name); strcat(absname, "/"); NATIVEOS(fchdir)(fd); oskit_dir_mkdir(dst, name, 666); oskit_dir_lookup(dst, name, &dfile); oskit_file_query(dfile, &oskit_dir_iid, (void**)&ddir); oskit_file_release(dfile); copy_dir(fd, ddir); oskit_dir_release(ddir); NATIVEOS(close)(fd); NATIVEOS(fchdir)(dirfd); absname[oldlen] = 0; } else { static char fb[65536]; oskit_error_t rc; oskit_file_t *file; oskit_openfile_t *ofile; oskit_u32_t actual; int b, fd = NATIVEOS(open)(name, 0 /* don't use O_RDONLY!*/); if (fd == -1) { printf("unix/bmodfs: couldn't open %s/errno=%d\n", name, NATIVEOS(errno)); goto next; } if (verbose) printf("unix/bmodfs: copying %s%s ...\n", absname, name); rc = oskit_dir_create(dst, name, 0, 666, &file); assert(rc == 0); /* it's the bmod fs, oskit_file_open would * return rc == 0 & ofile == 0. Must use * adaptor as in liboskit_c::open(). */ rc = oskit_soa_openfile_from_file(file, OSKIT_O_WRONLY, &ofile); assert(rc == 0 && ofile); while ((b = NATIVEOS(read) (fd, fb, sizeof fb)) > 0) { rc = oskit_openfile_write(ofile, fb, b, &actual); assert(rc == 0); assert(b == actual); } NATIVEOS(close)(fd); oskit_openfile_release(ofile); oskit_file_release(file); } next: d = ((void *)d) + d->d_reclen; free(name); } } }