diff options
Diffstat (limited to 'lib')
-rw-r--r-- | lib/fuse.c | 33 | ||||
-rw-r--r-- | lib/fuse_i.h | 10 | ||||
-rw-r--r-- | lib/helper.c | 131 | ||||
-rw-r--r-- | lib/mount.c | 22 |
4 files changed, 131 insertions, 65 deletions
@@ -1550,7 +1550,36 @@ static int check_version(struct fuse *f) return 0; } -struct fuse *fuse_new(int fd, int flags, const struct fuse_operations *op) + +int fuse_is_lib_option(const char *opt) +{ + if (strcmp(opt, "debug") == 0 || + strcmp(opt, "hard_remove") == 0) + return 1; + else + return 0; +} + +static void parse_lib_opts(struct fuse *f, const char *opts) +{ + if (opts) { + char *xopts = strdup(opts); + char *s = xopts; + char *opt; + + while((opt = strsep(&s, ","))) { + if (strcmp(opt, "debug") == 0) + f->flags |= FUSE_DEBUG; + else if (strcmp(opt, "hard_remove") == 0) + f->flags |= FUSE_HARD_REMOVE; + else + fprintf(stderr, "fuse: warning: unknown option `%s'\n", opt); + } + free(xopts); + } +} + +struct fuse *fuse_new(int fd, const char *opts, const struct fuse_operations *op) { struct fuse *f; struct node *root; @@ -1562,7 +1591,7 @@ struct fuse *fuse_new(int fd, int flags, const struct fuse_operations *op) return NULL; } - f->flags = flags; + parse_lib_opts(f, opts); f->fd = fd; f->ctr = 0; f->generation = 0; diff --git a/lib/fuse_i.h b/lib/fuse_i.h index 8942d74..58c0a41 100644 --- a/lib/fuse_i.h +++ b/lib/fuse_i.h @@ -10,6 +10,16 @@ #include <stdio.h> #include <pthread.h> +/* FUSE flags: */ + +/** Enable debuging output */ +#define FUSE_DEBUG (1 << 1) + +/** If a file is removed but it's still open, don't hide the file but + remove it immediately */ +#define FUSE_HARD_REMOVE (1 << 2) + + typedef unsigned long fino_t; struct node { diff --git a/lib/helper.c b/lib/helper.c index 76b6eb7..b75855a 100644 --- a/lib/helper.c +++ b/lib/helper.c @@ -25,23 +25,31 @@ struct fuse *fuse_get(void) static void usage(char *progname) { fprintf(stderr, - "usage: %s mountpoint [options] [-- [fusermount options]]\n" + "usage: %s mountpoint [options]\n" "Options:\n" - " -d enable debug output (implies -f)\n" - " -f foreground operation\n" - " -s disable multithreaded operation\n" - " -i immediate removal (don't delay until last release)\n" - " -h print help\n" + " -d enable debug output (implies -f)\n" + " -f foreground operation\n" + " -s disable multithreaded operation\n" + " -o opt,[opt...] mount options\n" + " -h print help\n" "\n" - "Fusermount options:\n" - " see 'fusermount -h'\n", + "Mount options:\n" + " default_permissions enable permission checking\n" + " allow_other allow access to other users\n" + " kernel_cache cache files in kernel\n" + " large_read issue large read requests (2.4 only)\n" + " direct_io use direct I/O\n" + " max_read=N set maximum size of read requests\n" + " hard_remove immediate removal (don't hide files)\n" + " debug enable debug output\n" + " fsname=NAME set filesystem name in mtab\n", progname); exit(1); } static void invalid_option(char *argv[], int argctr) { - fprintf(stderr, "invalid option: %s\n", argv[argctr]); + fprintf(stderr, "invalid option: %s\n\n", argv[argctr]); usage(argv[0]); } @@ -81,12 +89,12 @@ static void set_signal_handlers() set_one_signal_handler(SIGPIPE, SIG_IGN); } -static int fuse_start(int fuse_fd, int flags, int multithreaded, +static int fuse_do(int fuse_fd, const char *opts, int multithreaded, int background, const struct fuse_operations *op) { int pid; - fuse = fuse_new(fuse_fd, flags, op); + fuse = fuse_new(fuse_fd, opts, op); if (fuse == NULL) return 1; @@ -111,35 +119,79 @@ static int fuse_start(int fuse_fd, int flags, int multithreaded, return 0; } +static void add_option_to(const char *opt, char **optp) +{ + unsigned len = strlen(opt); + if (*optp) { + unsigned oldlen = strlen(*optp); + *optp = realloc(*optp, oldlen + 1 + len + 1); + (*optp)[oldlen] = ','; + strcpy(*optp + oldlen + 1, opt); + } else { + *optp = malloc(len + 1); + strcpy(*optp, opt); + } +} + +static void add_options(char **lib_optp, char **kernel_optp, const char *opts) +{ + char *xopts = strdup(opts); + char *s = xopts; + char *opt; + + while((opt = strsep(&s, ",")) != NULL) { + if (fuse_is_lib_option(opt)) + add_option_to(opt, lib_optp); + else + add_option_to(opt, kernel_optp); + } + free(xopts); +} + void fuse_main(int argc, char *argv[], const struct fuse_operations *op) { int argctr; - int flags; int multithreaded; int background; int fuse_fd; char *fuse_mountpoint = NULL; - char **fusermount_args = NULL; - char *newargs[3]; char *basename; + char *kernel_opts = NULL; + char *lib_opts = NULL; + char *fsname_opt; int err; + + basename = strrchr(argv[0], '/'); + if (basename == NULL) + basename = argv[0]; + else if (basename[1] != '\0') + basename++; + + fsname_opt = malloc(strlen(basename) + 64); + sprintf(fsname_opt, "fsname=%s", basename); + add_options(&lib_opts, &kernel_opts, fsname_opt); + free(fsname_opt); - flags = 0; multithreaded = 1; background = 1; - for (argctr = 1; argctr < argc && !fusermount_args; argctr ++) { + for (argctr = 1; argctr < argc; argctr ++) { if (argv[argctr][0] == '-') { if (strlen(argv[argctr]) == 2) switch (argv[argctr][1]) { + case 'o': + if (argctr + 1 == argc || argv[argctr+1][0] == '-') { + fprintf(stderr, "missing option after -o\n\n"); + usage(argv[0]); + } + argctr ++; + add_options(&lib_opts, &kernel_opts, argv[argctr]); + break; + case 'd': - flags |= FUSE_DEBUG; + add_options(&lib_opts, &kernel_opts, "debug"); background = 0; break; - case 'i': - flags |= FUSE_HARD_REMOVE; - break; - case 'f': background = 0; break; @@ -152,15 +204,15 @@ void fuse_main(int argc, char *argv[], const struct fuse_operations *op) usage(argv[0]); break; - case '-': - fusermount_args = &argv[argctr+1]; - break; - default: invalid_option(argv, argctr); } - else - invalid_option(argv, argctr); + else { + if (argv[argctr][1] == 'o') + add_options(&lib_opts, &kernel_opts, &argv[argctr][2]); + else + invalid_option(argv, argctr); + } } else if (fuse_mountpoint == NULL) fuse_mountpoint = strdup(argv[argctr]); else @@ -168,30 +220,19 @@ void fuse_main(int argc, char *argv[], const struct fuse_operations *op) } if (fuse_mountpoint == NULL) { - fprintf(stderr, "missing mountpoint\n"); + fprintf(stderr, "missing mountpoint\n\n"); usage(argv[0]); } - if (fusermount_args != NULL) - fusermount_args -= 2; /* Hack! */ - else { - fusermount_args = newargs; - fusermount_args[2] = NULL; - } - basename = strrchr(argv[0], '/'); - if (basename == NULL) - basename = argv[0]; - else if (basename[1] != '\0') - basename++; - - fusermount_args[0] = "-n"; - fusermount_args[1] = basename; - - fuse_fd = fuse_mount(fuse_mountpoint, (const char **) fusermount_args); + fuse_fd = fuse_mount(fuse_mountpoint, kernel_opts); if (fuse_fd == -1) exit(1); + if (kernel_opts) + free(kernel_opts); - err = fuse_start(fuse_fd, flags, multithreaded, background, op); + err = fuse_do(fuse_fd, lib_opts, multithreaded, background, op); + if (lib_opts) + free(lib_opts); close(fuse_fd); fuse_unmount(fuse_mountpoint); if (err) diff --git a/lib/mount.c b/lib/mount.c index 648dfbc..05dcb59 100644 --- a/lib/mount.c +++ b/lib/mount.c @@ -78,7 +78,7 @@ void fuse_unmount(const char *mountpoint) system(umount_cmd); } -int fuse_mount(const char *mountpoint, const char *args[]) +int fuse_mount(const char *mountpoint, const char *opts) { const char *mountprog = FUSERMOUNT_PROG; int fds[2], pid; @@ -101,28 +101,14 @@ int fuse_mount(const char *mountpoint, const char *args[]) if(pid == 0) { char env[10]; - char **newargv; - int numargs = 0; - int actr; - int i; - - if(args != NULL) - while(args[numargs] != NULL) - numargs ++; - - newargv = (char **) malloc((1 + numargs + 2) * sizeof(char *)); - actr = 0; - newargv[actr++] = strdup(mountprog); - for(i = 0; i < numargs; i++) - newargv[actr++] = strdup(args[i]); - newargv[actr++] = strdup(mountpoint); - newargv[actr++] = NULL; + const char *argv[] = {mountprog, opts ? "-o" : mountpoint, opts, + mountpoint, NULL}; close(fds[1]); fcntl(fds[0], F_SETFD, 0); snprintf(env, sizeof(env), "%i", fds[0]); setenv(FUSE_COMMFD_ENV, env, 1); - execvp(mountprog, newargv); + execvp(mountprog, (char **) argv); perror("fuse: failed to exec fusermount"); exit(1); } |