static int ciopfs_opt_parse(void *data, const char *arg, int key, struct fuse_args *outargs) { switch (key) { case FUSE_OPT_KEY_NONOPT: if (!dirname) { /* realpath(char *s, NULL) is a POSIX.1-2008 extension, originally from GLIBC, and might be unavailible on older non-glibc systems. */ if (!(dirname = realpath(arg, NULL))) { perror(outargs->argv[0]); exit(1); } return 0; } return 1; case FUSE_OPT_KEY_OPT: if (arg[0] == '-') { switch (arg[1]) { case 'd': case 'f': dolog = stderr_print; } } else if (!strcmp("allow_other", arg)) { /* disable multithreaded mode if the file system * is accessible to multiple users simultanousely * because we can't store uid/gid per thread and * this leads to all sorts of race conditions and * security issues. */ single_threaded = (getuid() == 0); } return 1; case CIOPFS_OPT_HELP: usage(outargs->argv[0]); fuse_opt_add_arg(outargs, "-ho"); fuse_main(outargs->argc, outargs->argv, &ciopfs_operations, NULL); exit(0); case CIOPFS_OPT_VERSION: fprintf(stderr, "%s: "VERSION" fuse: %d\n", outargs->argv[0], fuse_version()); exit(0); default: fprintf(stderr, "see `%s -h' for usage\n", outargs->argv[0]); exit(1); } return 1; }
/** * parse_options - Read and validate the programs command line * Read the command line, verify the syntax and parse the options. * * Return: 0 success, -1 error. */ int ntfs_parse_options(struct ntfs_options *popts, void (*usage)(void), int argc, char *argv[]) { int c; static const char *sopt = "-o:hnvV"; static const struct option lopt[] = { { "options", required_argument, NULL, 'o' }, { "help", no_argument, NULL, 'h' }, { "no-mtab", no_argument, NULL, 'n' }, { "verbose", no_argument, NULL, 'v' }, { "version", no_argument, NULL, 'V' }, { NULL, 0, NULL, 0 } }; opterr = 0; /* We'll handle the errors, thank you. */ while ((c = getopt_long(argc, argv, sopt, lopt, NULL)) != -1) { switch (c) { case 1: /* A non-option argument */ if (!popts->device) { popts->device = ntfs_malloc(PATH_MAX + 1); if (!popts->device) return -1; /* Canonicalize device name (mtab, etc) */ popts->arg_device = optarg; if (!ntfs_realpath_canonicalize(optarg, popts->device)) { ntfs_log_perror("%s: Failed to access " "volume '%s'", EXEC_NAME, optarg); free(popts->device); popts->device = NULL; return -1; } } else if (!popts->mnt_point) { popts->mnt_point = optarg; } else { ntfs_log_error("%s: You must specify exactly one " "device and exactly one mount " "point.\n", EXEC_NAME); return -1; } break; case 'o': if (popts->options) if (ntfs_strappend(&popts->options, ",")) return -1; if (ntfs_strappend(&popts->options, optarg)) return -1; break; case 'h': usage(); exit(9); case 'n': /* * no effect - automount passes it, meaning 'no-mtab' */ break; case 'v': /* * We must handle the 'verbose' option even if * we don't use it because mount(8) passes it. */ break; case 'V': ntfs_log_info("%s %s %s %d\n", EXEC_NAME, VERSION, FUSE_TYPE, fuse_version()); exit(0); default: ntfs_log_error("%s: Unknown option '%s'.\n", EXEC_NAME, argv[optind - 1]); return -1; } } if (!popts->device) { ntfs_log_error("%s: No device is specified.\n", EXEC_NAME); return -1; } if (!popts->mnt_point) { ntfs_log_error("%s: No mountpoint is specified.\n", EXEC_NAME); return -1; } return 0; }
int main() { return !(FUSE_VERSION == fuse_version()); }
void make_fsname(struct fuse_args *args) { char fsnamearg[256]; unsigned int l; #if HAVE_FUSE_VERSION int libver; libver = fuse_version(); if (libver >= 27) { l = snprintf(fsnamearg,256,"-osubtype=mfs%s,fsname=",(mfsopts.meta)?"meta":""); if (libver >= 28) { l += strncpy_escape_commas(fsnamearg+l,256-l,mfsopts.masterhost); if (l<255) { fsnamearg[l++]=':'; } l += strncpy_escape_commas(fsnamearg+l,256-l,mfsopts.masterport); if (mfsopts.subfolder[0]!='/') { if (l<255) { fsnamearg[l++]='/'; } } if (mfsopts.subfolder[0]!='/' && mfsopts.subfolder[1]!=0) { l += strncpy_escape_commas(fsnamearg+l,256-l,mfsopts.subfolder); } if (l>255) { l=255; } fsnamearg[l]=0; } else { l += strncpy_remove_commas(fsnamearg+l,256-l,mfsopts.masterhost); if (l<255) { fsnamearg[l++]=':'; } l += strncpy_remove_commas(fsnamearg+l,256-l,mfsopts.masterport); if (mfsopts.subfolder[0]!='/') { if (l<255) { fsnamearg[l++]='/'; } } if (mfsopts.subfolder[0]!='/' && mfsopts.subfolder[1]!=0) { l += strncpy_remove_commas(fsnamearg+l,256-l,mfsopts.subfolder); } if (l>255) { l=255; } fsnamearg[l]=0; } } else { #else l = snprintf(fsnamearg,256,"-ofsname=mfs%s#",(mfsopts.meta)?"meta":""); l += strncpy_remove_commas(fsnamearg+l,256-l,mfsopts.masterhost); if (l<255) { fsnamearg[l++]=':'; } l += strncpy_remove_commas(fsnamearg+l,256-l,mfsopts.masterport); if (mfsopts.subfolder[0]!='/') { if (l<255) { fsnamearg[l++]='/'; } } if (mfsopts.subfolder[0]!='/' && mfsopts.subfolder[1]!=0) { l += strncpy_remove_commas(fsnamearg+l,256-l,mfsopts.subfolder); } if (l>255) { l=255; } fsnamearg[l]=0; #endif #if HAVE_FUSE_VERSION } #endif fuse_opt_insert_arg(args, 1, fsnamearg); }
static void usage (void) { printf(usage_msg, PACKAGE, VERSION, fuse_version(), V2, HOME); }
int main (int argc, char *argv[]) { int err = 0; struct stat sbuf; char *parsed_options = NULL; struct fuse_args fargs = FUSE_ARGS_INIT(0, NULL); struct extfs_data opts; debugf("version:'%s', fuse_version:'%d'", VERSION, fuse_version()); memset(&opts, 0, sizeof(opts)); if (parse_options(argc, argv, &opts)) { usage(); return -1; } if (stat(opts.device, &sbuf)) { debugf_main("Failed to access '%s'", opts.device); err = -3; goto err_out; } if (do_probe(&opts) != 0) { debugf_main("Probe failed"); err = -4; goto err_out; } parsed_options = parse_mount_options(opts.options ? opts.options : "", &opts); if (!parsed_options) { err = -2; goto err_out; } debugf_main("opts.device: %s", opts.device); debugf_main("opts.mnt_point: %s", opts.mnt_point); debugf_main("opts.volname: %s", (opts.volname != NULL) ? opts.volname : ""); debugf_main("opts.options: %s", opts.options); debugf_main("parsed_options: %s", parsed_options); if (fuse_opt_add_arg(&fargs, PACKAGE) == -1 || fuse_opt_add_arg(&fargs, "-s") == -1 || fuse_opt_add_arg(&fargs, "-o") == -1 || fuse_opt_add_arg(&fargs, parsed_options) == -1 || fuse_opt_add_arg(&fargs, opts.mnt_point) == -1) { debugf_main("Failed to set FUSE options"); fuse_opt_free_args(&fargs); err = -5; goto err_out; } if (opts.readonly == 0) { debugf_main("mounting read-write"); } else { debugf_main("mounting read-only"); } fuse_main(fargs.argc, fargs.argv, &ext2fs_ops, &opts); err_out: fuse_opt_free_args(&fargs); free(parsed_options); free(opts.options); free(opts.device); free(opts.volname); return err; }
int do_mount(char *spec, char *dir, int mflag, char *opt) { // VERIFY(mflag == 0); vfs_t *vfs = kmem_zalloc(sizeof(vfs_t), KM_SLEEP); if(vfs == NULL) return ENOMEM; VFS_INIT(vfs, zfs_vfsops, 0); VFS_HOLD(vfs); struct mounta uap = { .spec = spec, .dir = dir, .flags = mflag | MS_SYSSPACE, .fstype = "zfs-fuse", .dataptr = "", .datalen = 0, .optptr = opt, .optlen = strlen(opt) }; int ret; if ((ret = VFS_MOUNT(vfs, rootdir, &uap, kcred)) != 0) { kmem_free(vfs, sizeof(vfs_t)); return ret; } /* Actually, optptr is totally ignored by VFS_MOUNT. * So we are going to pass this with fuse_mount_options if possible */ if (fuse_mount_options == NULL) fuse_mount_options = ""; char real_opts[1024]; *real_opts = 0; if (*fuse_mount_options) strcat(real_opts,fuse_mount_options); // comes with a starting , if (*opt) sprintf(&real_opts[strlen(real_opts)],",%s",opt); #ifdef DEBUG atomic_inc_32(&mounted);; fprintf(stderr, "mounting %s\n", dir); #endif char *fuse_opts = NULL; int has_default_perm = 0; if (fuse_version() <= 27) { if(asprintf(&fuse_opts, FUSE_OPTIONS, spec, real_opts) == -1) { VERIFY(do_umount(vfs, B_FALSE) == 0); return ENOMEM; } } else { if(asprintf(&fuse_opts, FUSE_OPTIONS ",big_writes", spec, real_opts) == -1) { VERIFY(do_umount(vfs, B_FALSE) == 0); return ENOMEM; } } struct fuse_args args = FUSE_ARGS_INIT(0, NULL); if(fuse_opt_add_arg(&args, "") == -1 || fuse_opt_add_arg(&args, "-o") == -1 || fuse_opt_add_arg(&args, fuse_opts) == -1) { fuse_opt_free_args(&args); free(fuse_opts); VERIFY(do_umount(vfs, B_FALSE) == 0); return ENOMEM; } has_default_perm = detect_fuseoption(fuse_opts,"default_permissions"); free(fuse_opts); struct fuse_chan *ch = fuse_mount(dir, &args); if(ch == NULL) { VERIFY(do_umount(vfs, B_FALSE) == 0); return EIO; } if (has_default_perm) vfs->fuse_attribute = FUSE_VFS_HAS_DEFAULT_PERM; struct fuse_session *se = fuse_lowlevel_new(&args, &zfs_operations, sizeof(zfs_operations), vfs); fuse_opt_free_args(&args); if(se == NULL) { VERIFY(do_umount(vfs, B_FALSE) == 0); /* ZFSFUSE: FIXME?? */ fuse_unmount(dir,ch); return EIO; } fuse_session_add_chan(se, ch); if(zfsfuse_newfs(dir, ch) != 0) { fuse_session_destroy(se); fuse_unmount(dir,ch); return EIO; } return 0; }