From cdb8b79bad5fea81b74931a9027f1d5ca344af8e Mon Sep 17 00:00:00 2001 From: Miklos Szeredi Date: Wed, 12 Dec 2007 14:25:40 +0000 Subject: change indenting --- lib/mount_bsd.c | 560 ++++++++++++++++++++++++++++---------------------------- 1 file changed, 283 insertions(+), 277 deletions(-) (limited to 'lib/mount_bsd.c') diff --git a/lib/mount_bsd.c b/lib/mount_bsd.c index 5197464..fb4f12a 100644 --- a/lib/mount_bsd.c +++ b/lib/mount_bsd.c @@ -1,9 +1,9 @@ /* - FUSE: Filesystem in Userspace - Copyright (C) 2005-2006 Csaba Henk + FUSE: Filesystem in Userspace + Copyright (C) 2005-2006 Csaba Henk - This program can be distributed under the terms of the GNU LGPLv2. - See the file COPYING.LIB. + This program can be distributed under the terms of the GNU LGPLv2. + See the file COPYING.LIB. */ #include "fuse_i.h" @@ -22,343 +22,349 @@ #include #include -#define FUSERMOUNT_PROG "mount_fusefs" -#define FUSE_DEV_TRUNK "/dev/fuse" +#define FUSERMOUNT_PROG "mount_fusefs" +#define FUSE_DEV_TRUNK "/dev/fuse" enum { - KEY_ALLOW_ROOT, - KEY_RO, - KEY_HELP, - KEY_VERSION, - KEY_KERN + KEY_ALLOW_ROOT, + KEY_RO, + KEY_HELP, + KEY_VERSION, + KEY_KERN }; struct mount_opts { - int allow_other; - int allow_root; - int ishelp; - char *kernel_opts; + int allow_other; + int allow_root; + int ishelp; + char *kernel_opts; }; static const struct fuse_opt fuse_mount_opts[] = { - { "allow_other", offsetof(struct mount_opts, allow_other), 1 }, - { "allow_root", offsetof(struct mount_opts, allow_root), 1 }, - FUSE_OPT_KEY("allow_root", KEY_ALLOW_ROOT), - FUSE_OPT_KEY("-r", KEY_RO), - FUSE_OPT_KEY("-h", KEY_HELP), - FUSE_OPT_KEY("--help", KEY_HELP), - FUSE_OPT_KEY("-V", KEY_VERSION), - FUSE_OPT_KEY("--version", KEY_VERSION), - /* standard FreeBSD mount options */ - FUSE_OPT_KEY("dev", KEY_KERN), - FUSE_OPT_KEY("async", KEY_KERN), - FUSE_OPT_KEY("atime", KEY_KERN), - FUSE_OPT_KEY("dev", KEY_KERN), - FUSE_OPT_KEY("exec", KEY_KERN), - FUSE_OPT_KEY("suid", KEY_KERN), - FUSE_OPT_KEY("symfollow", KEY_KERN), - FUSE_OPT_KEY("rdonly", KEY_KERN), - FUSE_OPT_KEY("sync", KEY_KERN), - FUSE_OPT_KEY("union", KEY_KERN), - FUSE_OPT_KEY("userquota", KEY_KERN), - FUSE_OPT_KEY("groupquota", KEY_KERN), - FUSE_OPT_KEY("clusterr", KEY_KERN), - FUSE_OPT_KEY("clusterw", KEY_KERN), - FUSE_OPT_KEY("suiddir", KEY_KERN), - FUSE_OPT_KEY("snapshot", KEY_KERN), - FUSE_OPT_KEY("multilabel", KEY_KERN), - FUSE_OPT_KEY("acls", KEY_KERN), - FUSE_OPT_KEY("force", KEY_KERN), - FUSE_OPT_KEY("update", KEY_KERN), - FUSE_OPT_KEY("ro", KEY_KERN), - FUSE_OPT_KEY("rw", KEY_KERN), - FUSE_OPT_KEY("auto", KEY_KERN), - /* options supported under both Linux and FBSD */ - FUSE_OPT_KEY("allow_other", KEY_KERN), - FUSE_OPT_KEY("default_permissions", KEY_KERN), - /* FBSD FUSE specific mount options */ - FUSE_OPT_KEY("private", KEY_KERN), - FUSE_OPT_KEY("neglect_shares", KEY_KERN), - FUSE_OPT_KEY("push_symlinks_in", KEY_KERN), - /* stock FBSD mountopt parsing routine lets anything be negated... */ - FUSE_OPT_KEY("nodev", KEY_KERN), - FUSE_OPT_KEY("noasync", KEY_KERN), - FUSE_OPT_KEY("noatime", KEY_KERN), - FUSE_OPT_KEY("nodev", KEY_KERN), - FUSE_OPT_KEY("noexec", KEY_KERN), - FUSE_OPT_KEY("nosuid", KEY_KERN), - FUSE_OPT_KEY("nosymfollow", KEY_KERN), - FUSE_OPT_KEY("nordonly", KEY_KERN), - FUSE_OPT_KEY("nosync", KEY_KERN), - FUSE_OPT_KEY("nounion", KEY_KERN), - FUSE_OPT_KEY("nouserquota", KEY_KERN), - FUSE_OPT_KEY("nogroupquota", KEY_KERN), - FUSE_OPT_KEY("noclusterr", KEY_KERN), - FUSE_OPT_KEY("noclusterw", KEY_KERN), - FUSE_OPT_KEY("nosuiddir", KEY_KERN), - FUSE_OPT_KEY("nosnapshot", KEY_KERN), - FUSE_OPT_KEY("nomultilabel", KEY_KERN), - FUSE_OPT_KEY("noacls", KEY_KERN), - FUSE_OPT_KEY("noforce", KEY_KERN), - FUSE_OPT_KEY("noupdate", KEY_KERN), - FUSE_OPT_KEY("noro", KEY_KERN), - FUSE_OPT_KEY("norw", KEY_KERN), - FUSE_OPT_KEY("noauto", KEY_KERN), - FUSE_OPT_KEY("noallow_other", KEY_KERN), - FUSE_OPT_KEY("nodefault_permissions", KEY_KERN), - FUSE_OPT_KEY("noprivate", KEY_KERN), - FUSE_OPT_KEY("noneglect_shares", KEY_KERN), - FUSE_OPT_KEY("nopush_symlinks_in", KEY_KERN), - /* Linux specific mount options, but let just the mount util handle them */ - FUSE_OPT_KEY("fsname=", KEY_KERN), - FUSE_OPT_KEY("nonempty", KEY_KERN), - FUSE_OPT_KEY("large_read", KEY_KERN), - FUSE_OPT_KEY("max_read=", KEY_KERN), - FUSE_OPT_END + { "allow_other", offsetof(struct mount_opts, allow_other), 1 }, + { "allow_root", offsetof(struct mount_opts, allow_root), 1 }, + FUSE_OPT_KEY("allow_root", KEY_ALLOW_ROOT), + FUSE_OPT_KEY("-r", KEY_RO), + FUSE_OPT_KEY("-h", KEY_HELP), + FUSE_OPT_KEY("--help", KEY_HELP), + FUSE_OPT_KEY("-V", KEY_VERSION), + FUSE_OPT_KEY("--version", KEY_VERSION), + /* standard FreeBSD mount options */ + FUSE_OPT_KEY("dev", KEY_KERN), + FUSE_OPT_KEY("async", KEY_KERN), + FUSE_OPT_KEY("atime", KEY_KERN), + FUSE_OPT_KEY("dev", KEY_KERN), + FUSE_OPT_KEY("exec", KEY_KERN), + FUSE_OPT_KEY("suid", KEY_KERN), + FUSE_OPT_KEY("symfollow", KEY_KERN), + FUSE_OPT_KEY("rdonly", KEY_KERN), + FUSE_OPT_KEY("sync", KEY_KERN), + FUSE_OPT_KEY("union", KEY_KERN), + FUSE_OPT_KEY("userquota", KEY_KERN), + FUSE_OPT_KEY("groupquota", KEY_KERN), + FUSE_OPT_KEY("clusterr", KEY_KERN), + FUSE_OPT_KEY("clusterw", KEY_KERN), + FUSE_OPT_KEY("suiddir", KEY_KERN), + FUSE_OPT_KEY("snapshot", KEY_KERN), + FUSE_OPT_KEY("multilabel", KEY_KERN), + FUSE_OPT_KEY("acls", KEY_KERN), + FUSE_OPT_KEY("force", KEY_KERN), + FUSE_OPT_KEY("update", KEY_KERN), + FUSE_OPT_KEY("ro", KEY_KERN), + FUSE_OPT_KEY("rw", KEY_KERN), + FUSE_OPT_KEY("auto", KEY_KERN), + /* options supported under both Linux and FBSD */ + FUSE_OPT_KEY("allow_other", KEY_KERN), + FUSE_OPT_KEY("default_permissions", KEY_KERN), + /* FBSD FUSE specific mount options */ + FUSE_OPT_KEY("private", KEY_KERN), + FUSE_OPT_KEY("neglect_shares", KEY_KERN), + FUSE_OPT_KEY("push_symlinks_in", KEY_KERN), + /* stock FBSD mountopt parsing routine lets anything be negated... */ + FUSE_OPT_KEY("nodev", KEY_KERN), + FUSE_OPT_KEY("noasync", KEY_KERN), + FUSE_OPT_KEY("noatime", KEY_KERN), + FUSE_OPT_KEY("nodev", KEY_KERN), + FUSE_OPT_KEY("noexec", KEY_KERN), + FUSE_OPT_KEY("nosuid", KEY_KERN), + FUSE_OPT_KEY("nosymfollow", KEY_KERN), + FUSE_OPT_KEY("nordonly", KEY_KERN), + FUSE_OPT_KEY("nosync", KEY_KERN), + FUSE_OPT_KEY("nounion", KEY_KERN), + FUSE_OPT_KEY("nouserquota", KEY_KERN), + FUSE_OPT_KEY("nogroupquota", KEY_KERN), + FUSE_OPT_KEY("noclusterr", KEY_KERN), + FUSE_OPT_KEY("noclusterw", KEY_KERN), + FUSE_OPT_KEY("nosuiddir", KEY_KERN), + FUSE_OPT_KEY("nosnapshot", KEY_KERN), + FUSE_OPT_KEY("nomultilabel", KEY_KERN), + FUSE_OPT_KEY("noacls", KEY_KERN), + FUSE_OPT_KEY("noforce", KEY_KERN), + FUSE_OPT_KEY("noupdate", KEY_KERN), + FUSE_OPT_KEY("noro", KEY_KERN), + FUSE_OPT_KEY("norw", KEY_KERN), + FUSE_OPT_KEY("noauto", KEY_KERN), + FUSE_OPT_KEY("noallow_other", KEY_KERN), + FUSE_OPT_KEY("nodefault_permissions", KEY_KERN), + FUSE_OPT_KEY("noprivate", KEY_KERN), + FUSE_OPT_KEY("noneglect_shares", KEY_KERN), + FUSE_OPT_KEY("nopush_symlinks_in", KEY_KERN), + /* + * Linux specific mount options, but let just the mount util + * handle them + */ + FUSE_OPT_KEY("fsname=", KEY_KERN), + FUSE_OPT_KEY("nonempty", KEY_KERN), + FUSE_OPT_KEY("large_read", KEY_KERN), + FUSE_OPT_KEY("max_read=", KEY_KERN), + FUSE_OPT_END }; static void mount_help(void) { - fprintf(stderr, - " -o allow_root allow access to root\n" - ); - system(FUSERMOUNT_PROG " --help"); - fputc('\n', stderr); + fprintf(stderr, + " -o allow_root allow access to root\n" + ); + system(FUSERMOUNT_PROG " --help"); + fputc('\n', stderr); } static void mount_version(void) { - system(FUSERMOUNT_PROG " --version"); + system(FUSERMOUNT_PROG " --version"); } static int fuse_mount_opt_proc(void *data, const char *arg, int key, - struct fuse_args *outargs) + struct fuse_args *outargs) { - struct mount_opts *mo = data; - - switch (key) { - case KEY_ALLOW_ROOT: - if (fuse_opt_add_opt(&mo->kernel_opts, "allow_other") == -1 || - fuse_opt_add_arg(outargs, "-oallow_root") == -1) - return -1; - return 0; - - case KEY_RO: - arg = "ro"; - /* fall through */ - - case KEY_KERN: - return fuse_opt_add_opt(&mo->kernel_opts, arg); - - case KEY_HELP: - mount_help(); - mo->ishelp = 1; - break; - - case KEY_VERSION: - mount_version(); - mo->ishelp = 1; - break; - } - return 1; + struct mount_opts *mo = data; + + switch (key) { + case KEY_ALLOW_ROOT: + if (fuse_opt_add_opt(&mo->kernel_opts, "allow_other") == -1 || + fuse_opt_add_arg(outargs, "-oallow_root") == -1) + return -1; + return 0; + + case KEY_RO: + arg = "ro"; + /* fall through */ + + case KEY_KERN: + return fuse_opt_add_opt(&mo->kernel_opts, arg); + + case KEY_HELP: + mount_help(); + mo->ishelp = 1; + break; + + case KEY_VERSION: + mount_version(); + mo->ishelp = 1; + break; + } + return 1; } void fuse_unmount_compat22(const char *mountpoint) { - char dev[128]; - char *ssc, *umount_cmd; - FILE *sf; - int rv; - char *seekscript = - "exec 2>/dev/null; " /* error message is annoying in help output */ - "/usr/bin/fstat " FUSE_DEV_TRUNK "* | " - "/usr/bin/awk 'BEGIN{ getline; if (! ($3 == \"PID\" && $10 == \"NAME\")) exit 1; }; " - " { if ($3 == %d) print $10; }' | " - "/usr/bin/sort | " - "/usr/bin/uniq | " - "/usr/bin/awk '{ i += 1; if (i > 1){ exit 1; }; printf; }; END{ if (i == 0) exit 1; }'"; - - (void) mountpoint; - - /* - * If we don't know the fd, we have to resort to the scripted solution -- - * iterating over the fd-s is unpractical, as we don't know how many of - * open files we have. (This could be looked up in procfs -- however, - * that's optional on FBSD; or read out from the kmem -- however, that's - * bound to privileges (in fact, that's what happens when we call the - * setgid kmem fstat(1) utility). - */ - asprintf(&ssc, seekscript, getpid()); - - errno = 0; - sf = popen(ssc, "r"); - if (! sf) - return; - - fgets(dev, sizeof(dev), sf); - rv = pclose(sf); - if (rv) - return; - - asprintf(&umount_cmd, "/sbin/umount %s", dev); - system(umount_cmd); + char dev[128]; + char *ssc, *umount_cmd; + FILE *sf; + int rv; + char *seekscript = + /* error message is annoying in help output */ + "exec 2>/dev/null; " + "/usr/bin/fstat " FUSE_DEV_TRUNK "* | " + "/usr/bin/awk 'BEGIN{ getline; if (! ($3 == \"PID\" && $10 == \"NAME\")) exit 1; }; " + " { if ($3 == %d) print $10; }' | " + "/usr/bin/sort | " + "/usr/bin/uniq | " + "/usr/bin/awk '{ i += 1; if (i > 1){ exit 1; }; printf; }; END{ if (i == 0) exit 1; }'"; + + (void) mountpoint; + + /* + * If we don't know the fd, we have to resort to the scripted + * solution -- iterating over the fd-s is unpractical, as we + * don't know how many of open files we have. (This could be + * looked up in procfs -- however, that's optional on FBSD; or + * read out from the kmem -- however, that's bound to + * privileges (in fact, that's what happens when we call the + * setgid kmem fstat(1) utility). + */ + asprintf(&ssc, seekscript, getpid()); + + errno = 0; + sf = popen(ssc, "r"); + if (! sf) + return; + + fgets(dev, sizeof(dev), sf); + rv = pclose(sf); + if (rv) + return; + + asprintf(&umount_cmd, "/sbin/umount %s", dev); + system(umount_cmd); } void fuse_kern_unmount(const char *mountpoint, int fd) { - char *ep, *umount_cmd, dev[128]; - struct stat sbuf; + char *ep, *umount_cmd, dev[128]; + struct stat sbuf; - (void)mountpoint; + (void)mountpoint; - if (fstat(fd, &sbuf) == -1) - return; + if (fstat(fd, &sbuf) == -1) + return; - devname_r(sbuf.st_rdev, S_IFCHR, dev, 128); + devname_r(sbuf.st_rdev, S_IFCHR, dev, 128); - if (strncmp(dev, "fuse", 4)) - return; + if (strncmp(dev, "fuse", 4)) + return; - strtol(dev + 4, &ep, 10); - if (*ep != '\0') - return; + strtol(dev + 4, &ep, 10); + if (*ep != '\0') + return; - asprintf(&umount_cmd, "/sbin/umount " _PATH_DEV "%s", dev); - system(umount_cmd); + asprintf(&umount_cmd, "/sbin/umount " _PATH_DEV "%s", dev); + system(umount_cmd); } /* Check if kernel is doing init in background */ static int init_backgrounded(void) { - int ibg, len; + int ibg, len; - len = sizeof(ibg); + len = sizeof(ibg); - if (sysctlbyname("vfs.fuse.init_backgrounded", &ibg, &len, NULL, 0)) - return 0; + if (sysctlbyname("vfs.fuse.init_backgrounded", &ibg, &len, NULL, 0)) + return 0; - return ibg; + return ibg; } static int fuse_mount_core(const char *mountpoint, const char *opts) { - const char *mountprog = FUSERMOUNT_PROG; - int fd; - char *fdnam, *dev; - int pid; + const char *mountprog = FUSERMOUNT_PROG; + int fd; + char *fdnam, *dev; + int pid; - fdnam = getenv("FUSE_DEV_FD"); + fdnam = getenv("FUSE_DEV_FD"); - if (fdnam) { - char *ep; + if (fdnam) { + char *ep; - fd = strtol(fdnam, &ep, 10); + fd = strtol(fdnam, &ep, 10); - if (*ep != '\0') { - fprintf(stderr, "invalid value given in FUSE_DEV_FD\n"); - return -1; - } + if (*ep != '\0') { + fprintf(stderr, "invalid value given in FUSE_DEV_FD\n"); + return -1; + } - if (fd < 0) - return -1; + if (fd < 0) + return -1; - goto mount; - } + goto mount; + } - dev = getenv("FUSE_DEV_NAME"); + dev = getenv("FUSE_DEV_NAME"); - if (! dev) - dev = FUSE_DEV_TRUNK; + if (! dev) + dev = FUSE_DEV_TRUNK; - if ((fd = open(dev, O_RDWR)) < 0) { - perror("fuse: failed to open fuse device"); - return -1; - } + if ((fd = open(dev, O_RDWR)) < 0) { + perror("fuse: failed to open fuse device"); + return -1; + } mount: - if (getenv("FUSE_NO_MOUNT") || ! mountpoint) - goto out; - - pid = fork(); - - if (pid == -1) { - perror("fuse: fork() failed"); - close(fd); - return -1; - } - - if (pid == 0) { - if (! init_backgrounded()) { - /* - * If init is not backgrounded, we have to call the mount util - * backgrounded, to avoid deadlock. - */ - - pid = fork(); - - if (pid == -1) { - perror("fuse: fork() failed"); - close(fd); - exit(1); - } - } - - if (pid == 0) { - const char *argv[32]; - int a = 0; - - if (! fdnam) - asprintf(&fdnam, "%d", fd); - - argv[a++] = mountprog; - if (opts) { - argv[a++] = "-o"; - argv[a++] = opts; - } - argv[a++] = fdnam; - argv[a++] = mountpoint; - argv[a++] = NULL; - execvp(mountprog, (char **) argv); - perror("fuse: failed to exec mount program"); - exit(1); - } - - exit(0); - } - - waitpid(pid, NULL, 0); + if (getenv("FUSE_NO_MOUNT") || ! mountpoint) + goto out; + + pid = fork(); + + if (pid == -1) { + perror("fuse: fork() failed"); + close(fd); + return -1; + } + + if (pid == 0) { + if (! init_backgrounded()) { + /* + * If init is not backgrounded, we have to + * call the mount util backgrounded, to avoid + * deadlock. + */ + + pid = fork(); + + if (pid == -1) { + perror("fuse: fork() failed"); + close(fd); + exit(1); + } + } + + if (pid == 0) { + const char *argv[32]; + int a = 0; + + if (! fdnam) + asprintf(&fdnam, "%d", fd); + + argv[a++] = mountprog; + if (opts) { + argv[a++] = "-o"; + argv[a++] = opts; + } + argv[a++] = fdnam; + argv[a++] = mountpoint; + argv[a++] = NULL; + execvp(mountprog, (char **) argv); + perror("fuse: failed to exec mount program"); + exit(1); + } + + exit(0); + } + + waitpid(pid, NULL, 0); out: - return fd; + return fd; } int fuse_kern_mount(const char *mountpoint, struct fuse_args *args) { - struct mount_opts mo; - int res = -1; - - memset(&mo, 0, sizeof(mo)); - /* mount util should not try to spawn the daemon */ - setenv("MOUNT_FUSEFS_SAFE", "1", 1); - /* to notify the mount util it's called from lib */ - setenv("MOUNT_FUSEFS_CALL_BY_LIB", "1", 1); - - if (args && - fuse_opt_parse(args, &mo, fuse_mount_opts, fuse_mount_opt_proc) == -1) - return -1; - - if (mo.allow_other && mo.allow_root) { - fprintf(stderr, "fuse: 'allow_other' and 'allow_root' options are mutually exclusive\n"); - goto out; - } - if (mo.ishelp) - return 0; - - res = fuse_mount_core(mountpoint, mo.kernel_opts); - out: - free(mo.kernel_opts); - return res; + struct mount_opts mo; + int res = -1; + + memset(&mo, 0, sizeof(mo)); + /* mount util should not try to spawn the daemon */ + setenv("MOUNT_FUSEFS_SAFE", "1", 1); + /* to notify the mount util it's called from lib */ + setenv("MOUNT_FUSEFS_CALL_BY_LIB", "1", 1); + + if (args && + fuse_opt_parse(args, &mo, fuse_mount_opts, fuse_mount_opt_proc) == -1) + return -1; + + if (mo.allow_other && mo.allow_root) { + fprintf(stderr, "fuse: 'allow_other' and 'allow_root' options are mutually exclusive\n"); + goto out; + } + if (mo.ishelp) + return 0; + + res = fuse_mount_core(mountpoint, mo.kernel_opts); +out: + free(mo.kernel_opts); + return res; } FUSE_SYMVER(".symver fuse_unmount_compat22,fuse_unmount@FUSE_2.2"); -- cgit v1.2.3