static bool remount_partition(int fd, const char* dir) { if (!directory_exists(dir)) { return true; } std::string dev = find_mount(dir); if (dev.empty()) { return true; } if (!make_block_device_writable(dev)) { WriteFdFmt(fd, "remount of %s failed; couldn't make block device %s writable: %s\n", dir, dev.c_str(), strerror(errno)); return false; } if (mount(dev.c_str(), dir, "none", MS_REMOUNT, nullptr) == -1) { WriteFdFmt(fd, "remount of %s failed: %s\n", dir, strerror(errno)); return false; } return true; }
int cat_file(char *pathname) { char *mybuf, file[3]; int n, fd, size; MOUNT *mnt; strcat(pathname, " RD"); fd = open_file(pathname); mnt=(MOUNT *)find_mount(running->cwd->dev); size=mnt->blksize; mybuf=malloc(size+1); while(n=myread(fd, mybuf, size)) { mybuf[n]=0; myprintf("%s", mybuf); } sprintf(file, "%d", fd); close_file(file); free(mybuf); }
int chmod_file(char *cmd) { int newMod, ino, dev; char path[1024], mod[10]; MINODE *mip; MOUNT *mnt; sscanf(cmd, "%s %s", mod, path); newMod=strtol(mod, NULL, 0); dev=running->cwd->dev; ino=getino(&dev, path); if (ino==0) { printf(RED "invalid path\n" RESET); return -1; } mip=iget(dev, ino); mip->inode.i_mode=newMod; mip->dirty=true; mnt=(MOUNT *)find_mount(dev); sync_mount_atime(mnt); iput(mip); }
int chown(char *cmd) { int newOwner, ino, dev; char path[1024], own[10]; MINODE *mip; MOUNT *mnt; sscanf(cmd, "%s %s", own, path); newOwner=atoi(own); dev=running->cwd->dev; ino=getino(&dev, path); if(ino==0) { printf(RED "invalid path\n" RESET); return -1; } mip=iget(dev, ino); mip->inode.i_uid=newOwner; mip->dirty=true; mnt=(MOUNT *)find_mount(dev); sync_mount_atime(mnt); iput(mip); return; }
/** * \brief Open the given directory * * \param path Fully-qualified absolute path to directory * \param dhandle Return handle, if call succeeds * * This call fails if the path does not exist or is not a directory. */ errval_t vfs_opendir(const char *path, vfs_handle_t *dhandle) { const char *relpath = NULL; // locate mount point struct vfs_mount *m = find_mount(path, &relpath); if (m == NULL) { return FS_ERR_NOTFOUND; } // call fs ops func assert(m->ops->opendir != NULL); errval_t ret = m->ops->opendir(m->st, relpath, dhandle); // update handle with mount pointer if (err_is_ok(ret)) { struct vfs_handle *h = *dhandle; h->mount = m; } return ret; }
FILE * fopen(const char *name, const char *how){ MountEntry *me; me = find_mount(name); if( me ) name = basenameoffile(name); #ifdef USE_PROC if( currproc && !me ) me = currproc->cwd; #endif if( !me ) return 0; if( me->flags & MNTE_F_DEV ) return me->fdev; if( me->fscf && me->fscf->open ) return (me->fscf->open)(me, name, how); else return me->fdev; }
status_t fs_make_dir(const char *path) { char temppath[FS_MAX_PATH_LEN]; strlcpy(temppath, path, sizeof(temppath)); fs_normalize_path(temppath); const char *newpath; struct fs_mount *mount = find_mount(temppath, &newpath); if (!mount) return ERR_NOT_FOUND; if (!mount->api->mkdir) { put_mount(mount); return ERR_NOT_SUPPORTED; } status_t err = mount->api->mkdir(mount->cookie, newpath); put_mount(mount); return err; }
/* * Mount a filesystem. Once we've found the device, call MOUNTFUNC to * set up the filesystem and hand back a struct fs. */ int vfs_mount(const char *devname, int (*mountfunc)(struct device *dev, struct fs **fs_store)) { int ret; lock_vdev_list(); vfs_dev_t *vdev; if ((ret = find_mount(devname, &vdev)) != 0) { goto out; } if (vdev->fs != NULL) { ret = -E_BUSY; goto out; } assert(vdev->devname != NULL && vdev->mountable); struct device *dev = vop_info(vdev->devnode, device); if ((ret = mountfunc(dev, &(vdev->fs))) == 0) { assert(vdev->fs != NULL); cprintf("vfs: mount %s.\n", vdev->devname); } out: unlock_vdev_list(); return ret; }
int myread(int fd, char buffer[], int nbytes) { int i, size, lblk, *bno, *ibno, *dbno, start, remain, avil, file_size, offset, count=0; OFT *oftp; char *cq, *buf, *inbuf, *dinbuf, *readbuf; MINODE *mip; MOUNT *mnt; cq=buffer; if (fd < 0 || fd >NFD) { printf(RED"Invalid FD\n"RESET); return -1; } oftp=running->fd[fd]; mip=oftp->ptr; mnt=find_mount(mip->dev); size=mnt->blksize; buf=malloc(size+1); inbuf=malloc(size+1); dinbuf=malloc(size+1); readbuf=malloc(size+1); offset=oftp->offset; file_size=oftp->ptr->inode.i_size; avil=file_size-offset; printf("* fd=%d, size=%d avil=%d nbytes=%d\n", fd, file_size, avil, nbytes); while(nbytes && avil) { lblk=(oftp->offset)/size; start=(oftp->offset)%size; if (lblk<12) { bno =&(mip->inode.i_block[lblk]); } else if (lblk>=12 && lblk<((size/4)+12)) { bget_block(mip->dev, mip->inode.i_block[12], buf, size); bno = (int *)buf+(lblk-12); } else if (lblk>=((size/4)+12) && lblk<(((size/4)*(size/4))+(size/4)+12)) { bget_block(mip->dev, mip->inode.i_block[13], buf, size); lblk=((lblk-12) - (size/4)); ibno = (int *)buf + (lblk/size); bget_block(mip->dev, *ibno, inbuf, size); lblk%=(size/4); bno=(int *)inbuf + lblk; } else { bget_block(mip->dev, mip->inode.i_block[14], buf, size); lblk=((lblk-12) - ((size/4)*(size/4)+(size/4))); dbno=(int *)buf + (lblk/((size/4)*(size/4))); bget_block(mip->dev, *dbno, dinbuf, size); lblk%=((size/4)*(size/4)); ibno=(int *)buf + lblk/(size); bget_block(mip->dev, *ibno, inbuf, size); lblk%=(size/4); bno=(int *)inbuf + lblk; } bget_block(mip->dev, *bno, readbuf, size); cp = readbuf + start; remain = size - start; if(avail >= size && remain == size && nbytes >= size) { strncpy(cq, cp, size); running->fd[fd]->offset += size; count += size; avail -= size; nbytes -= size; remain -= size; } else if (remain <= avil && remain <= nbytes) { memcpy(cq, cp, remain); running->fd[fd]->offset += remain; count += remain; avil -= remain; nbytes -= remain; remain -= remain; } else { memcpy(cq, cp, avil); running->fd[fd]->offset += avil; count += avil; avil -= avil; nbytes -= avil; remain -= avil; } } printf("myread : read %d char from file descriptor %d\n", count, fd); FREE_4(buf, inbuf, dinbuf, readbuf); return count; }
int main(int argc, char *argv[]) { long timeout_val; int c; int flushcache = 0; int unmount_automounted = 0; // Unmount automounted mounts struct autodir *dir, *d; char real_mntpnt[PATH_MAX]; struct stat stbuf; char *master_map = "auto_master"; int null; struct statfs *mntp; int count = 0; char *stack[STACKSIZ]; char **stkptr; char *defval; int fd; int flags, altflags; struct staticmap *static_ent; /* * Read in the values from config file first before we check * commandline options so the options override the file. */ if ((defopen(AUTOFSADMIN)) == 0) { if ((defval = defread("AUTOMOUNT_TIMEOUT=")) != NULL) { errno = 0; timeout_val = strtol(defval, (char **)NULL, 10); if (errno == 0 && timeout_val > 0 && timeout_val <= INT_MAX) mount_timeout = (int)timeout_val; } if ((defval = defread("AUTOMOUNT_VERBOSE=")) != NULL) { if (strncasecmp("true", defval, 4) == 0) verbose = TRUE; else verbose = FALSE; } if ((defval = defread("AUTOMOUNTD_TRACE=")) != NULL) { /* * Turn on tracing here too if the automountd * is set up to do it - since automount calls * many of the common library functions. */ errno = 0; trace = (int)strtol(defval, (char **)NULL, 10); if (errno != 0) trace = 0; } /* close defaults file */ defopen(NULL); } while ((c = getopt(argc, argv, "mM:D:f:t:vcu?")) != EOF) { switch (c) { case 'm': pr_msg("Warning: -m option not supported"); break; case 'M': pr_msg("Warning: -M option not supported"); break; case 'D': pr_msg("Warning: -D option not supported"); break; case 'f': pr_msg("Error: -f option no longer supported"); usage(); break; case 't': if (strchr(optarg, '=')) { pr_msg("Error: invalid value for -t"); usage(); } mount_timeout = atoi(optarg); break; case 'v': verbose++; break; case 'c': flushcache++; break; case 'u': unmount_automounted++; break; default: usage(); break; } } if (optind < argc) { pr_msg("%s: command line mountpoints/maps " "no longer supported", argv[optind]); usage(); } /* * Get an array of current system mounts */ num_current_mounts = getmntinfo(¤t_mounts, MNT_NOWAIT); if (num_current_mounts == 0) { pr_msg("Couldn't get current mounts: %m"); exit(1); } autofs_control_fd = open("/dev/" AUTOFS_CONTROL_DEVICE, O_RDONLY); if (autofs_control_fd == -1 && errno == ENOENT) { /* * Oops, we probably don't have the autofs kext * loaded. */ FTS *fts; static char *const paths[] = { "/Network", NULL }; FTSENT *ftsent; int error; /* * This means there can't be any autofs mounts yet, so * this is the first time we're being run since a reboot. * Clean out any stuff left in /Network from the reboot. */ fts = fts_open(paths, FTS_NOCHDIR|FTS_PHYSICAL|FTS_XDEV, NULL); if (fts != NULL) { while ((ftsent = fts_read(fts)) != NULL) { /* * We only remove directories - if * there are files, we assume they're * there for a purpose. * * We remove directories after we've * removed their children, so we want * to process directories visited in * post-order. * * We don't remove /Network itself. */ if (ftsent->fts_info == FTS_DP && ftsent->fts_level > FTS_ROOTLEVEL) rmdir(ftsent->fts_accpath); } fts_close(fts); } /* * Now load it. */ error = load_autofs(); if (error != 0) { pr_msg("can't load autofs kext"); exit(1); } /* * Try the open again. */ autofs_control_fd = open("/dev/" AUTOFS_CONTROL_DEVICE, O_RDONLY); } if (autofs_control_fd == -1) { if (errno == EBUSY) pr_msg("Another automount is running"); else pr_msg("Couldn't open %s: %m", "/dev/" AUTOFS_CONTROL_DEVICE); exit(1); } /* * Update the mount timeout. */ if (ioctl(autofs_control_fd, AUTOFS_SET_MOUNT_TO, &mount_timeout) == -1) pr_msg("AUTOFS_SET_MOUNT_TO failed: %m"); /* * Attempt to unmount any non-busy triggered mounts; this includes * not only autofs mounts, but, for example SMB Dfs mounts. * * This is done before sleep, and after a network change, to * try to get rid of as many network mounts as we can; each * unmounted network mount is a network mount on which we * can't hang. */ if (unmount_automounted) { if (verbose) pr_msg("Unmounting triggered mounts"); if (ioctl(autofs_control_fd, AUTOFS_UNMOUNT_TRIGGERED, 0) == -1) pr_msg("AUTOFS_UNMOUNT_TRIGGERED failed: %m"); exit(0); } if (flushcache) { /* * Notify the automounter that it should flush its caches, * as we might be on a different network with different maps. */ if (ioctl(autofs_control_fd, AUTOFS_NOTIFYCHANGE, 0) == -1) pr_msg("AUTOFS_NOTIFYCHANGE failed: %m"); } (void) umask(0); ns_setup(stack, &stkptr); (void) loadmaster_map(master_map, "", stack, &stkptr); /* * Mount the daemon at its mount points. */ for (dir = dir_head; dir; dir = dir->dir_next) { if (realpath(dir->dir_name, real_mntpnt) == NULL) { /* * We couldn't get the real path for this, * perhaps because it doesn't exist. * If it's not because it doesn't exist, just * give up on this entry. Otherwise, just null * out the real path - we'll try creating the * directory later, and will set dir_realpath * then, if that succeeds. */ if (errno != ENOENT) { pr_msg("%s: Can't convert to real path: %m", dir->dir_name); continue; } dir->dir_realpath = NULL; } else { dir->dir_realpath = strdup(real_mntpnt); if (dir->dir_realpath == NULL) { pr_msg("Couldn't allocate real path: %m"); exit(1); } } /* * Skip null entries */ if (strcmp(dir->dir_map, "-null") == 0) continue; /* * Skip null'ed entries */ null = 0; for (d = dir->dir_prev; d; d = d->dir_prev) { if (paths_match(dir, d)) null = 1; } if (null) continue; /* * If this is -fstab, and there are no fstab "net" entries, * skip this map if our directory search path doesn't * include Active Directory. We don't want /Network/Servers * (or wherever it shows up) to exist if this system isn't * using AD (AD supplies fstab entries on the fly, so they * might not exist right now) and we don't have any fstab * entries. */ if (strcmp(dir->dir_map, "-fstab") == 0) { if (!have_ad() && !havefstabkeys()) { /* * We're not using AD, and fstab is * inaccessible or devoid of "net" entries. */ free(dir->dir_map); dir->dir_map = strdup("-null"); continue; } endfsent(); } /* * If this is -fstab or -static, and there's another entry * that's supposed to mount something on the same directory * and isn't "-fstab" or "-static", ignore this; we might * have a server that's supplying real automounter maps for * the benefit of OS X systems with autofs and also supplying * fstab entries for the benefit of older OS X systems, and * we want to mount the real automounter map, not the -fstab * or -static map, in that case. */ if (strcmp(dir->dir_map, "-fstab") == 0 || strcmp(dir->dir_map, "-static") == 0) { for (d = dir_head; d; d = d->dir_next) { if (paths_match(dir, d) && strcmp(d->dir_map, "-fstab") != 0 && strcmp(d->dir_map, "-static") != 0) { pr_msg("%s: ignoring redundant %s map", dir->dir_name, dir->dir_map); break; } } if (d != NULL) { continue; } } /* * Parse the mount options and get additional flags to pass * to mount() (standard mount options) and autofs mount * options. * * XXX - we ignore flags on an update; if they're different * from the current flags for that mount, we'd need to do a * remount. */ if (!parse_mntopts(dir->dir_opts, &flags, &altflags)) { /* * Failed. */ continue; } /* * If this is -static, check whether the entry refers * to this host; if so, make the appropriate symlink * exist at the "mount point" path. */ if (strcmp(dir->dir_map, "-static") == 0) { static_ent = get_staticmap_entry(dir->dir_name); if (static_ent == NULL) { /* * Whiskey tango foxtrot? There should * be an entry here. Log an error and * ignore this mount. */ pr_msg("can't find fstab entry for %s", dir->dir_name); continue; } if (host_is_us(static_ent->host, strlen(static_ent->host)) || self_check(static_ent->host)) { /* * Yup, this is us. * Try to make the appropriate symlink. */ make_symlink(static_ent->localpath, dir->dir_name); release_staticmap_entry(static_ent); continue; } release_staticmap_entry(static_ent); } /* * Check whether there's already an entry * in the mnttab for this mountpoint. */ if (dir->dir_realpath != NULL && (mntp = find_mount(dir->dir_realpath)) != NULL) { struct autofs_update_args au; /* * If it's not an autofs mount - don't * mount over it. */ if (strcmp(mntp->f_fstypename, MNTTYPE_AUTOFS) != 0) { pr_msg("%s: already mounted on %s", mntp->f_mntfromname, dir->dir_realpath); continue; } /* * This is already mounted, so just update it. * We don't bother to check whether any options are * changing, as we'd have to make a trip into the * kernel to get the current options to check them, * so we might as well just make a trip to do the * update. */ au.fsid = mntp->f_fsid; au.opts = dir->dir_opts; au.map = dir->dir_map; au.mntflags = altflags; au.direct = dir->dir_direct; au.node_type = dir->dir_direct ? NT_TRIGGER : 0; if (ioctl(autofs_control_fd, AUTOFS_UPDATE_OPTIONS, &au) < 0) { pr_msg("update %s: %m", dir->dir_realpath); continue; } if (verbose) pr_msg("%s updated", dir->dir_realpath); } else { struct autofs_args ai; int st_flags = 0; /* * This trigger isn't already mounted; either * the path doesn't exist at all, or it * exists but nothing is mounted on it. * * Create a mount point if necessary * If the path refers to an existing symbolic * link, refuse to mount on it. This avoids * future problems. (We don't use dir->dir_realpath * because that's never a symbolic link.) */ if (lstat(dir->dir_name, &stbuf) == 0) { if ((stbuf.st_mode & S_IFMT) != S_IFDIR) { pr_msg("%s: Not a directory", dir->dir_name); continue; } st_flags = stbuf.st_flags; /* * Either realpath() succeeded or it * failed with ENOENT; otherwise, we * would have quit before getting here. * * If it failed, report an error, as * the problem isn't that "dir->dir_name" * doesn't exist, the problem is that, * somehow, we got ENOENT even though * it exists. */ if (dir->dir_realpath == NULL) { errno = ENOENT; pr_msg("%s: Can't convert to real path: %m", dir->dir_name); continue; } } else { /* * Mountpoint doesn't exist. * * Create it unless it's under /Volumes. * At boot time it's possible the volume * containing the mountpoint hasn't mounted yet. */ if (strncmp(dir->dir_name, "/Volumes/", 9) == 0) { pr_msg("%s: mountpoint unavailable", dir->dir_name); continue; } if (mkdir_r(dir->dir_name)) { pr_msg("%s: %m", dir->dir_name); continue; } /* * realpath() presumably didn't succeed, * as dir->dir_name couldn't be statted. * Call it again, to get the real path * corresponding to the newly-created * mount point. */ if (realpath(dir->dir_name, real_mntpnt) == NULL) { /* * Failed. */ pr_msg("%s: Can't convert to real path: %m", dir->dir_name); continue; } dir->dir_realpath = strdup(real_mntpnt); if (dir->dir_realpath == NULL) { pr_msg("Couldn't allocate real path for %s: %m", dir->dir_name); continue; } } /* * If the "hidefromfinder" option is set for * this autofs mountpoint then also set the * UF_HIDDEN bit on the directory so it'll still * be invisible to the Finder even if not mounted on. */ if (altflags & AUTOFS_MNT_HIDEFROMFINDER) st_flags |= UF_HIDDEN; else st_flags &= ~UF_HIDDEN; if (chflags(dir->dir_name, st_flags) < 0) pr_msg("%s: can't set hidden", dir->dir_name); /* * Mount it. Use the real path (symlink-free), * for reasons mentioned above. */ ai.version = AUTOFS_ARGSVERSION; ai.path = dir->dir_realpath; ai.opts = dir->dir_opts; ai.map = dir->dir_map; ai.subdir = ""; ai.direct = dir->dir_direct; if (dir->dir_direct) ai.key = dir->dir_name; else ai.key = ""; ai.mntflags = altflags; ai.mount_type = MOUNT_TYPE_MAP; /* top-level autofs mount */ ai.node_type = dir->dir_direct ? NT_TRIGGER : 0; if (mount(MNTTYPE_AUTOFS, dir->dir_realpath, MNT_DONTBROWSE | MNT_AUTOMOUNTED | flags, &ai) < 0) { pr_msg("mount %s: %m", dir->dir_realpath); continue; } if (verbose) pr_msg("%s mounted", dir->dir_realpath); } count++; } if (verbose && count == 0) pr_msg("no mounts"); /* * Now compare the /etc/mnttab with the master * map. Any autofs mounts in the /etc/mnttab * that are not in the master map must be * unmounted * * XXX - if there are no autofs mounts left, should we * unload autofs, or arrange that it be unloaded? */ do_unmounts(); /* * Let PremountHomeDirectoryWithAuthentication() know that we're * done. */ fd = open("/var/run/automount.initialized", O_CREAT|O_WRONLY, 0600); close(fd); return (0); }
static void make_symlink(const char *target, const char *path) { struct stat stbuf; char linktarget[PATH_MAX + 1]; ssize_t pathlength; struct statfs *mnt; struct stat st; /* * Does the target exist? */ if (lstat(path, &stbuf) == 0) { /* * Yes. What is it? */ if ((stbuf.st_mode & S_IFMT) == S_IFLNK) { /* * It's a symlink. * What does it point to? */ pathlength = readlink(path, linktarget, PATH_MAX); if (pathlength == -1) { /* * FAIL. */ pr_msg("can't read target of %s: %m", path); return; } linktarget[pathlength] = '\0'; /* * Does it point to the same place that we * want it to point to? * * XXX - case-sensitivity? That's hard to * handle, given that the path might cross * multiple file systems with different case- * sensitivities. */ if (strcmp(linktarget, target) == 0) { /* * Yes, it does. * We don't need to do anything. */ if (verbose) pr_msg("link %s unchanged", path); return; } /* * Get rid of the existing symlink. */ if (unlink(path) == -1) { pr_msg("can't unlink %s: %m", path); return; } } else if ((stbuf.st_mode & S_IFMT) == S_IFDIR) { /* * It's a directory. * Is there an autofs mount atop it? */ mnt = find_mount(path); if (mnt != NULL) { /* * Something's mounted atop it; is it * autofs? */ if (strcmp(mnt->f_fstypename, MNTTYPE_AUTOFS) == 0) { /* * Yes. Try to unmount it (and * everything under it). */ if (ioctl(autofs_control_fd, AUTOFS_UNMOUNT, &mnt->f_fsid) != 0) { /* * Failed. * Leave it alone for now. */ return; } } } /* * Now try to remove the directory. */ if (rmdir(path) != 0) { /* * Failed. Leave it alone. */ return; } } else { /* * Neither a symlink nor a directory. * Leave it alone. */ return; } } else { /* * lstat() failed; is it because the target doesn't * exist, or because we couldn't get its * information? */ if (errno != ENOENT) { /* * We couldn't get its information. * Leave it alone. */ return; } } /* * OK, the target should not exist. * Make the symlink. */ if (symlink(target, path) == -1) { pr_msg("can't create symlink from %s to %s: %m", path, target); } /* * Validate the symlink in case the path and target * don't match but still yield an ELOOP. */ if (stat(path, &st) < 0) { pr_msg("Invalid symbolic link: %s to %s: %m", path, target); (void) unlink(path); } }
/** * \brief Mount a filesystem into the local VFS * * \param mountpoint Fully-qualified absolute path to the mount-point * Must be a directory in the existing VFS which is not already a mount-point * * \param uri URI of source file system to mount. * Currently-supported are: * ramfs://[servicename] where servicename is registered in the name service * nfs://hostip/path */ errval_t vfs_mount(const char *mountpoint, const char *uri) { errval_t err; // copy mountpoint and normalise it assert(mountpoint != NULL); char *mp = strdup(mountpoint); assert(mp != NULL); vfs_path_normalise(mp); // sanity-check mountpoint: must start at root and not have .. in it if (mp[0] != VFS_PATH_SEP || strncmp(mp, "/../", 4) == 0) { free(mp); return VFS_ERR_BAD_MOUNTPOINT; } // sanity-check mountpoint // if this is the first mount, it must be for the root, otherwise it must // not duplicate an existing mount, and the mount-point must exist if (mounts == NULL) { if (strcmp(mp, VFS_PATH_SEP_STR) != 0) { free(mp); return VFS_ERR_BAD_MOUNTPOINT; } } else { struct vfs_mount *parent = find_mount(mp, NULL); assert(parent != NULL); // root should always have matched if (strcmp(parent->mountpoint, mp) == 0) { free(mp); return VFS_ERR_MOUNTPOINT_IN_USE; } // check for existence of mountpoint by attempting to open it vfs_handle_t tmp; err = vfs_opendir(mp, &tmp); if (err_is_fail(err)) { free(mp); return err_push(err, VFS_ERR_MOUNTPOINT_NOTFOUND); } vfs_closedir(tmp); } // parse protocol part of URI char *pos = strstr(uri, "://"); if (pos == NULL) { free(mp); return VFS_ERR_BAD_URI; } struct vfs_mount *m = malloc(sizeof(struct vfs_mount)); assert(m != NULL); m->mountpoint = mp; size_t len = pos - uri; if (strncmp(uri, "nfs", len) == 0) { #ifndef DISABLE_NFS err = vfs_nfs_mount(uri, &m->st, &m->ops); #else err = VFS_ERR_UNKNOWN_FILESYSTEM; #endif } else if (strncmp(uri, "ramfs", len) == 0) { err = vfs_ramfs_mount(uri, &m->st, &m->ops); } else if (strncmp(uri, "blockdevfs", len) == 0) { err = vfs_blockdevfs_mount(uri, &m->st, &m->ops); } else if (strncmp(uri, "fat16", len) == 0) { err = vfs_fat_mount(uri, &m->st, &m->ops); } else if (strncmp(uri, "fat32", len) == 0) { err = vfs_fat_mount(uri, &m->st, &m->ops); } else { debug_printf("VFS: unknown file system %.*s\n", (int)len, uri); err = VFS_ERR_UNKNOWN_FILESYSTEM; } if (err_is_fail(err)) { free(m); free(mp); return err; } // add to list of mounts m->next = mounts; mounts = m; return SYS_ERR_OK; }
DEFALIAS(dir, ll) { int how=0, i; const char *what; MountEntry *me; if( !strcmp(argv[0], "ll") ) how = LSHOW_ALL | LSHOW_LONG ; if( !strcmp(argv[0], "ls") ) how = LSHOW_SHORT ; if( argc == 1) what = ""; else{ if( argv[1][0] == '-' ){ for(i=how=0; argv[1][i]; i++){ switch( argv[1][i] ){ case 'a': how |= LSHOW_ALL; break; case 'd': how |= LSHOW_DEVS; break; case 'f': how |= LSHOW_FSYS; break; case 'x': how |= LSHOW_EXT; break; case 'l': how |= LSHOW_LONG; break; case 's': how |= LSHOW_SHORT; break; case 'h': printf("-a\tall\n-d\tdevs\n-f\tfilesys\n-l\tlong\n-s\tshort\n"); return 0; } } what = argc>2 ? argv[2] : ""; }else{ what = argc>1 ? argv[1] : ""; if( !strcmp(argv[1], DEVPREFIX) ){ how |= LSHOW_DEVS; what = ""; } if( !strcmp(argv[1], ":") ){ how |= LSHOW_FSYS; what = ""; } if( !strcmp(argv[1], "::") ){ how |= LSHOW_DEVS | LSHOW_FSYS | LSHOW_LONG; what = ""; } } } if( (how & LSHOW_FSYS) || (how & LSHOW_DEVS) ){ if( how & LSHOW_FSYS ){ // synthesize a "dev" filesystem printf("\tdev:%s\n", (how & LSHOW_LONG) ? "\ttype dev" : ""); } /* list all devs or filesystems */ me = mountlist; while( me ){ if( (me->flags & MNTE_F_DEV) && (how & LSHOW_DEVS) || (me->flags & MNTE_F_FS) && (how & LSHOW_FSYS) ){ printf("\t%s", me->name); if( how & LSHOW_LONG ){ if( me->fscf && me->fscf->name ) printf("\ttype %s", me->fscf->name); } printf("\n"); } me = me->next; } return 0; } #ifdef USE_FILESYS me = find_mount(what); if( me ) what = basenameoffile(what); #ifdef USE_PROC if( !me ) me = currproc->cwd; #endif if( !me ){ fsmsg("no such file or device\n"); return -1; } if( me->fscf && me->fscf->ops ) i = (me->fscf->ops)(FSOP_DIR, me, how, what); else i = -1; if( i ) f_error("ls [-adfxl] [me]"); return i; #else f_error("no filesys configured\n"); return -1; #endif }