static int opt_parse(struct fuse_opt_context *ctx) { if (ctx->argc) { if (add_arg(ctx, ctx->argv[0]) == -1) return -1; } for (ctx->argctr = 1; ctx->argctr < ctx->argc; ctx->argctr++) if (process_one(ctx, ctx->argv[ctx->argctr]) == -1) return -1; if (ctx->opts) { if (fuse_opt_insert_arg(&ctx->outargs, 1, "-o") == -1 || fuse_opt_insert_arg(&ctx->outargs, 2, ctx->opts) == -1) return -1; } /* If option separator ("--") is the last argument, remove it */ if (ctx->nonopt && ctx->nonopt == ctx->outargs.argc && strcmp(ctx->outargs.argv[ctx->outargs.argc - 1], "--") == 0) { free(ctx->outargs.argv[ctx->outargs.argc - 1]); ctx->outargs.argv[--ctx->outargs.argc] = NULL; } return 0; }
struct fuse_args * parse_options(int argc, char *argv[]) { struct fuse_args * args=calloc(1, sizeof(struct fuse_args)); struct cow_config *conf = cow_getConfig(); int pathmaxcnt = 0; do{ pathmaxcnt++; conf->cwd = calloc(PATH_MAX*pathmaxcnt, sizeof(char)); if(getcwd(conf->cwd, PATH_MAX*pathmaxcnt)==NULL){ free(conf->cwd); conf->cwd = NULL; } }while(conf->cwd==NULL && errno == ERANGE); if(conf->cwd==NULL){ fprintf(stderr, "ERROR: couldnt allocate current working directory buffer (%d)\n", errno); exit(-1); } { struct fuse_args tmp=FUSE_ARGS_INIT(argc, argv); memcpy(args, &tmp, sizeof(struct fuse_args)); } if (fuse_opt_parse(args, cow_getConfig(), cow_opts, cow_opt_proc)==-1) exit(-1); char *cliopt = NULL; int clilen = strlen(FUSE_MP_OPT_STR)+strlen(conf->srcdir)+1; int i = 0; for(i=0;i<conf->dstdircnt;i++){ if(i) clilen++; /* separator character */ clilen += strlen(conf->dstdirs[i]); } clilen++; /* null byte */ cliopt = calloc(clilen, sizeof(char)); sprintf(cliopt, "%s%s=", FUSE_MP_OPT_STR, conf->srcdir); for(i=0;i<conf->dstdircnt;i++){ if(i) strcat(cliopt, ";"); strcat(cliopt, conf->dstdirs[i]); } fuse_opt_insert_arg(args, 1, cliopt); fuse_opt_insert_arg(args, 1, conf->mountpt); return args; }
/* ----------------------------------------------------- */ int main(int argc,char* argv[]) { signal(SIGINT, fs_sigint_handler); fs_set_limit_attr(); if (mpinit(0, 50)) return -1; voolefs.tc = 10; voolefs.tpool = threadpool_init(voolefs.tc ,10); voolefs.cinc = 8; voolefs.phost = mpcalloc(sizeof(struct host)); voolefs.phost->host = inet_addr("123.125.149.11"); voolefs.phost->port = htons(4869); voolefs.hostc = 1; voolefs.semc = 20; char* pmpoint = fs_create_mountpoint(); struct fuse_args args = FUSE_ARGS_INIT(argc, argv); char *fsname =(char*)mpcalloc(256); sprintf(fsname,"-osubtype=%s,fsname=%s",argv[0],pmpoint); mpfree(pmpoint); int ret = fuse_opt_parse(&args, NULL,NULL,NULL /*&voolefs, voolefs_opts, fs_opt_proc*/); int multithreaded = 0; int foreground = 0; ret = fuse_opt_insert_arg(&args,1,fsname); /* if (fuse_is_lib_option("ac_attr_timeout=")) fuse_opt_insert_arg(&args, 1, "-oauto_cache,ac_attr_timeout=0"); */ ret = fuse_parse_cmdline(&args, &voolefs.mountpoint, &multithreaded, &foreground); voolefs.ch = fuse_mount(voolefs.mountpoint, &args); // event_reinit(voolefs.ev_base); if(voolefs.ch) { ret = fcntl(fuse_chan_fd(voolefs.ch), F_SETFD, FD_CLOEXEC); voolefs.fuse = fuse_new(voolefs.ch,&args,&oper,sizeof(struct fuse_operations),NULL); if (voolefs.fuse == NULL) { fs_cleanup(); abort(); } fs_daemonize(0); voole_net_create(); /* if( multithreaded) ret = fuse_loop_mt(voolefs.fuse); else */ ret = fuse_loop(voolefs.fuse); } if( voolefs.fuse ) fuse_remove_signal_handlers(fuse_get_session(voolefs.fuse)); mpfree(fsname); if( voolefs.peventbase ) { event_base_free(voolefs.peventbase); voolefs.peventbase = NULL; } return ret; }
static int opt_parse(struct fuse_opt_context *ctx) { if (ctx->argc) { if (add_arg(ctx, ctx->argv[0]) == -1) return -1; } for (ctx->argctr = 1; ctx->argctr < ctx->argc; ctx->argctr++) if (process_one(ctx, ctx->argv[ctx->argctr]) == -1) return -1; if (ctx->opts) { if (fuse_opt_insert_arg(&ctx->outargs, 1, "-o") == -1 || fuse_opt_insert_arg(&ctx->outargs, 2, ctx->opts) == -1) return -1; } if (ctx->nonopt && ctx->nonopt == ctx->outargs.argc) { free(ctx->outargs.argv[ctx->outargs.argc - 1]); ctx->outargs.argv[--ctx->outargs.argc] = NULL; } return 0; }
static int call_proc(fuse_opt_proc_t proc, void* data, const char* arg, int key, struct fuse_args *outargs, bool is_opt) { if (key == FUSE_OPT_KEY_DISCARD) return 0; if (key != FUSE_OPT_KEY_KEEP && proc != NULL) { const int rv = proc(data, arg, key, outargs); if (rv == -1 || /* error */ rv == 0 /* discard */) return rv; } if (is_opt) { /* Do we already have "-o" at the beginning of outargs? */ if (outargs->argc >= 3 && strcmp(outargs->argv[1], "-o") == 0) { /* Append the option to the comma-separated list. */ if (fuse_opt_add_opt_escaped(&outargs->argv[2], arg) == -1) return -1; } else { /* Insert -o arg at the beginning. */ if (fuse_opt_insert_arg(outargs, 1, "-o") == -1) return -1; if (fuse_opt_insert_arg(outargs, 2, arg) == -1) return -1; } } else { if (fuse_opt_add_arg(outargs, arg) == -1) return -1; } return 0; }
int fuse_opt_add_arg(struct fuse_args *args, const char *name) { return (fuse_opt_insert_arg(args, args->argc, name)); }
int main(int argc, char **argv) { int ret, i, cmd_args_len; struct fuse_args args = FUSE_ARGS_INIT(argc, argv); struct ltfs_fuse_data *priv = (struct ltfs_fuse_data *) calloc(1, sizeof(struct ltfs_fuse_data)); char *lang, **mount_options, **snmp_options, *cmd_args; void *message_handle; /* Suppress warning on Windows builds. */ #ifdef HP_mingw_BUILD (void) lang; (void) mount_options; #endif /* HP_mingw_BUILD */ priv->verbose = LTFS_INFO; priv->allow_other = (geteuid() == 0) ? 1 : 0; priv->pid_orig = getpid(); #ifndef HP_mingw_BUILD /* Check for LANG variable and set it to en_US.UTF-8 if it is unset. */ lang = getenv("LANG"); if (! lang) { fprintf(stderr, "LTFS9015W Setting the locale to 'en_US.UTF-8'. If this is wrong, please set the LANG environment variable before starting ltfs.\n"); ret = setenv("LANG", "en_US.UTF-8", 1); if (ret) { fprintf(stderr, "LTFS9016E Cannot set the LANG environment variable\n"); return 1; } } #endif /* HP_mingw_BUILD */ /* Start up libltfs with the default logging level. User overrides are * processed later, after command line parsing. */ openlog("ltfs", LOG_PID, LOG_USER); ret = ltfs_init(LTFS_INFO, true, true); if (ret < 0) { /* Failed to initialize libltfs */ ltfsmsg(LTFS_ERR, "10000E", ret); } /* Register messages with libltfs */ ret = ltfsprintf_load_plugin("bin_ltfs", bin_ltfs_dat, &message_handle); if (ret < 0) { ltfsmsg(LTFS_ERR, "10012E", ret); return 1; } if (! priv) { ltfsmsg(LTFS_ERR, "10001E", "main: private data"); return 1; } /* Parse command line options to pick up the configuration file */ priv->first_parsing_pass = true; ret = fuse_opt_parse(&args, priv, ltfs_options_pass1, ltfs_parse_options); if (ret < 0) { ltfsmsg(LTFS_ERR, "9001E"); return 1; } /* Load the configuration file */ ret = config_file_load(priv->config_file, &priv->config); if (ret < 0) { ltfsmsg(LTFS_ERR, "10008E", ret); return 1; } /* We don't use this in HP-SOS. The code is present but it will always endup indicating that * snmp is disabled. */ /* Get snmp option value from configuration file */ snmp_options = config_file_get_options("snmp", priv->config); if (snmp_options) { priv->snmp_enabled = false; for (i=0; snmp_options[i]; ++i) { if (! strcmp(snmp_options[i], "enabled")) priv->snmp_enabled = true; else if (! strncmp(snmp_options[i], "deffile ", 8)) { ret = asprintf(&priv->snmp_deffile, "%s", snmp_options[i]+8); if (ret < 0) { ltfsmsg(LTFS_ERR, "10001E", "library_main: snmp_deffile"); priv->snmp_enabled = false; break; } } } if (priv->snmp_enabled) { #if 0 ltfs_snmp_init(priv->snmp_deffile); #endif /* 0 */ } } /* Not supported on Windows. TODO: Verify this again.*/ #ifndef HP_mingw_BUILD /* Bring in extra mount options set in the config file */ mount_options = config_file_get_options("single-drive", priv->config); if (! mount_options) return 1; for (i=0; mount_options[i]; ++i) { ret = fuse_opt_insert_arg(&args, i+1, mount_options[i]); if (ret < 0) { /* Could not enable FUSE option */ ltfsmsg(LTFS_ERR, "14001E", mount_options[i], ret); return 1; } free(mount_options[i]); } free(mount_options); #endif /* HP_mingw_BUILD */ /* Parse command line options again, this time for real */ priv->first_parsing_pass = false; ret = fuse_opt_parse(&args, priv, ltfs_options, ltfs_parse_options); if (ret < 0) { ltfsmsg(LTFS_ERR, "9001E"); return 1; } /* Set the logging level */ if (priv->verbose > 100) ltfs_set_syslog_level(priv->verbose / 100); ltfs_set_log_level(priv->verbose % 100); /* LTFS starting */ #ifdef GENERIC_OEM_BUILD ltfsmsg(LTFS_INFO, "14000I", SOFTWARE_PRODUCT_NAME, PACKAGE_VERSION, priv->verbose); #else ltfsmsg(LTFS_INFO, "14000I", LTFS_VENDOR_NAME SOFTWARE_PRODUCT_NAME, PACKAGE_VERSION, priv->verbose); #endif /* GENERIC_OEM_BUILD */ ltfsmsg(LTFS_INFO, "14058I", "LTFS Format Specification", LTFS_INDEX_VERSION_STR); /* Show command line arguments */ for (i = 0, cmd_args_len = 0 ; i < argc; i++) { cmd_args_len += strlen(argv[i]) + 1; } cmd_args = calloc(1, cmd_args_len + 1); if (!cmd_args) { /* Memory allocation failed */ ltfsmsg(LTFS_ERR, "10001E", "ltfs (arguments)"); return -ENOMEM; } strcat(cmd_args, argv[0]); for (i = 1; i < argc; i++) { strcat(cmd_args, " "); strcat(cmd_args, argv[i]); } ltfsmsg(LTFS_INFO, "14104I", cmd_args); free(cmd_args); /* Show build time information */ ltfsmsg(LTFS_INFO, "14105I", BUILD_SYS_FOR); ltfsmsg(LTFS_INFO, "14106I", BUILD_SYS_GCC); /* Show run time information */ show_runtime_system_info(); /* Show avaliable tape device list */ if (priv->device_list) { ret = show_device_list(priv); ltfs_finish(); return (ret != 0) ? 0 : 1; } /* Validate sync option */ ret = validate_sync_option(priv); if (ret != 0) return 1; /* Error message was already displayed */ /* Print the active sync mode */ switch(priv->sync_type) { case LTFS_SYNC_TIME: ltfsmsg(LTFS_INFO, "14063I", "time", priv->sync_time); break; case LTFS_SYNC_CLOSE: ltfsmsg(LTFS_INFO, "14064I", "close"); break; case LTFS_SYNC_UNMOUNT: ltfsmsg(LTFS_INFO, "14064I", "unmount"); break; default: ltfsmsg(LTFS_ERR, "14065E", priv->sync_type); return 1; } /* Enable correct permissions checking in the kernel if any permission overrides are set */ ret = fuse_opt_add_arg(&args, "-odefault_permissions"); if (ret < 0) { /* Could not enable FUSE option */ ltfsmsg(LTFS_ERR, "14001E", "default_permissions", ret); return 1; } /* Let all users access this filesystem by default */ if (priv->allow_other) { ret = fuse_opt_add_arg(&args, "-oallow_other"); if (ret < 0) { /* Could not enable FUSE option */ ltfsmsg(LTFS_ERR, "14001E", "allow_other", ret); return 1; } } /* Unlink objects from the file system instead of having them renamed to .fuse_hidden */ ret = fuse_opt_add_arg(&args, "-ohard_remove"); if (ret < 0) { /* Could not enable FUSE option */ ltfsmsg(LTFS_ERR, "14001E", "hard_remove", ret); return 1; } /* perform reads synchronously */ ret = fuse_opt_add_arg(&args, "-osync_read"); if (ret < 0) { /* Could not enable FUSE option */ ltfsmsg(LTFS_ERR, "14001E", "sync_read", ret); return 1; } #ifdef __APPLE__ /* Change MacFUSE timeout from 60 secs to 3100 secs (41mins) */ /* 3100 secs comes from the timeout value of locate/space, it is the most longest timeout value */ /* in the commands used by LTFS. Actually the timeout value of locate/space is 2500 secs, */ /* we set the MacFUSE as the timeout value of locate/space + 10 mins. Because MacFUSE timeout */ /* should come after the drive command timeout. */ fuse_opt_add_arg(&args, "-odaemon_timeout=3100"); if (ret < 0) { /* Could not enable FUSE option */ ltfsmsg(LTFS_ERR, "14001E", "daemon_timeout", ret); return 1; } /* * Disable vnode cache to return correct owner. * LTFS will return the owner as accessed user, vnode cache will return previous user * when the cache is hot. */ fuse_opt_add_arg(&args, "-onovncache"); if (ret < 0) { /* Could not enable FUSE option */ ltfsmsg(LTFS_ERR, "14001E", "novncache", ret); return 1; } #endif #if FUSE_VERSION >= 28 /* For FUSE 2.8 or higher, automatically enable big_writes */ ret = fuse_opt_add_arg(&args, "-obig_writes"); if (ret < 0) { /* Could not enable FUSE option */ ltfsmsg(LTFS_ERR, "14001E", "big_writes", ret); return 1; } #endif /* Set up permissions based on mount options and current user information */ ret = permissions_setup(priv); if (ret < 0) { /* Failed to set up permissions */ ltfsmsg(LTFS_ERR, "14002E", ret); usage(argv[0], priv); return 1; } /* Bring in some configuration defaults if needed */ if (priv->tape_backend_name == NULL) { priv->tape_backend_name = config_file_get_default_plugin("driver", priv->config); if (priv->tape_backend_name == NULL) { /* No driver plugin configured and no default found */ ltfsmsg(LTFS_ERR, "14056E"); return 1; } } if (priv->iosched_backend_name == NULL) priv->iosched_backend_name = config_file_get_default_plugin("iosched", priv->config); if (priv->iosched_backend_name && strcmp(priv->iosched_backend_name, "none") == 0) priv->iosched_backend_name = NULL; if (priv->kmi_backend_name == NULL) priv->kmi_backend_name = config_file_get_default_plugin("kmi", priv->config); if (priv->kmi_backend_name && strcmp(priv->kmi_backend_name, "none") == 0) priv->kmi_backend_name = NULL; if (priv->work_directory == NULL || ! strcmp(priv->work_directory, "")) priv->work_directory = LTFS_DEFAULT_WORK_DIR; if (priv->force_min_pool) { priv->min_pool_size = parse_size_t(priv->force_min_pool); if (priv->min_pool_size == 0) { ltfsmsg(LTFS_ERR, "14109E"); return 1; } } else priv->min_pool_size = LTFS_MIN_CACHE_SIZE_DEFAULT; if (priv->force_max_pool) { priv->max_pool_size = parse_size_t(priv->force_max_pool); if (priv->max_pool_size == 0) { ltfsmsg(LTFS_ERR, "14110E"); return 1; } } else priv->max_pool_size = LTFS_MAX_CACHE_SIZE_DEFAULT; if (priv->min_pool_size > priv->max_pool_size) { /* Min pool size cannot be greater than max pool size */ ltfsmsg(LTFS_ERR, "14003E", priv->min_pool_size, priv->max_pool_size); return 1; } /* * Make sure at least one parameter was provided (mount point). * If exactly one param, check if it's an accessible directory. * With more than one param, have to defer to fuse_main to find if valid. */ #ifndef HP_mingw_BUILD struct stat mpstatbuf; #endif /* HP_mingw_BUILD */ if (argc < 2) { ltfsmsg(LTFS_ERR, "14200E"); /* missing mountpoint parameter */ usage (argv[0], priv); return 1; } /* OSR * * In our MinGW environment, the mount point does not exist when * the file system is executed */ #ifndef HP_mingw_BUILD if (argc == 2) { ret = stat(argv[1], &mpstatbuf); if (ret < 0) { /* Path does not exist */ ltfsmsg(LTFS_ERR, "14201E", argv[1]); return 1; } else if (! S_ISDIR(mpstatbuf.st_mode)) { /* Path exists but is not a directory */ ltfsmsg(LTFS_ERR, "14201E", argv[1]); return 1; } } #endif /* HP_mingw_BUILD */ /* Make sure work directory exists */ ret = create_workdir(priv); if (ret < 0) { if (priv->work_directory) { free((void *)priv->work_directory); priv->work_directory = NULL; priv->work_directory = LTFS_DEFAULT_WORK_DIR; } } /* Load plugins */ ret = plugin_load(&priv->driver_plugin, "driver", priv->tape_backend_name, priv->config); if (ret < 0) { ltfsmsg(LTFS_ERR, "14054E", ret); return 1; } if (priv->iosched_backend_name) { ret = plugin_load(&priv->iosched_plugin, "iosched", priv->iosched_backend_name, priv->config); if (ret < 0) { ltfsmsg(LTFS_ERR, "14055E", ret); return 1; } } if (priv->kmi_backend_name) { ret = plugin_load(&priv->kmi_plugin, "kmi", priv->kmi_backend_name, priv->config); if (ret < 0) { ltfsmsg(LTFS_ERR, "14057E", ret); return 1; } } /* Make sure we have a device name */ if (! priv->devname) { priv->devname = ltfs_default_device_name(priv->driver_plugin.ops); if (! priv->devname) { /* The backend \'%s\' does not have a default device */ ltfsmsg(LTFS_ERR, "14009E", priv->tape_backend_name); return 1; } } /* Initialize filesystem component in libltfs */ ret = ltfs_fs_init(); if (ret) return 1; /* Invoke the single drive main operations */ ret = ltfs_mutex_init(&priv->file_table_lock); if (ret) { /* Cannot initialize open file table */ ltfsmsg(LTFS_ERR, "14114E"); return 1; } ret = single_drive_main(&args, priv); /* Send a trap of LTFS termination */ #if 0 if (priv->snmp_enabled) ltfs_snmp_finish(); #endif /* 0 */ /* Unload plugins */ if (priv->iosched_backend_name) plugin_unload(&priv->iosched_plugin); if (priv->kmi_backend_name) plugin_unload(&priv->kmi_plugin); plugin_unload(&priv->driver_plugin); /* Free data structures */ ltfsprintf_unload_plugin(message_handle); ltfs_finish(); config_file_free(priv->config); free(priv); fuse_opt_free_args(&args); return ret; }
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); }
int main(int argc, char** argv) { CURL *easy; CURLcode curl_res; char *tmp; int res; struct fuse_args args = FUSE_ARGS_INIT(argc, argv); /* Initialize curl library before we are a multithreaded program */ curl_global_init(CURL_GLOBAL_ALL); memset(&ftpfs, 0, sizeof ftpfs); /* Set some default values */ ftpfs.curl_version = curl_version_info(CURLVERSION_NOW); ftpfs.safe_nobody = ftpfs.curl_version->version_num > CURLFTPFS_BAD_NOBODY; ftpfs.blksize = 4096; ftpfs.disable_epsv = 1; ftpfs.multiconn = 1; ftpfs.attached_to_multi = 0; if (fuse_opt_parse(&args, &ftpfs, ftpfs_opts, ftpfs_opt_proc) == -1) return 1; if (!ftpfs.host) { fprintf(stderr, "missing host\n"); fprintf(stderr, "see `%s -h' for usage\n", argv[0]); return 1; } if (!ftpfs.iocharset) { ftpfs.iocharset = "UTF8"; } if (ftpfs.codepage) { convert_charsets(ftpfs.iocharset, ftpfs.codepage, &ftpfs.host); } easy = curl_easy_init(); if (easy == NULL) { fprintf(stderr, "Error initializing libcurl\n"); return 1; } res = cache_parse_options(&args); if (res == -1) return 1; if (!prompt_passwd("host", &ftpfs.user)) return 1; if (!prompt_passwd("proxy", &ftpfs.proxy_user)) return 1; if (ftpfs.transform_symlinks && !ftpfs.mountpoint) { fprintf(stderr, "cannot transform symlinks: no mountpoint given\n"); return 1; } if (!ftpfs.transform_symlinks) ftpfs.symlink_prefix_len = 0; else if (realpath(ftpfs.mountpoint, ftpfs.symlink_prefix) != NULL) ftpfs.symlink_prefix_len = strlen(ftpfs.symlink_prefix); else { fprintf(stderr, "unable to normalize mount path\n"); return 1; } set_common_curl_stuff(easy); curl_easy_setopt_or_die(easy, CURLOPT_WRITEDATA, NULL); curl_easy_setopt_or_die(easy, CURLOPT_NOBODY, ftpfs.safe_nobody); curl_res = curl_easy_perform(easy); if (curl_res != 0) ftpfs_curl_easy_perform_abort(); curl_easy_setopt_or_die(easy, CURLOPT_NOBODY, 0); ftpfs.multi = curl_multi_init(); if (ftpfs.multi == NULL) { fprintf(stderr, "Error initializing libcurl multi\n"); return 1; } ftpfs.connection = easy; pthread_mutex_init(&ftpfs.lock, NULL); /* Set the filesystem name to show the current server */ tmp = g_strdup_printf("-ofsname=curlftpfs#%s", ftpfs.host); fuse_opt_insert_arg(&args, 1, tmp); g_free(tmp); res = ftpfs_fuse_main(&args); cancel_previous_multi(); curl_multi_cleanup(ftpfs.multi); curl_easy_cleanup(easy); curl_global_cleanup(); fuse_opt_free_args(&args); pthread_mutex_destroy(&ftpfs.lock); cache_deinit(); return res; }