int main(int argc, char *argv[]) { struct fuse_args args = FUSE_ARGS_INIT(argc, argv); char *mountpoint; int err = -1; int fd; if (fuse_parse_cmdline(&args, &mountpoint, NULL, NULL) != -1 && (fd = fuse_mount(mountpoint, &args)) != -1) { struct fuse_session *se; se = fuse_lowlevel_new(&args, &hello_ll_oper, sizeof(hello_ll_oper), NULL); if (se != NULL) { if (fuse_set_signal_handlers(se) != -1) { struct fuse_chan *ch = fuse_kern_chan_new(fd); if (ch != NULL) { fuse_session_add_chan(se, ch); err = fuse_session_loop(se); } fuse_remove_signal_handlers(se); } fuse_session_destroy(se); } close(fd); } fuse_unmount(mountpoint); fuse_opt_free_args(&args); return err ? 1 : 0; }
int main(int argc, char** argv) { struct fuse_args args = FUSE_ARGS_INIT(argc, argv); char* mountpoint; int multithreaded; int foreground; if (fuse_opt_parse(&args, NULL, tfs_opts, tfs_opt_proc) == -1) return 1; if (fuse_parse_cmdline(&args, &mountpoint, &multithreaded, &foreground) == -1) return 1; struct fuse_chan *ch = fuse_mount(mountpoint, &args); if (!ch) return 1; struct fuse *fuse = fuse_new(ch, &args, &tfs_oper, sizeof(struct fuse_operations), NULL); if (!fuse) { fuse_unmount(mountpoint, ch); return 1; } if (options.debug == 1 || foreground == 1) { if (fuse_daemonize(foreground) != -1) return 1; } if (fuse_set_signal_handlers(fuse_get_session(fuse)) == -1) { fuse_unmount(mountpoint, ch); fuse_destroy(fuse); return 1; } initMultiCastListener(); if (multithreaded) return fuse_loop_mt(fuse); if (!options.debug) fprintf(stderr, "Running single threaded and we are not debugging, your performance may suffer.\n"); return fuse_loop(fuse); };
struct fuse * fuse_setup(int argc, char **argv, const struct fuse_operations *ops, size_t size, char **mp, int *mt, void *data) { struct fuse_args args = FUSE_ARGS_INIT(argc, argv); struct fuse_chan *fc; struct fuse *fuse; int fg; if (fuse_parse_cmdline(&args, mp, mt, &fg)) goto err; fuse_daemonize(0); if ((fc = fuse_mount(*mp, NULL)) == NULL) goto err; if ((fuse = fuse_new(fc, NULL, ops, size, data)) == NULL) { free(fc); goto err; } return (fuse); err: free(*mp); return (NULL); }
struct fuse *fuse_setup_common(int argc, char *argv[], const struct fuse_operations *op, size_t op_size, char **mountpoint, int *multithreaded, int *fd, void *user_data, int compat) { struct fuse_args args = FUSE_ARGS_INIT(argc, argv); struct fuse_chan *ch; struct fuse *fuse; int foreground; int res; res = fuse_parse_cmdline(&args, mountpoint, multithreaded, &foreground); if (res == -1) return NULL; #ifdef __APPLE__ if (!*mountpoint) { fprintf(stderr, "fuse: no mount point\n"); return NULL; } #endif ch = fuse_mount_common(*mountpoint, &args); if (!ch) { fuse_opt_free_args(&args); goto err_free; } fuse = fuse_new_common(ch, &args, op, op_size, user_data, compat); fuse_opt_free_args(&args); if (fuse == NULL) goto err_unmount; res = fuse_daemonize(foreground); if (res == -1) goto err_unmount; res = fuse_set_signal_handlers(fuse_get_session(fuse)); if (res == -1) goto err_unmount; if (fd) *fd = fuse_chan_fd(ch); return fuse; err_unmount: fuse_unmount_common(*mountpoint, ch); if (fuse) fuse_destroy(fuse); err_free: free(*mountpoint); return NULL; }
/* ----------------------------------------------------- */ 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; }
int main(int argc, char *argv[]){ // Initialize an empty argument list struct fuse_args mountpt = FUSE_ARGS_INIT(0, NULL); // add program and mountpoint fuse_opt_add_arg(&mountpt, argv[0]); fuse_opt_add_arg(&mountpt, argv[1]); //fuse_opt_add_arg(&mountpt, argv[2]);// for debug //fuse_opt_add_arg(&mountpt, argv[3]);// for debug log_file_path= argv[2]; fs_size=atoi(argv[3])*1000000; num_blocks=fs_size/block_size; if(num_blocks < 1000){ free_space =block_size; }else free_space=block_size*4; dictionary= malloc(num_blocks*sizeof(int)); log_fp = fopen (log_file_path,"a+"); if (log_fp == NULL) { printf ("Data file could not be opened\n"); return 1; } initialize_dictionary(); mount=time(NULL); struct fuse_args args = FUSE_ARGS_INIT(mountpt.argc, mountpt.argv); struct fuse_chan *ch; char *mountpoint; int err = -1; if (fuse_parse_cmdline(&args, &mountpoint, NULL, NULL) != -1 && (ch = fuse_mount(mountpoint, &args)) != NULL) { struct fuse_session *se; se = fuse_lowlevel_new(&args, &lfs_ll_oper, sizeof(lfs_ll_oper), NULL); if (se != NULL) { if (fuse_set_signal_handlers(se) != -1) { fuse_session_add_chan(se, ch); /* Block until ctrl+c or fusermount -u */ err = fuse_session_loop(se); fuse_remove_signal_handlers(se); fuse_session_remove_chan(ch); } fuse_session_destroy(se); unmount=time(NULL); write_stats(); } fuse_unmount(mountpoint, ch); } fuse_opt_free_args(&args); free(dictionary); fclose(log_fp); return err ? 1 : 0; }
static int mount_root(int argc, char ** argv) { Dprintf("%s()\n", __FUNCTION__); if (!(root = calloc(1, sizeof(*root)))) return -ENOMEM; // We can't use FUSE_ARGS_INIT() here so assert we are initing the // whole structure static_assert(sizeof(root->args) == sizeof(argc) + sizeof(argv) + sizeof(int)); root->args.argc = argc; root->args.argv = argv; root->args.allocated = 0; if (!(root->fstitch_path = strdup(""))) return -ENOMEM; if (!(root->parents = hash_map_create())) return -ENOMEM; root->cfs = NULL; // set later via fuse_serve_mount_set_root() if (fuse_parse_cmdline(&root->args, &root->mountpoint, NULL, NULL) == -1) { fprintf(stderr, "%s(): fuse_parse_cmdline() failed\n", __FUNCTION__); return -1; } if ((root->channel_fd = fuse_mount(root->mountpoint, &root->args)) == -1) { fprintf(stderr, "%s():%d: fuse_mount(\"%s\") failed\n", __FUNCTION__, __LINE__, root->mountpoint); return -1; } if (!(root->session = fuse_lowlevel_new(&root->args, ops, ops_len, root))) { fprintf(stderr, "%s(): fuse_lowlevel_new() failed\n", __FUNCTION__); return -1; } if (!(root->channel = fuse_kern_chan_new(root->channel_fd))) { fprintf(stderr, "%s(): fuse_kern_chan_new() failed\n", __FUNCTION__); return -1; } fuse_session_add_chan(root->session, root->channel); mounts_insert(root); root->mounted = 1; return 0; }
void sqfs_usage(char *progname, bool fuse_usage) { fprintf(stderr, "%s (c) 2012 Dave Vasilevsky\n\n", PACKAGE_STRING); fprintf(stderr, "Usage: %s [options] ARCHIVE MOUNTPOINT\n", progname ? progname : PACKAGE_NAME); if (fuse_usage) { struct fuse_args args = FUSE_ARGS_INIT(0, NULL); fuse_opt_add_arg(&args, ""); /* progname */ fuse_opt_add_arg(&args, "-ho"); fprintf(stderr, "\n"); fuse_parse_cmdline(&args, NULL, NULL, NULL); } exit(-2); }
void process_arguments(int argc, char **argv) { struct zfs_opts zopts; main_args = (struct fuse_args)FUSE_ARGS_INIT(argc, argv); memset(&zopts, 0, sizeof(zopts)); if (fuse_opt_parse (&main_args, &zopts, main_options, handle_one_argument) != 0) { usage(); exit(EXIT_FAILURE); } if (zopts.config) { set_local_config_path(zopts.config); } set_log_level(&syplogger, zopts.loglevel); // start zfsd on background or foreground int foreground; int rv; char * mountpoint; rv = fuse_parse_cmdline(&main_args, &mountpoint, NULL, &foreground); if (rv == -1) { message(LOG_INFO, FACILITY_ZFSD, "Failed to parse fuse cmdline options.\n"); exit(EXIT_FAILURE); } set_mountpoint(mountpoint); free(mountpoint); #ifndef ENABLE_CLI_CONSOLE //cli use console, don't daemonize rv = fuse_daemonize(foreground); if (rv == -1) { message(LOG_INFO, FACILITY_ZFSD, "Failed to daemonize zfsd.\n"); exit(EXIT_FAILURE); } #endif }
struct fuse *fuse_setup(int argc, char *argv[], const struct fuse_operations *op, size_t op_size, char **mountpoint, int *multithreaded, void *user_data) { struct fuse_args args = FUSE_ARGS_INIT(argc, argv); struct fuse_chan *ch=NULL; struct fuse *fuse; int foreground; int res; res = fuse_parse_cmdline(&args, mountpoint, multithreaded, &foreground); rDebug("res=%i", res); if (res == -1) return NULL; ch = fuse_mount(*mountpoint, &args); fuse = fuse_new(ch, &args, op, op_size, user_data); fuse_opt_free_args(&args); if (fuse == NULL || ch==NULL) goto err_unmount; res = fuse_daemonize(foreground); rDebug("res=%i", res); if (res == -1) goto err_unmount; if (fuse->conf.setsignals) { res = fuse_set_signal_handlers(fuse_get_session(fuse)); rDebug("res=%i", res); if (res == -1) goto err_unmount; } return fuse; err_unmount: fuse_unmount(*mountpoint, ch); if (fuse) fuse_destroy(fuse); free(*mountpoint); return NULL; }
int cdfs_options_output_proc(void *data, const char *arg, int key, struct fuse_args *outargs) { (void) arg; (void) data; switch (key) { case KEY_HELP: usage(outargs->argv[0], stdout); printf( "General options:\n" " -o opt,[opt...] mount options\n" " -h --help print help\n" " -V --version print version\n" " -d -o debug enable debug output (implies -f)\n" " -f foreground operation\n" "\n" "cdfs options:\n" " -o device=DEVICE device to use (like /dev/sr0)\n" " -o cache-directory=DIR directory to store cached files\n" " -o progressfifo=FILE fifo ro write cdrom read progress to\n" " -o logging=NUMBER set loglevel (0=no logging)\n" " -o cachebackend=none[default],sqlite backend to store cache info\n" " -o readaheadpolicy=none/piece/whole policy for readahead\n" " -o hashprogram=md5sum/sha1sum/.. program to compute hash, default md5sum\n" " -o discid path write the discid to, default cache-directory\n" "\n" "FUSE options:\n"); fflush(stdout); dup2(1, 2); fuse_opt_add_arg(outargs, "--help"); fuse_mount(NULL, outargs); fuse_lowlevel_new(outargs, NULL, 0, NULL); exit(0); case KEY_VERSION: printf("xmpfs version %s\n", PACKAGE_VERSION); fflush(stdout); dup2(1, 2); fuse_opt_add_arg(outargs, "--version"); fuse_parse_cmdline(outargs, NULL, NULL, NULL); fuse_lowlevel_new(outargs, NULL, 0, NULL); exit(0); } return 1; }
int main(int argc, char *argv[]) { struct fuse_args args = FUSE_ARGS_INIT(argc, argv); struct fuse_chan *ch; char *mountpoint; int ret = -1; struct lo_data lo = { .debug = 0 }; if (fuse_opt_parse(&args, &lo, lo_opts, NULL) == -1) exit(1); lo.root.next = lo.root.prev = &lo.root; lo.root.fd = open("/", O_PATH); lo.root.nlookup = 2; if (lo.root.fd == -1) err(1, "open(\"/\", O_PATH)"); if (fuse_parse_cmdline(&args, &mountpoint, NULL, NULL) != -1 && (ch = fuse_mount(mountpoint, &args)) != NULL) { struct fuse_session *se; se = fuse_lowlevel_new(&args, &lo_oper, sizeof(lo_oper), &lo); if (se != NULL) { if (fuse_set_signal_handlers(se) != -1) { fuse_session_add_chan(se, ch); ret = fuse_session_loop(se); fuse_remove_signal_handlers(se); fuse_session_remove_chan(ch); } fuse_session_destroy(se); } fuse_unmount(mountpoint, ch); free(mountpoint); } fuse_opt_free_args(&args); while (lo.root.next != &lo.root) lo_free(lo.root.next); return ret ? 1 : 0; }
// get the mountpoint option, by parsing the FUSE command line static int vdev_get_mountpoint( int fuse_argc, char** fuse_argv, char** ret_mountpoint ) { struct fuse_args fargs = FUSE_ARGS_INIT(fuse_argc, fuse_argv); char* mountpoint = NULL; int unused_1; int unused_2; int rc = 0; // parse command-line... rc = fuse_parse_cmdline( &fargs, &mountpoint, &unused_1, &unused_2 ); if( rc < 0 ) { vdev_error("fuse_parse_cmdline rc = %d\n", rc ); fuse_opt_free_args(&fargs); return rc; } else { if( mountpoint != NULL ) { *ret_mountpoint = strdup( mountpoint ); free( mountpoint ); rc = 0; } else { rc = -ENOMEM; } fuse_opt_free_args(&fargs); } return 0; }
// return value: // 0 - discard this arg // 1 - keep this arg for future processing static int mfs_opt_proc_stage2(void *data, const char *arg, int key, struct fuse_args *outargs) { (void)data; switch (key) { case FUSE_OPT_KEY_OPT: return 1; case FUSE_OPT_KEY_NONOPT: return 1; case KEY_HOST: if (mfsopts.masterhost!=NULL) { free(mfsopts.masterhost); } mfsopts.masterhost = strdup(arg+2); return 0; case KEY_PORT: if (mfsopts.masterport!=NULL) { free(mfsopts.masterport); } mfsopts.masterport = strdup(arg+2); return 0; case KEY_BIND: if (mfsopts.bindhost!=NULL) { free(mfsopts.bindhost); } mfsopts.bindhost = strdup(arg+2); return 0; case KEY_PROXY: if (mfsopts.proxyhost!=NULL) { free(mfsopts.proxyhost); } mfsopts.proxyhost = strdup(arg+2); return 0; case KEY_PATH: if (mfsopts.subfolder!=NULL) { free(mfsopts.subfolder); } mfsopts.subfolder = strdup(arg+2); return 0; case KEY_PASSWORDASK: mfsopts.passwordask = 1; return 0; case KEY_META: mfsopts.meta = 1; return 0; case KEY_NOSTDMOUNTOPTIONS: mfsopts.nostdmountoptions = 1; return 0; case KEY_VERSION: fprintf(stderr, "MFS version %s\n",VERSSTR); { struct fuse_args helpargs = FUSE_ARGS_INIT(0, NULL); fuse_opt_add_arg(&helpargs,outargs->argv[0]); fuse_opt_add_arg(&helpargs,"--version"); fuse_parse_cmdline(&helpargs,NULL,NULL,NULL); fuse_mount(NULL,&helpargs); } exit(0); case KEY_HELP: usage(outargs->argv[0]); { struct fuse_args helpargs = FUSE_ARGS_INIT(0, NULL); fuse_opt_add_arg(&helpargs,outargs->argv[0]); fuse_opt_add_arg(&helpargs,"-ho"); fuse_parse_cmdline(&helpargs,NULL,NULL,NULL); fuse_mount("",&helpargs); } exit(1); default: fprintf(stderr, "internal error\n"); abort(); } }
int main(int argc, char **argv) { char line[1024]; char username[sizeof(line)] = "", api_key[sizeof(line)] = "", settings_filename[sizeof(line)] = "", use_snet[sizeof(line)] = "", authurl[MAX_URL_SIZE] = "https://auth.api.rackspacecloud.com/v1.0"; FILE *settings; int foreground = 0; struct fuse_args args = FUSE_ARGS_INIT(argc, argv); char *home = get_home_dir(); snprintf(settings_filename, sizeof(settings_filename), "%s%s.cloudfuse", home, home[strlen(home)] == '/' ? "" : "/"); if ((settings = fopen(settings_filename, "r"))) { while (fgets(line, sizeof(line), settings)) { sscanf(line, " username = %[^\r\n ]", username); sscanf(line, " api_key = %[^\r\n ]", api_key); sscanf(line, " cache_timeout = %d", &cache_timeout); sscanf(line, " authurl = %[^\r\n ]", authurl); sscanf(line, " use_snet = %[^\r\n ]", use_snet); } fclose(settings); } if (!*username || !*api_key) { fprintf(stderr, "Unable to read %s\n", settings_filename); fprintf(stderr, "It should contain:\n\n"); fprintf(stderr, " username=[Mosso username]\n"); fprintf(stderr, " api_key=[Mosso api key]\n\n"); fprintf(stderr, "These entries are optional:\n\n"); fprintf(stderr, " cache_timeout=[seconds for directory caching]\n"); fprintf(stderr, " use_snet=[True to connect to snet]\n"); fprintf(stderr, " authurl=[used for testing]\n"); return 1; } fuse_parse_cmdline(&args, NULL, NULL, &foreground); cloudfs_debug(foreground); if (!cloudfs_connect(username, api_key, authurl, !strncasecmp(use_snet, "true", sizeof(use_snet)))) { fprintf(stderr, "Unable to authenticate.\n"); return 1; } static struct fuse_operations cfs_oper = { .readdir = cfs_readdir, .mkdir = cfs_mkdir, .read = cfs_read, .create = cfs_create, .open = cfs_open, .fgetattr = cfs_fgetattr, .getattr = cfs_getattr, .flush = cfs_flush, .release = cfs_release, .rmdir = cfs_rmdir, .ftruncate = cfs_ftruncate, .truncate = cfs_truncate, .write = cfs_write, .unlink = cfs_unlink, .fsync = cfs_fsync, .statfs = cfs_statfs, .chmod = cfs_chmod, .chown = cfs_chown, }; pthread_mutex_init(&dmut, NULL); signal(SIGPIPE, SIG_IGN); return fuse_main(argc, argv, &cfs_oper, NULL); }
struct fuse_session *cuse_lowlevel_setup(int argc, char *argv[], const struct cuse_info *ci, const struct cuse_lowlevel_ops *clop, int *multithreaded, void *userdata) { const char *devname = "/dev/cuse"; static const struct fuse_opt kill_subtype_opts[] = { FUSE_OPT_KEY("subtype=", FUSE_OPT_KEY_DISCARD), FUSE_OPT_END }; struct fuse_args args = FUSE_ARGS_INIT(argc, argv); struct fuse_session *se; struct fuse_chan *ch; int fd; int foreground; int res; res = fuse_parse_cmdline(&args, NULL, multithreaded, &foreground); if (res == -1) goto err_args; res = fuse_opt_parse(&args, NULL, kill_subtype_opts, NULL); if (res == -1) goto err_args; /* * Make sure file descriptors 0, 1 and 2 are open, otherwise chaos * would ensue. */ do { fd = open("/dev/null", O_RDWR); if (fd > 2) close(fd); } while (fd >= 0 && fd <= 2); se = cuse_lowlevel_new(&args, ci, clop, userdata); fuse_opt_free_args(&args); if (se == NULL) goto err_args; fd = open(devname, O_RDWR); if (fd == -1) { if (errno == ENODEV || errno == ENOENT) fprintf(stderr, "cuse: device not found, try 'modprobe cuse' first\n"); else fprintf(stderr, "cuse: failed to open %s: %s\n", devname, strerror(errno)); goto err_se; } ch = fuse_kern_chan_new(fd); if (!ch) { close(fd); goto err_se; } fuse_session_add_chan(se, ch); res = fuse_set_signal_handlers(se); if (res == -1) goto err_se; res = fuse_daemonize(foreground); if (res == -1) goto err_sig; return se; err_sig: fuse_remove_signal_handlers(se); err_se: fuse_session_destroy(se); err_args: fuse_opt_free_args(&args); return NULL; }
void get_mount_point (int argc, char **argv) { struct fuse_args argst = FUSE_ARGS_INIT (argc, argv); fuse_parse_cmdline (&argst, &mount_point, NULL, NULL); }
int main(int argc, char *argv[]) { int res; int mt,fg; int i; char *mountpoint; struct fuse_args args = FUSE_ARGS_INIT(argc, argv); struct fuse_args defaultargs = FUSE_ARGS_INIT(0, NULL); #if defined(SIGPIPE) && defined(SIG_IGN) signal(SIGPIPE,SIG_IGN); #endif strerr_init(); mycrc32_init(); setenv("FUSE_THREAD_STACK","524288",0); // works good with 262144 but not 131072, so for safety we will use 524288 mfsopts.masterhost = NULL; mfsopts.masterport = NULL; mfsopts.bindhost = NULL; mfsopts.proxyhost = NULL; mfsopts.subfolder = NULL; mfsopts.password = NULL; mfsopts.md5pass = NULL; mfsopts.preferedlabels = NULL; mfsopts.nofile = 0; mfsopts.nice = -19; #ifdef MFS_USE_MEMLOCK mfsopts.memlock = 0; #endif #ifdef MFS_USE_MALLOPT mfsopts.limitarenas = 2; #endif #if defined(__linux__) && defined(OOM_DISABLE) mfsopts.oomdisable = 1; #endif mfsopts.nostdmountoptions = 0; mfsopts.meta = 0; mfsopts.flattrash = 0; mfsopts.debug = 0; mfsopts.delayedinit = 0; #ifdef __linux__ mfsopts.mkdircopysgid = 1; #else mfsopts.mkdircopysgid = 0; #endif mfsopts.sugidclearmodestr = NULL; mfsopts.donotrememberpassword = 0; // mfsopts.xattraclsupport = 0; mfsopts.cachefiles = 0; mfsopts.noxattrs = 0; mfsopts.noposixlocks = 0; mfsopts.nobsdlocks = 0; mfsopts.cachemode = NULL; mfsopts.writecachesize = 0; mfsopts.readaheadsize = 0; mfsopts.readaheadleng = 0; mfsopts.readaheadtrigger = 0; mfsopts.ioretries = 30; mfsopts.timeout = 0; mfsopts.logretry = 5; mfsopts.passwordask = 0; mfsopts.attrcacheto = 1.0; mfsopts.xattrcacheto = 30.0; mfsopts.entrycacheto = 0.0; mfsopts.direntrycacheto = 1.0; mfsopts.negentrycacheto = 0.0; mfsopts.groupscacheto = 300.0; mfsopts.fsyncbeforeclose = 0; mfsopts.fsyncmintime = 0.0; custom_cfg = 0; // dump_args("input_args",&args); if (args.argc>1) { uint32_t hostlen,portlen,colons; char *c,*portbegin; int optpos; // skip options in format '-o XXXX' and '-oXXXX' optpos = 1; while (optpos<args.argc) { c = args.argv[optpos]; if (c[0]=='-' && c[1]=='o') { if (c[2]) { optpos++; } else { optpos+=2; } } else { break; } } if (optpos<args.argc) { // check if next arg matches to HOST[:PORT]:[PATH] c = args.argv[optpos]; colons = 0; for (i=0 ; c[i] ; i++) { if (c[i]==':') { colons++; } } if (colons>0) { hostlen = 0; portlen = 0; portbegin = NULL; while (((*c)>='a' && (*c)<='z') || ((*c)>='A' && (*c)<='Z') || ((*c)>='0' && (*c)<='9') || (*c)=='-' || (*c)=='.') { // DNS chars c++; hostlen++; } if (hostlen>0) { if ((*c)==':' && colons>1) { c++; portbegin = c; while ((*c)>='0' && ((*c)<='9')) { c++; portlen++; } } if ((*c)==':') { // match found c++; if (*c) { mfsopts.subfolder = strdup(c); } mfsopts.masterhost = malloc(hostlen+1); memcpy(mfsopts.masterhost,args.argv[optpos],hostlen); mfsopts.masterhost[hostlen]=0; if (portbegin!=NULL && portlen>0) { mfsopts.masterport = malloc(portlen+1); memcpy(mfsopts.masterport,portbegin,portlen); mfsopts.masterport[portlen]=0; } for (i=optpos+1 ; i<args.argc ; i++) { args.argv[i-1] = args.argv[i]; } args.argc--; } } } } } // dump_args("after_first_filter",&args); if (fuse_opt_parse(&args, &defaultargs, mfs_opts_stage1, mfs_opt_proc_stage1)<0) { exit(1); } if (custom_cfg==0) { int cfgfd; char *cfgfile; cfgfile=strdup(ETC_PATH "/mfs/mfsmount.cfg"); if ((cfgfd = open(cfgfile,O_RDONLY))<0 && errno==ENOENT) { free(cfgfile); cfgfile=strdup(ETC_PATH "/mfsmount.cfg"); if ((cfgfd = open(cfgfile,O_RDONLY))>=0) { fprintf(stderr,"default sysconf path has changed - please move mfsmount.cfg from "ETC_PATH"/ to "ETC_PATH"/mfs/\n"); } } if (cfgfd>=0) { close(cfgfd); } mfs_opt_parse_cfg_file(cfgfile,1,&defaultargs); free(cfgfile); } // dump_args("parsed_defaults",&defaultargs); // dump_args("changed_args",&args); for (i=0 ; i<defaultargs.argc ; i++) { fuse_opt_add_arg(&args,defaultargs.argv[i]); } // dump_args("combined_args",&args); if (fuse_opt_parse(&args, &mfsopts, mfs_opts_stage2, mfs_opt_proc_stage2)<0) { exit(1); } // dump_args("combined_args_after_parse",&args); if (mfsopts.cachemode!=NULL && mfsopts.cachefiles) { fprintf(stderr,"mfscachemode and mfscachefiles options are exclusive - use only mfscachemode\nsee: %s -h for help\n",argv[0]); return 1; } if (mfsopts.cachemode==NULL) { #if defined(__FreeBSD__) || defined(__APPLE__) mfsopts.keepcache = 3; #else mfsopts.keepcache = (mfsopts.cachefiles)?1:0; #endif } else if (strcasecmp(mfsopts.cachemode,"AUTO")==0) { mfsopts.keepcache=0; } else if (strcasecmp(mfsopts.cachemode,"YES")==0 || strcasecmp(mfsopts.cachemode,"ALWAYS")==0) { mfsopts.keepcache=1; } else if (strcasecmp(mfsopts.cachemode,"NO")==0 || strcasecmp(mfsopts.cachemode,"NONE")==0 || strcasecmp(mfsopts.cachemode,"NEVER")==0) { mfsopts.keepcache=2; } else if (strcasecmp(mfsopts.cachemode,"DIRECT")==0) { mfsopts.keepcache=3; } else { fprintf(stderr,"unrecognized cachemode option\nsee: %s -h for help\n",argv[0]); return 1; } if (mfsopts.sugidclearmodestr==NULL) { #if defined(DEFAULT_SUGID_CLEAR_MODE_EXT) mfsopts.sugidclearmode = SUGID_CLEAR_MODE_EXT; #elif defined(DEFAULT_SUGID_CLEAR_MODE_BSD) mfsopts.sugidclearmode = SUGID_CLEAR_MODE_BSD; #elif defined(DEFAULT_SUGID_CLEAR_MODE_OSX) mfsopts.sugidclearmode = SUGID_CLEAR_MODE_OSX; #else mfsopts.sugidclearmode = SUGID_CLEAR_MODE_NEVER; #endif } else if (strcasecmp(mfsopts.sugidclearmodestr,"NEVER")==0) { mfsopts.sugidclearmode = SUGID_CLEAR_MODE_NEVER; } else if (strcasecmp(mfsopts.sugidclearmodestr,"ALWAYS")==0) { mfsopts.sugidclearmode = SUGID_CLEAR_MODE_ALWAYS; } else if (strcasecmp(mfsopts.sugidclearmodestr,"OSX")==0) { mfsopts.sugidclearmode = SUGID_CLEAR_MODE_OSX; } else if (strcasecmp(mfsopts.sugidclearmodestr,"BSD")==0) { mfsopts.sugidclearmode = SUGID_CLEAR_MODE_BSD; } else if (strcasecmp(mfsopts.sugidclearmodestr,"EXT")==0) { mfsopts.sugidclearmode = SUGID_CLEAR_MODE_EXT; } else if (strcasecmp(mfsopts.sugidclearmodestr,"XFS")==0) { mfsopts.sugidclearmode = SUGID_CLEAR_MODE_XFS; } else { fprintf(stderr,"unrecognized sugidclearmode option\nsee: %s -h for help\n",argv[0]); return 1; } if (mfsopts.masterhost==NULL) { mfsopts.masterhost = strdup(DEFAULT_MASTERNAME); } if (mfsopts.masterport==NULL) { mfsopts.masterport = strdup(DEFAULT_MASTER_CLIENT_PORT); } if (mfsopts.proxyhost==NULL) { mfsopts.proxyhost = strdup("127.0.0.1"); } if (mfsopts.subfolder==NULL) { mfsopts.subfolder = strdup("/"); } if (mfsopts.nofile==0) { mfsopts.nofile=100000; } if (mfsopts.writecachesize==0) { mfsopts.writecachesize=256; } if (mfsopts.writecachesize<16) { fprintf(stderr,"write cache size too low (%u MiB) - increased to 16 MiB\n",mfsopts.writecachesize); mfsopts.writecachesize=16; } if (mfsopts.writecachesize>2048) { fprintf(stderr,"write cache size too big (%u MiB) - decresed to 2048 MiB\n",mfsopts.writecachesize); mfsopts.writecachesize=2048; } if (mfsopts.readaheadsize==0) { mfsopts.readaheadsize=256; } if (mfsopts.readaheadsize<16) { fprintf(stderr,"read ahead size too low (%u MiB) - increased to 16 MiB\n",mfsopts.readaheadsize); mfsopts.readaheadsize=16; } if (mfsopts.readaheadsize>2048) { fprintf(stderr,"read ahead size too big (%u MiB) - decresed to 2048 MiB\n",mfsopts.readaheadsize); mfsopts.readaheadsize=2048; } if (mfsopts.readaheadleng==0) { mfsopts.readaheadleng=0x100000; } if (mfsopts.readaheadleng<0x20000) { fprintf(stderr,"read ahead length too low (%u B) - increased to 128 KiB\n",mfsopts.readaheadleng); mfsopts.readaheadleng=0x20000; } if (mfsopts.readaheadleng>0x200000) { fprintf(stderr,"read ahead length too big (%u B) - decresed to 2 MiB\n",mfsopts.readaheadleng); mfsopts.readaheadleng=0x200000; } if (mfsopts.readaheadtrigger==0) { mfsopts.readaheadtrigger=mfsopts.readaheadleng*10; } if (mfsopts.nostdmountoptions==0) { fuse_opt_add_arg(&args, "-o" DEFAULT_OPTIONS); } if (mfsopts.fsyncbeforeclose) { mfsopts.fsyncmintime=0.0; } if (csorder_init(mfsopts.preferedlabels)<0) { fprintf(stderr,"error parsing preferred labels expression\nsee: %s -h for help\n",argv[0]); return 1; } make_fsname(&args); remove_mfsmount_magic(&args); // dump_args("combined_args_before_fuse_parse_cmdline",&args); if (fuse_parse_cmdline(&args,&mountpoint,&mt,&fg)<0) { fprintf(stderr,"see: %s -h for help\n",argv[0]); return 1; } if (!mountpoint) { if (defaultmountpoint) { mountpoint = defaultmountpoint; } else { fprintf(stderr,"no mount point\nsee: %s -h for help\n",argv[0]); return 1; } } res = mainloop(&args,mountpoint,mt,fg); fuse_opt_free_args(&defaultargs); fuse_opt_free_args(&args); free(mfsopts.masterhost); free(mfsopts.masterport); if (mfsopts.bindhost) { free(mfsopts.bindhost); } if (mfsopts.proxyhost) { free(mfsopts.proxyhost); } free(mfsopts.subfolder); if (defaultmountpoint) { free(defaultmountpoint); } stats_term(); strerr_term(); return res; }
int single_drive_main(struct fuse_args *args, struct ltfs_fuse_data *priv) { int ret; char *index_rules_utf8; char fsname[strlen(priv->devname) + 16]; char *invalid_start; #ifdef __APPLE__ char *opt_volname = NULL; #endif char *mountpoint = NULL; struct fuse_args tmpa=FUSE_ARGS_INIT(0, NULL); int i; bool is_worm; #ifdef HP_mingw_BUILD (void) i; (void) tmpa; (void) mountpoint; #endif /* HP_mingw_BUILD */ /* Setup signal handler to terminate cleanly */ ret = ltfs_set_signal_handlers(); if (ret < 0) { ltfsmsg(LTFS_ERR, "10013E"); return 1; } /* Validate rollback_mount option */ if (priv->rollback_str) { errno = 0; priv->rollback_gen = strtoul(priv->rollback_str, &invalid_start, 0); if( (*invalid_start != '\0') || priv->rollback_gen == 0 ) { ltfsmsg(LTFS_ERR, "14091E", priv->rollback_str); return 1; } } /* * HP change: HP drives don't support the append only mode functionality. * All the options and messages related to that are disabled. Code remains * but is non-functional. */ /* Validate append_only_mode */ if (priv->str_append_only_mode) { if (strcasecmp(priv->str_append_only_mode, "on") == 0) priv->append_only_mode = 1; else if (strcasecmp(priv->str_append_only_mode, "off") == 0) priv->append_only_mode = 0; else { ltfsmsg(LTFS_ERR, "14115E", priv->str_append_only_mode); return 1; } } else { /* The append_only_mode will always be 0 in our environment. */ priv->append_only_mode = 0; } if (priv->eject == 0 && priv->append_only_mode != 0) { /* Append only mode need to eject a cartridge at unmount to clear the mode on drive setting */ /* To avoid cartridge ejection at unmount, disable append only mode at the moount with noeject option */ priv->append_only_mode = 0; /*ltfsmsg(LTFS_INFO, "14095I");*/ } /* If the local inode space is big enough, have FUSE pass through our UIDs as inode * numbers instead of generating its own. */ if (sizeof(ino_t) >= 8) { ret = fuse_opt_add_arg(args, "-ouse_ino"); if (ret < 0) { /* Could not enable FUSE option */ ltfsmsg(LTFS_ERR, "14001E", "use_ino", ret); return 1; } } /* Set file system name to "ltfs:devname" in case FUSE doesn't pick it up */ snprintf(fsname, sizeof(fsname), "-ofsname=ltfs:%s", priv->devname); ret = fuse_opt_add_arg(args, fsname); if (ret < 0) { /* Could not enable FUSE option */ ltfsmsg(LTFS_ERR, "14001E", "fsname", ret); return 1; } /* Allocate the LTFS volume structure */ if (ltfs_volume_alloc("ltfs", &priv->data) < 0) { /* Could not allocate LTFS volume structure */ ltfsmsg(LTFS_ERR, "14011E"); return 1; } ltfs_use_atime(priv->atime, priv->data); /* * OSR * * In our MinGW environment, we mount the device on access. This * processing is deferred until ltfs_fuse_mount * */ #ifndef HP_mingw_BUILD if (ltfs_device_open(priv->devname, priv->driver_plugin.ops, priv->data) < 0) { /* Could not open device */ ltfsmsg(LTFS_ERR, "10004E", priv->devname); ltfs_volume_free(&priv->data); return 1; } if (priv->release_device) { ltfs_release_medium(priv->data); ltfs_device_close(priv->data); ltfs_volume_free(&priv->data); return 0; } /* Parse backend options */ if (ltfs_parse_tape_backend_opts(args, priv->data)) { /* Backend option parsing failed */ ltfsmsg(LTFS_ERR, "14012E"); ltfs_volume_free(&priv->data); return 1; } if (priv->kmi_backend_name) { if (kmi_init(&priv->kmi_plugin, priv->data) < 0) { /* Encryption function disabled. */ ltfsmsg(LTFS_ERR, "14089E"); ltfs_volume_free(&priv->data); return 1; } if (ltfs_parse_kmi_backend_opts(args, priv->data)) { /* Backend option parsing failed */ ltfsmsg(LTFS_ERR, "14090E"); ltfs_volume_free(&priv->data); return 1; } if (tape_clear_key(priv->data->device, priv->data->kmi_handle) < 0) return 1; } /* Setup tape drive */ priv->data->append_only_mode = (bool)priv->append_only_mode; if (ltfs_setup_device(priv->data)) { ltfsmsg(LTFS_ERR, "14075E"); ltfs_volume_free(&priv->data); return 1; } /* Check EOD validation is skipped or not */ if (priv->skip_eod_check) { ltfsmsg(LTFS_INFO, "14076I"); ltfsmsg(LTFS_INFO, "14077I"); ltfs_set_eod_check(! priv->skip_eod_check, priv->data); } /* Validate symbolic link type */ priv->data->livelink = false; if (priv->symlink_str) { if (strcasecmp(priv->symlink_str, "live") == 0) priv->data->livelink = true; else if (strcasecmp(priv->symlink_str, "posix") == 0) priv->data->livelink = false; else { ltfsmsg(LTFS_ERR, "14093E", priv->symlink_str); return 1; } ltfsmsg(LTFS_INFO, "14092I", priv->symlink_str); } /* Mount the volume */ ltfs_set_traverse_mode(TRAVERSE_BACKWARD, priv->data); if (ltfs_mount(false, false, false, false, priv->rollback_gen, priv->data) < 0) { ltfsmsg(LTFS_ERR, "14013E"); ltfs_volume_free(&priv->data); return 1; } ret = tape_get_worm_status(priv->data->device, &is_worm); if (ret != 0 || is_worm) { ltfsmsg(LTFS_ERR, "14116E", ret); ltfs_volume_free(&priv->data); return 1; } /* Set up index criteria */ if (priv->index_rules) { ret = pathname_format(priv->index_rules, &index_rules_utf8, false, false); if (ret < 0) { /* Could not format data placement rules. */ ltfsmsg(LTFS_ERR, "14016E", ret); ltfs_volume_free(&priv->data); return 1; } ret = ltfs_override_policy(index_rules_utf8, false, priv->data); free(index_rules_utf8); if (ret == -LTFS_POLICY_IMMUTABLE) { /* Volume doesn't allow override. Ignoring user-specified criteria. */ ltfsmsg(LTFS_WARN, "14015W"); } else if (ret < 0) { /* Could not parse data placement rules */ ltfsmsg(LTFS_ERR, "14017E", ret); ltfs_volume_free(&priv->data); return 1; } } /* Configure I/O scheduler cache */ ltfs_set_scheduler_cache(priv->min_pool_size, priv->max_pool_size, priv->data); /* mount read-only if underlying medium is write-protected */ ret = ltfs_get_tape_readonly(priv->data); if (ret < 0 && ret != -LTFS_WRITE_PROTECT && ret != -LTFS_WRITE_ERROR && ret != -LTFS_NO_SPACE && ret != -LTFS_LESS_SPACE) { /* No other errors are expected. */ /* Could not get read-only status of medium */ ltfsmsg(LTFS_ERR, "14018E"); ltfs_volume_free(&priv->data); return 1; } else if (ret == -LTFS_WRITE_PROTECT || ret == -LTFS_WRITE_ERROR || ret == -LTFS_NO_SPACE || ret == -LTFS_LESS_SPACE || priv->rollback_gen != 0) { if (ret == -LTFS_WRITE_PROTECT || ret == -LTFS_WRITE_ERROR || ret == -LTFS_NO_SPACE) { ret = ltfs_get_partition_readonly(ltfs_ip_id(priv->data), priv->data); if (ret == -LTFS_WRITE_PROTECT || ret == -LTFS_WRITE_ERROR) { if (priv->data->rollback_mount) { /* The cartridge will be mounted as read-only if a valid generation number is supplied with * rollback_mount */ ltfsmsg(LTFS_INFO, "14072I", priv->rollback_gen); } else { if (ltfs_get_tape_logically_readonly(priv->data) == -LTFS_LOGICAL_WRITE_PROTECT) { /* The tape is logically write protected i.e. incompatible medium*/ ltfsmsg(LTFS_INFO, "14118I"); }else { /* The tape is really write protected */ ltfsmsg(LTFS_INFO, "14019I"); } } } else if (ret == -LTFS_NO_SPACE) { /* The index partition is in early warning zone. To be mounted read-only */ ltfsmsg(LTFS_INFO, "14073I"); } else { /* 0 or -LTFS_LESS_SPACE */ /* The data partition may be in early warning zone. To be mounted read-only */ ltfsmsg(LTFS_INFO, "14074I"); } } else if (ret == -LTFS_LESS_SPACE) ltfsmsg(LTFS_INFO, "14071I"); /*else ltfsmsg(LTFS_INFO, "14072I", priv->rollback_gen);*/ ret = fuse_opt_add_arg(args, "-oro"); if (ret < 0) { /* Could not set FUSE option */ ltfsmsg(LTFS_ERR, "14001E", "ro", ret); ltfs_volume_free(&priv->data); return 1; } } #else /* OSR */ /* Save the arguments so we can parse them later at the init * callback */ priv->args = args; #endif /* HP_mingw_BUILD */ /* Cleanup signal handler */ ret = ltfs_unset_signal_handlers(); if (ret < 0) { ltfsmsg(LTFS_ERR, "10014E"); return 1; } #ifdef __APPLE__ /* * Set the volume name (logical) when LTFS runs on OS X */ if (priv->data->index->volume_name) { ret = asprintf(&opt_volname, "-ovolname=%s(%s)", priv->data->index->volume_name, "ltfs"); if (ret < 0) { /* Memory allocation failed */ ltfsmsg(LTFS_ERR, "10001E", "option string for volume name"); ltfs_volume_free(&priv->data); return 1; } ret = fuse_opt_add_arg(args, opt_volname); if (ret < 0) { /* Could not set FUSE option */ ltfsmsg(LTFS_ERR, "14001E", "volname", ret); ltfs_volume_free(&priv->data); free(opt_volname); return 1; } } #endif /* __APPLE__ */ /* Not supported on Windows. TODO: Verify this again.*/ #ifndef HP_mingw_BUILD /* Get and store mount point */ for ( i=0; i<args->argc; i++) { fuse_opt_add_arg(&tmpa, args->argv[i]); } ret = fuse_parse_cmdline( &tmpa, &mountpoint, NULL, NULL); fuse_opt_free_args(&tmpa); if (ret < 0 || mountpoint == NULL) { ltfsmsg(LTFS_ERR, "14094E", ret); ltfs_volume_free(&priv->data); return 1; } priv->data->mountpoint = mountpoint; priv->data->mountpoint_len = strlen(mountpoint); #endif /* HP_mingw_BUILD */ /* now we can safely call FUSE */ ltfsmsg(LTFS_INFO, "14111I"); ltfsmsg(LTFS_INFO, "14112I"); ltfsmsg(LTFS_INFO, "14113I"); ret = fuse_main(args->argc, args->argv, <fs_ops, priv); /* Setup signal handler again to terminate cleanly */ ret = ltfs_set_signal_handlers(); if (ret < 0) { ltfsmsg(LTFS_ERR, "10013E"); return 1; } /* * OSR * * In our MinGW environment, we stay running after the device is * dismounted/ejected. This processing is deferred until * ltfs_fuse_unmount * */ #ifndef HP_mingw_BUILD if (priv->eject) ltfs_eject_tape(priv->data); ltfs_device_close(priv->data); #endif /* HP_mingw_BUILD */ /* close the volume */ #ifdef __APPLE__ if (opt_volname) free(opt_volname); #endif /* __APPLE__ */ ltfs_volume_free(&priv->data); ltfs_unset_signal_handlers(); return ret; }
// run fskit with fuse int fskit_fuse_main( struct fskit_fuse_state* state, int argc, char** argv ) { int rc = 0; // set up FUSE struct fuse_args args = FUSE_ARGS_INIT(argc, argv); struct fuse_chan* ch = NULL; struct fuse* fs = NULL; int multithreaded = 1; int foreground = 0; char* mountpoint = NULL; // parse command-line... rc = fuse_parse_cmdline( &args, &mountpoint, &multithreaded, &foreground ); if( rc < 0 ) { fskit_error("fuse_parse_cmdline rc = %d\n", rc ); fuse_opt_free_args(&args); return rc; } if( mountpoint == NULL ) { fskit_error("%s", "No mountpoint given\n"); fuse_opt_free_args(&args); return rc; } state->mountpoint = strdup( mountpoint ); // mount ch = fuse_mount( mountpoint, &args ); if( ch == NULL ) { rc = -errno; fskit_error("fuse_mount failed, errno = %d\n", rc ); fuse_opt_free_args(&args); if( rc == 0 ) { rc = -EPERM; } return rc; } // create the filesystem fs = fuse_new( ch, &args, &state->ops, sizeof(state->ops), state ); fuse_opt_free_args(&args); if( fs == NULL ) { // failed rc = -errno; fskit_error("fuse_new failed, errno = %d\n", rc ); fuse_unmount( mountpoint, ch ); if( rc == 0 ) { rc = -EPERM; } return rc; } // daemonize if running in the background fskit_debug("FUSE daemonize: foreground=%d\n", foreground); rc = fuse_daemonize( foreground ); if( rc != 0 ) { // failed fskit_error("fuse_daemonize(%d) rc = %d\n", foreground, rc ); fuse_unmount( mountpoint, ch ); fuse_destroy( fs ); return rc; } // set up FUSE signal handlers rc = fuse_set_signal_handlers( fuse_get_session(fs) ); if( rc < 0 ) { // failed fskit_error("fuse_set_signal_handlers rc = %d\n", rc ); fuse_unmount( mountpoint, ch ); fuse_destroy( fs ); return rc; } // if we have a post-mount callback, call it now, since FUSE is ready to receive requests if( state->postmount != NULL ) { rc = (*state->postmount)( state, state->postmount_cls ); if( rc != 0 ) { fskit_error("fskit postmount callback rc = %d\n", rc ); fuse_unmount( mountpoint, ch ); fuse_destroy( fs ); return rc; } } // run the filesystem--start processing requests fskit_debug("%s", "FUSE main loop entered\n"); if( multithreaded ) { rc = fuse_loop_mt( fs ); } else { rc = fuse_loop( fs ); } fskit_debug("%s", "FUSE main loop finished\n"); fuse_teardown( fs, mountpoint ); return rc; }
int main(int argc, char *argv[]) { struct fuse_args args; sqfs_opts opts; char *mountpoint = NULL; int mt, fg; int err; sqfs_ll *ll; struct fuse_lowlevel_ops sqfs_ll_ops; memset(&sqfs_ll_ops, 0, sizeof(sqfs_ll_ops)); sqfs_ll_ops.getattr = sqfs_ll_op_getattr; sqfs_ll_ops.opendir = sqfs_ll_op_opendir; sqfs_ll_ops.releasedir = sqfs_ll_op_releasedir; sqfs_ll_ops.readdir = sqfs_ll_op_readdir; sqfs_ll_ops.lookup = sqfs_ll_op_lookup; sqfs_ll_ops.open = sqfs_ll_op_open; sqfs_ll_ops.release = sqfs_ll_op_release; sqfs_ll_ops.read = sqfs_ll_op_read; sqfs_ll_ops.readlink = sqfs_ll_op_readlink; sqfs_ll_ops.listxattr = sqfs_ll_op_listxattr; sqfs_ll_ops.getxattr = sqfs_ll_op_getxattr; sqfs_ll_ops.forget = sqfs_ll_op_forget; /* PARSE ARGS */ args.argc = argc; args.argv = argv; args.allocated = 0; opts.progname = argv[0]; opts.image = NULL; opts.mountpoint = 0; if (fuse_opt_parse(&args, &opts, NULL, sqfs_opt_proc) == -1) sqfs_usage(argv[0], true); if (fuse_parse_cmdline(&args, &mountpoint, &mt, &fg) == -1) sqfs_usage(argv[0], true); if (mountpoint == NULL) sqfs_usage(argv[0], true); /* OPEN FS */ err = !(ll = sqfs_ll_open(opts.image)); /* STARTUP FUSE */ if (!err) { sqfs_ll_chan ch; err = -1; if (sqfs_ll_mount(&ch, mountpoint, &args) == SQFS_OK) { struct fuse_session *se = fuse_lowlevel_new(&args, &sqfs_ll_ops, sizeof(sqfs_ll_ops), ll); if (se != NULL) { if (sqfs_ll_daemonize(fg) != -1) { if (fuse_set_signal_handlers(se) != -1) { fuse_session_add_chan(se, ch.ch); /* FIXME: multithreading */ err = fuse_session_loop(se); fuse_remove_signal_handlers(se); #if HAVE_DECL_FUSE_SESSION_REMOVE_CHAN fuse_session_remove_chan(ch.ch); #endif } } fuse_session_destroy(se); } sqfs_ll_destroy(ll); sqfs_ll_unmount(&ch, mountpoint); } } fuse_opt_free_args(&args); free(ll); free(mountpoint); return -err; }
/* * Class: org_catacombae_jfuse_FUSE * Method: mountNative26 * Signature: (Lorg/catacombae/jfuse/FUSE26FileSystem;Ljava/lang/String;[Ljava/lang/String;Lorg/catacombae/jfuse/FUSE26Capabilities;Lorg/catacombae/jfuse/MacFUSE20Capabilities;)Z */ JNIEXPORT jboolean JNICALL Java_org_catacombae_jfuse_FUSE_mountNative26( JNIEnv *env, jclass cls, jobject fileSystem, jstring mountPoint, jobjectArray optionStrings, jobject fuseCapabilities, jobject macFuseCapabilities) { #define _FNAME_ "Java_org_catacombae_jfuse_FUSE_mountNative26" CSLogTraceEnter(_FNAME_ "(%p, %p, %p, %p, %p, %p, %p)", env, cls, fileSystem, mountPoint, optionStrings, fuseCapabilities, macFuseCapabilities); jboolean res = JNI_FALSE; jFUSEContext *context = new jFUSEContext(env, fileSystem); if(!fillFUSE26Operations(env, fuseCapabilities, &jfuse_operations)) CSPanicWithMessage("Could not fill FUSE 2.6 operations!"); else CSLogDebug("Filled FUSE 2.6 operations."); if(jfuse_operations.init != NULL) { context->setInitEnabled(true); } #if defined(__APPLE__) || defined(__DARWIN__) #if (__FreeBSD__ >= 10) if(macFuseCapabilities != NULL) { if(!fillMacFUSE20Operations(env, macFuseCapabilities, &jfuse_operations)) CSPanicWithMessage("Could not fill MacFUSE 2.0 operations!"); else { CSLogDebug("Filled MacFUSE 2.0 operations."); if(jfuse_operations.getxtimes != NULL || jfuse_operations.setbkuptime != NULL || jfuse_operations.setcrtime != NULL || jfuse_operations.setchgtime != NULL) { CSLogDebug("Requesting enabling of xtimes."); context->setXtimesEnabled(true); if(jfuse_operations.init == NULL) { CSLogDebug("Adding operation 'init' to fuse_operations for " "support enabling of xtimes..."); jfuse_operations.init = jfuse_init; } } } } else CSLogDebug("No MacFUSE 2.0 operations to fill."); #endif /*__FreeBSD__ >= 10 */ #endif /* defined(__APPLE__) || defined(__DARWIN__) */ /* Read mountpoint. */ jboolean isCopy; const char *utf8MountPoint = env->GetStringUTFChars(mountPoint, &isCopy); /* Read options. */ struct fuse_args args = FUSE_ARGS_INIT(0, NULL); if(fuse_opt_add_arg(&args, utf8MountPoint) != 0) CSPanicWithMessage("fuse_opt_add_arg failed unexpectedly."); jsize optionStringsLength = env->GetArrayLength(optionStrings); CSLogDebug("Reading option strings (length=%ld)...", (long)optionStringsLength); for(int i = 0; i < optionStringsLength; ++i) { jstring cur = (jstring)env->GetObjectArrayElement(optionStrings, i); const char *utfChars = env->GetStringUTFChars(cur, NULL); CSLogDebug(" Adding option %d: \"%s\"", i, utfChars); int addArgRetval = fuse_opt_add_arg(&args, utfChars); if(addArgRetval != 0) CSPanicWithMessage("fuse_opt_add_arg failed unexpectedly with " "retval=%d, errno: %d (%s)", addArgRetval, errno, strerror(errno)); env->ReleaseStringUTFChars(cur, utfChars); env->DeleteLocalRef(cur); } if(fuse_parse_cmdline(&args, NULL, NULL, NULL) != 0) CSLogError("fuse_parse_cmdline didn't return 0."); else { /* * FUSE regular mount procedure: * * Init: * - fuse_mount: * (char *mountpoint, struct fuse_args *args)-> (struct fuse_chan*) * - fuse_new: * (struct fuse_chan *ch, struct fuse_args *args, * struct fuse_operations *op, size_t op_size, void *user_data) * ->(struct fuse*) * Running: * - fuse_loop / fuse_loop_mt: * (struct fuse*)->(int) * Main loop, running until file system is unmounted. * Cleanup: * - fuse_unmount: * (char *mountpoint, struct fuse_chan *ch)->(void) * - fuse_destroy: * (struct fuse* f)->(void) * * * FUSE lowlevel mount procedure: * * Init: * - fuse_mount: * (char *mountpoint, struct fuse_args *args)->(struct fuse_chan*) * - fuse_lowlevel_new: * (struct fuse_args *args, struct fuse_lowlevel_ops *op, * size_t op_size, void *userdata) -> (struct fuse_session*) * - fuse_session_add_chan: * (struct fuse_session *se, struct fuse_chan *ch)->(void) * Running: * - fuse_session_loop / fuse_session_loop_mt: * (struct fuse_session *se)->(int) * Cleanup: * - fuse_session_remove_chan: * (struct fuse_chan *ch)->(void) * - fuse_session_destroy: * (struct fuse_session *se)->(void) * - fuse_unmount: * (char *mountpoint, struct fuse_chan *ch)->(void) */ fuse_chan *chan = NULL; fuse *fh = NULL; CSLogDebug("Invoking fuse_mount..."); chan = fuse_mount(utf8MountPoint, &args); CSLogDebug(" done. result=%p", chan); if(chan != NULL) { CSLogDebug("Invoking fuse_new..."); fh = fuse_new(chan, &args, &jfuse_operations, sizeof (jfuse_operations), context); CSLogDebug(" done. result=%p", fh); if(fh != NULL) { #if defined(__NetBSD__) int sighandler_res = 0; #else int sighandler_res = fuse_set_signal_handlers(fuse_get_session(fh)); #endif /* defined(__NetBSD__) */ if(sighandler_res == 0) { CSLogDebug("Invoking fuse_loop..."); int fuseLoopRetval = fuse_loop(fh); CSLogDebug(" done. result=%d", fuseLoopRetval); if(fuseLoopRetval != 0) CSLogError("fuse_loop exited with a non-zero value: %d " "(errno is %d (%s)", fuseLoopRetval, errno, strerror(errno)); else res = JNI_TRUE; #if !defined(__NetBSD__) fuse_remove_signal_handlers(fuse_get_session(fh)); #endif } else CSLogError("Couldn't set signal handlers!"); } else CSLogError("fuse_new exited with an error. (errno is %d (%s))", errno, strerror(errno)); } else CSLogError("fuse_mount exited with an error. (errno is %d (%s))", errno, strerror(errno)); fuse_opt_free_args(&args); if(chan != NULL) { CSLogDebug("Unmounting \"%s\"... (chan=%p)", utf8MountPoint, chan); fuse_unmount(utf8MountPoint, chan); } if(fh != NULL) { CSLogDebug("Destroying fuse filehandle %p...", fh); fuse_destroy(fh); } delete context; } CSLogTraceLeave(_FNAME_ "(%p, %p, %p, %p, %p, %p, %p): %d", env, cls, fileSystem, mountPoint, optionStrings, fuseCapabilities, macFuseCapabilities, res); return res; #undef _FNAME_ }
int main(int argc, char *argv[]) { int res; int mt,fg; char *mountpoint; struct fuse_args args = FUSE_ARGS_INIT(argc, argv); struct fuse_args defaultargs = FUSE_ARGS_INIT(0, NULL); #if defined(SIGPIPE) && defined(SIG_IGN) signal(SIGPIPE,SIG_IGN); #endif strerr_init(); mycrc32_init(); mfsopts.masterhost = NULL; mfsopts.masterport = NULL; mfsopts.bindhost = NULL; mfsopts.proxyhost = NULL; mfsopts.subfolder = NULL; mfsopts.password = NULL; mfsopts.md5pass = NULL; mfsopts.preferedlabels = NULL; mfsopts.nofile = 0; mfsopts.nice = -19; #ifdef MFS_USE_MEMLOCK mfsopts.memlock = 0; #endif #ifdef MFS_USE_MALLOPT mfsopts.limitarenas = 8; #endif mfsopts.nostdmountoptions = 0; mfsopts.meta = 0; mfsopts.debug = 0; mfsopts.delayedinit = 0; #ifdef __linux__ mfsopts.mkdircopysgid = 1; #else mfsopts.mkdircopysgid = 0; #endif mfsopts.sugidclearmodestr = NULL; mfsopts.donotrememberpassword = 0; // mfsopts.xattraclsupport = 0; mfsopts.cachefiles = 0; mfsopts.noxattrs = 0; mfsopts.noposixlocks = 0; mfsopts.nobsdlocks = 0; mfsopts.cachemode = NULL; mfsopts.writecachesize = 0; mfsopts.readaheadsize = 0; mfsopts.readaheadleng = 0; mfsopts.readaheadtrigger = 0; mfsopts.ioretries = 30; mfsopts.passwordask = 0; mfsopts.attrcacheto = 1.0; mfsopts.xattrcacheto = 30.0; mfsopts.entrycacheto = 0.0; mfsopts.direntrycacheto = 1.0; mfsopts.negentrycacheto = 1.0; mfsopts.groupscacheto = 300.0; mfsopts.fsyncbeforeclose = 0; custom_cfg = 0; // dump_args("input_args",&args); fuse_opt_add_arg(&defaultargs,"fakeappname"); if (fuse_opt_parse(&args, &defaultargs, mfs_opts_stage1, mfs_opt_proc_stage1)<0) { exit(1); } if (custom_cfg==0) { int cfgfd; char *cfgfile; cfgfile=strdup(ETC_PATH "/mfs/mfsmount.cfg"); if ((cfgfd = open(cfgfile,O_RDONLY))<0 && errno==ENOENT) { free(cfgfile); cfgfile=strdup(ETC_PATH "/mfsmount.cfg"); if ((cfgfd = open(cfgfile,O_RDONLY))>=0) { fprintf(stderr,"default sysconf path has changed - please move mfsmount.cfg from "ETC_PATH"/ to "ETC_PATH"/mfs/\n"); } } if (cfgfd>=0) { close(cfgfd); } mfs_opt_parse_cfg_file(cfgfile,1,&defaultargs); free(cfgfile); } // dump_args("parsed_defaults",&defaultargs); // dump_args("changed_args",&args); if (fuse_opt_parse(&defaultargs, &mfsopts, mfs_opts_stage2, mfs_opt_proc_stage2)<0) { exit(1); } if (fuse_opt_parse(&args, &mfsopts, mfs_opts_stage2, mfs_opt_proc_stage2)<0) { exit(1); } // dump_args("args_after_parse",&args); if (mfsopts.cachemode!=NULL && mfsopts.cachefiles) { fprintf(stderr,"mfscachemode and mfscachefiles options are exclusive - use only mfscachemode\nsee: %s -h for help\n",argv[0]); return 1; } if (mfsopts.cachemode==NULL) { mfsopts.keepcache=(mfsopts.cachefiles)?1:0; } else if (strcasecmp(mfsopts.cachemode,"AUTO")==0) { mfsopts.keepcache=0; } else if (strcasecmp(mfsopts.cachemode,"YES")==0 || strcasecmp(mfsopts.cachemode,"ALWAYS")==0) { mfsopts.keepcache=1; } else if (strcasecmp(mfsopts.cachemode,"NO")==0 || strcasecmp(mfsopts.cachemode,"NONE")==0 || strcasecmp(mfsopts.cachemode,"NEVER")==0) { mfsopts.keepcache=2; } else { fprintf(stderr,"unrecognized cachemode option\nsee: %s -h for help\n",argv[0]); return 1; } if (mfsopts.sugidclearmodestr==NULL) { #if defined(DEFAULT_SUGID_CLEAR_MODE_EXT) mfsopts.sugidclearmode = SUGID_CLEAR_MODE_EXT; #elif defined(DEFAULT_SUGID_CLEAR_MODE_BSD) mfsopts.sugidclearmode = SUGID_CLEAR_MODE_BSD; #elif defined(DEFAULT_SUGID_CLEAR_MODE_OSX) mfsopts.sugidclearmode = SUGID_CLEAR_MODE_OSX; #else mfsopts.sugidclearmode = SUGID_CLEAR_MODE_NEVER; #endif } else if (strcasecmp(mfsopts.sugidclearmodestr,"NEVER")==0) { mfsopts.sugidclearmode = SUGID_CLEAR_MODE_NEVER; } else if (strcasecmp(mfsopts.sugidclearmodestr,"ALWAYS")==0) { mfsopts.sugidclearmode = SUGID_CLEAR_MODE_ALWAYS; } else if (strcasecmp(mfsopts.sugidclearmodestr,"OSX")==0) { mfsopts.sugidclearmode = SUGID_CLEAR_MODE_OSX; } else if (strcasecmp(mfsopts.sugidclearmodestr,"BSD")==0) { mfsopts.sugidclearmode = SUGID_CLEAR_MODE_BSD; } else if (strcasecmp(mfsopts.sugidclearmodestr,"EXT")==0) { mfsopts.sugidclearmode = SUGID_CLEAR_MODE_EXT; } else if (strcasecmp(mfsopts.sugidclearmodestr,"XFS")==0) { mfsopts.sugidclearmode = SUGID_CLEAR_MODE_XFS; } else { fprintf(stderr,"unrecognized sugidclearmode option\nsee: %s -h for help\n",argv[0]); return 1; } if (mfsopts.masterhost==NULL) { mfsopts.masterhost = strdup(DEFAULT_MASTERNAME); } if (mfsopts.masterport==NULL) { mfsopts.masterport = strdup(DEFAULT_MASTER_CLIENT_PORT); } if (mfsopts.proxyhost==NULL) { mfsopts.proxyhost = strdup("127.0.0.1"); } if (mfsopts.subfolder==NULL) { mfsopts.subfolder = strdup("/"); } if (mfsopts.nofile==0) { mfsopts.nofile=100000; } if (mfsopts.writecachesize==0) { mfsopts.writecachesize=256; } if (mfsopts.writecachesize<16) { fprintf(stderr,"write cache size too low (%u MiB) - increased to 16 MiB\n",mfsopts.writecachesize); mfsopts.writecachesize=16; } if (mfsopts.writecachesize>2048) { fprintf(stderr,"write cache size too big (%u MiB) - decresed to 2048 MiB\n",mfsopts.writecachesize); mfsopts.writecachesize=2048; } if (mfsopts.readaheadsize==0) { mfsopts.readaheadsize=256; } if (mfsopts.readaheadsize<16) { fprintf(stderr,"read ahead size too low (%u MiB) - increased to 16 MiB\n",mfsopts.readaheadsize); mfsopts.readaheadsize=16; } if (mfsopts.readaheadsize>2048) { fprintf(stderr,"read ahead size too big (%u MiB) - decresed to 2048 MiB\n",mfsopts.readaheadsize); mfsopts.readaheadsize=2048; } if (mfsopts.readaheadleng==0) { mfsopts.readaheadleng=0x100000; } if (mfsopts.readaheadleng<0x20000) { fprintf(stderr,"read ahead length too low (%u B) - increased to 128 KiB\n",mfsopts.readaheadleng); mfsopts.readaheadleng=0x20000; } if (mfsopts.readaheadleng>0x200000) { fprintf(stderr,"read ahead length too big (%u B) - decresed to 2 MiB\n",mfsopts.readaheadleng); mfsopts.readaheadleng=0x200000; } if (mfsopts.readaheadtrigger==0) { mfsopts.readaheadtrigger=mfsopts.readaheadleng*10; } if (mfsopts.nostdmountoptions==0) { fuse_opt_add_arg(&args, "-o" DEFAULT_OPTIONS); } if (csorder_init(mfsopts.preferedlabels)<0) { fprintf(stderr,"error parsing prefered labels expression\nsee: %s -h for help\n",argv[0]); return 1; } make_fsname(&args); remove_mfsmount_magic(&args); // dump_args("args_before_fuse_parse_cmdline",&args); if (fuse_parse_cmdline(&args,&mountpoint,&mt,&fg)<0) { fprintf(stderr,"see: %s -h for help\n",argv[0]); return 1; } if (!mountpoint) { if (defaultmountpoint) { mountpoint = defaultmountpoint; } else { fprintf(stderr,"no mount point\nsee: %s -h for help\n",argv[0]); return 1; } } res = mainloop(&args,mountpoint,mt,fg); fuse_opt_free_args(&args); free(mfsopts.masterhost); free(mfsopts.masterport); if (mfsopts.bindhost) { free(mfsopts.bindhost); } if (mfsopts.proxyhost) { free(mfsopts.proxyhost); } free(mfsopts.subfolder); if (defaultmountpoint) { free(defaultmountpoint); } stats_term(); strerr_term(); return res; }
int main(int argc, char *argv[]) { if(argc <= 2) { QString arg = "-h"; if(argc > 1) arg = argv[1]; if(arg == QStringLiteral("-h") || arg == QStringLiteral("--help")) { std::cout << argv[0] << " FUSE_options --dbfs DBFS_options" << std::endl; std::cout << "FUSE_options" << std::endl; std::cout << "\tuse -h --dbfs switch to print FUSE options" << std::endl; std::cout << "DBFS_options" << std::endl; std::cout << "\t--dbfs\t" << "DBFS options separator, all options prior this will be ignored by DBFS" << std::endl; std::cout << "\t--host <host>\t" << "Database host" << std::endl; std::cout << "\t--port <port>\t" << "Database port" << std::endl; std::cout << "\t -u" << std::endl; std::cout << "\t--user <user>\t" << "Database user" << std::endl; std::cout << "\t -p" << std::endl; std::cout << "\t--password [<password>]\t" << "Database user password, use -p without password for interactive input." << std::endl; std::cout << "\t--database <database>\t" << "Database name" << std::endl; std::cout << "\t--db-schema\t" << "Database schema name" << std::endl; std::cout << "\t--table-name\t" << "DBFS table name, default is 'dbfs'" << std::endl; std::cout << "\t--create\t" << "Create DBFS tables" << std::endl; exit(0); } } int dbfs_switch_index; for(dbfs_switch_index = 1; dbfs_switch_index < argc; dbfs_switch_index++) if(argv[dbfs_switch_index] == QLatin1String("--dbfs")) { break; } QScopedPointer<qf::core::LogDevice> file_log_device(qf::core::FileLogDevice::install()); file_log_device->setDomainTresholds(argc - dbfs_switch_index, argv + dbfs_switch_index); file_log_device->setPrettyDomain(true); QString o_database; QString o_user; QString o_password; QString o_host; int o_port = 0; QString o_db_schema; QString o_table_name; bool o_create_db = false; bool o_ask_passwd = false; for(int i=dbfs_switch_index + 1; i<argc; i++) { QString arg = argv[i]; if(arg == QStringLiteral("--host")) { if(i<argc-1) { i++; o_host = argv[i]; } } else if(arg == QStringLiteral("--port")) { if(i<argc-1) { i++; o_port = QString(argv[i]).toInt(); } } else if(arg == QStringLiteral("-u") || arg == QStringLiteral("--user")) { if(i<argc-1) { i++; o_user = argv[i]; } } else if(arg == QStringLiteral("-p") || arg == QStringLiteral("--password")) { if(i<argc-1) { QString p = argv[i+1]; if(p.startsWith('-')) { o_ask_passwd = true; } else { o_password = p; i++; } } else { o_ask_passwd = true; } } else if(arg == QStringLiteral("--database")) { if(i<argc-1) { i++; o_database = argv[i]; } } else if(arg == QStringLiteral("--db-schema")) { if(i<argc-1) { i++; o_db_schema = argv[i]; } } else if(arg == QStringLiteral("--table-name")) { if(i<argc-1) { i++; o_table_name = argv[i]; } } else if(arg == QStringLiteral("--create")) { o_create_db = true; } } if(o_ask_passwd) { char pwd[256]; std::cout << "Please, enter your password: "******"Empty database name."; exit(1); } qfs::DbFsDriver *dbfs_drv = nullptr; qf::core::sql::Connection db_connection; if(dbfs_switch_index < (argc - 1)) { db_connection = QSqlDatabase::addDatabase("QPSQL"); db_connection.setHostName(o_host); if(o_port > 0) db_connection.setPort(o_port); db_connection.setDatabaseName(o_database); db_connection.setUserName(o_user); db_connection.setPassword(o_password); //qfInfo() << o_host << o_port << o_user << o_database; bool ok = db_connection.open(); if(!ok) { qfError() << db_connection.lastError().text(); exit(1); } if(!o_db_schema.isEmpty()) { if(!db_connection.setCurrentSchema(o_db_schema)) { qfError() << "Error setting db schema to:" << o_db_schema; exit(1); } } dbfs_drv = new qfs::DbFsDriver(); dbfs_drv->setConnectionName(db_connection.connectionName()); if(!o_table_name.isEmpty()) { dbfs_drv->setTableName(o_table_name); } if(o_create_db) { if(!dbfs_drv->createDbFs()) { qfError() << "Error creating dbfs table" << dbfs_drv->tableName(); } exit(1); } qfsqldbfs_setdriver(dbfs_drv); } int fuse_argc = dbfs_switch_index; /// FUSE variables struct fuse_args fuse_arguments = FUSE_ARGS_INIT(fuse_argc, argv); struct fuse_chan *fuse_channel = NULL; struct fuse *fuse_handle = NULL; char *mount_point = nullptr; if (fuse_parse_cmdline(&fuse_arguments, &mount_point, NULL, NULL) == -1) { qfError() << "fuse_parse_cmdline() - Error parsing fuse command line arguments!"; exit(1); } /// Tell FUSE where the local mountpoint is fuse_channel = fuse_mount(mount_point, &fuse_arguments); if (fuse_channel == NULL){ qfError()<<"fuse_mount() failed"; exit(1); } // Tell FUSE about implementations of FS operations struct fuse_operations fuse_ops; memset(&fuse_ops, 0, sizeof(fuse_ops)); fuse_ops.getattr = qfsqldbfs_getattr; fuse_ops.readdir = qfsqldbfs_readdir; fuse_ops.open = qfsqldbfs_open; fuse_ops.read = qfsqldbfs_read; fuse_ops.write = qfsqldbfs_write; fuse_ops.fsync = qfsqldbfs_fsync; fuse_ops.flush = qfsqldbfs_flush; fuse_ops.release = qfsqldbfs_release; fuse_ops.mknod = qfsqldbfs_mknod; fuse_ops.mkdir = qfsqldbfs_mkdir; fuse_ops.unlink = qfsqldbfs_unlink; fuse_ops.rmdir = qfsqldbfs_rmdir; fuse_ops.utime = qfsqldbfs_utime; fuse_ops.truncate = qfsqldbfs_truncate; fuse_ops.ftruncate = qfsqldbfs_ftruncate; fuse_ops.chmod = qfsqldbfs_chmod; fuse_ops.chown = qfsqldbfs_chown; fuse_ops.create = qfsqldbfs_create; fuse_ops.rename = qfsqldbfs_rename; fuse_handle = fuse_new(fuse_channel, &fuse_arguments, &fuse_ops, sizeof(fuse_ops), NULL); if (fuse_handle == NULL){ qfError()<<"fuse_new() failed"; exit(1); } if(dbfs_drv) { #ifdef USE_QT_EVENT_LOOP qfInfo() << "Using Qt event loop with FUSE in separated thread"; TheApp *app = new TheApp(argc, argv); s_fuseThread = new FuseThread(fuse_handle, fuse_channel, QString::fromUtf8(mount_point)); dbfs_drv->moveToThread(s_fuseThread); QObject::connect(s_fuseThread, &QThread::finished, app, &TheApp::onFuseThreadFinished, Qt::QueuedConnection); s_fuseThread->start(); set_signal_handlers(); { /// setup SQL notify QSqlDatabase notify_db = QSqlDatabase::addDatabase("QPSQL", "DBFS_Notify"); notify_db.setHostName(db_connection.hostName()); notify_db.setPort(db_connection.port()); notify_db.setUserName(db_connection.userName()); notify_db.setPassword(db_connection.password()); notify_db.setDatabaseName(db_connection.databaseName()); bool ok = notify_db.open(); if(!ok) { qfError() << "Error connect DBFS notify connection" << notify_db.lastError().text(); } else { QSqlDriver *drv = notify_db.driver(); //qRegisterMetaType<QSqlDriver::NotificationSource>("QSqlDriver::NotificationSource"); QObject::connect(drv, SIGNAL(notification(QString,QSqlDriver::NotificationSource,QVariant)), dbfs_drv, SLOT(onSqlNotify(QString,QSqlDriver::NotificationSource,QVariant)), Qt::DirectConnection); //QObject::connect(drv, SIGNAL(notification(QString,QSqlDriver::NotificationSource,QVariant)), app, SLOT(onSqlNotify(QString,QSqlDriver::NotificationSource,QVariant))); drv->subscribeToNotification(qfs::DbFsDriver::CHANNEL_INVALIDATE_DBFS_DRIVER_CACHE); qfInfo() << drv << "subscribedToNotifications:" << drv->subscribedToNotifications().join(", "); } } app->exec(); qfInfo() << "Waiting for FUSE thread to join ..."; s_fuseThread->wait(); #else qfInfo() << "Using FUSE event loop"; fuse_loop(fuse_handle); qfInfo() << "FUSE has quit its event loop"; #endif qfsqldbfs_setdriver(nullptr); QF_SAFE_DELETE(dbfs_drv); #ifdef USE_QT_EVENT_LOOP QF_SAFE_DELETE(s_fuseThread); QF_SAFE_DELETE(app); #endif } else { // used just to print FUSE help fuse_loop(fuse_handle); } qfInfo() << "bye"; return 0; }
int main(int argc, char **argv) { extern void init_ops(fuse_lowlevel_ops *ops); struct options options; std::memset(&options, 0, sizeof(options)); struct fuse_args args = FUSE_ARGS_INIT(argc, argv); struct fuse_chan *ch; char *mountpoint = NULL; int err = -1; std::string mountPath; unsigned format = 0; int foreground = false; int multithread = false; Pascal::VolumeEntryPointer volume; init_ops(&pascal_ops); // scan the argument list, looking for the name of the disk image. if (fuse_opt_parse(&args, &options ,pascal_options, pascal_option_proc) == -1) exit(1); if (fDiskImage.empty()) { usage(); exit(1); } // default prodos-order disk image. if (options.format) { format = Device::BlockDevice::ImageType(options.format); if (!format) std::fprintf(stderr, "Warning: Unknown image type ``%s''\n", options.format); } try { Device::BlockDevicePointer device; device = Device::BlockDevice::Open(fDiskImage.c_str(), File::ReadOnly, format); if (!device.get()) { std::fprintf(stderr, "Error: Unknown or unsupported device type.\n"); exit(1); } volume = Pascal::VolumeEntry::Open(device); } catch (::Exception &e) { std::fprintf(stderr, "%s\n", e.what()); std::fprintf(stderr, "%s\n", std::strerror(e.error())); return -1; } #ifdef __APPLE__ { // Macfuse supports custom volume names (displayed in Finder) std::string str("-ovolname="); str += volume->name(); fuse_opt_add_arg(&args, str.c_str()); // 512 byte blocksize. fuse_opt_add_arg(&args, "-oiosize=512"); } #endif fuse_opt_add_arg(&args, "-ofsname=PascalFS"); if (!options.readOnly) fuse_opt_add_arg(&args, "-ordonly"); if (options.readWrite) { std::fprintf(stderr, "Warning: write support is not yet enabled.\n"); } if (fuse_parse_cmdline(&args, &mountpoint, &multithread, &foreground) == -1) { usage(); return -1; } #ifdef __APPLE__ if (mountpoint == NULL || *mountpoint == 0) { if (make_mount_dir(volume->name(), mountPath)) mountpoint = (char *)mountPath.c_str(); } #endif if ((ch = fuse_mount(mountpoint, &args)) != NULL) { struct fuse_session* se; std::printf("Mounting ``%s'' on ``%s''\n", volume->name(), mountpoint); se = fuse_lowlevel_new(&args, &pascal_ops, sizeof(pascal_ops), volume.get()); if (se) do { err = fuse_daemonize(foreground); if (err < 0 ) break; err = fuse_set_signal_handlers(se); if (err < 0) break; fuse_session_add_chan(se, ch); if (multithread) err = fuse_session_loop_mt(se); else err = fuse_session_loop(se); fuse_remove_signal_handlers(se); fuse_session_remove_chan(ch); } while (false); if (se) fuse_session_destroy(se); fuse_unmount(mountpoint, ch); } fuse_opt_free_args(&args); #ifdef __APPLE__ if (!mountPath.empty()) rmdir(mountPath.c_str()); #endif return err ? 1 : 0; }