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; }
static void fuse_teardown_common(struct fuse *fuse, char *mountpoint) { struct fuse_session *se = fuse_get_session(fuse); struct fuse_chan *ch = fuse_session_next_chan(se, NULL); fuse_remove_signal_handlers(se); fuse_unmount_common(mountpoint, ch); fuse_destroy(fuse); free(mountpoint); }
void fuse_teardown(struct fuse *fuse, char *mountpoint) { struct fuse_session *se = fuse_get_session(fuse); struct fuse_chan *ch = se->ch; if (fuse->conf.setsignals) fuse_remove_signal_handlers(se); fuse_unmount(mountpoint, ch); fuse_destroy(fuse); free(mountpoint); }
/* ----------------------------------------------------- */ 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; }
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; }
void cuse_lowlevel_teardown(struct fuse_session *se) { fuse_remove_signal_handlers(se); fuse_session_destroy(se); }
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; }
int mainloop(struct fuse_args *args,const char* mp,int mt,int fg) { struct fuse_session *se; struct fuse_chan *ch; struct rlimit rls; int piped[2]; char s; int err; int i; md5ctx ctx; uint8_t md5pass[16]; if (mfsopts.passwordask && mfsopts.password==NULL && mfsopts.md5pass==NULL) { mfsopts.password = getpass("MFS Password:"******"bad md5 definition (md5 should be given as 32 hex digits)\n"); return 1; } p++; if (*p>='0' && *p<='9') { md5pass[i]+=(*p-'0'); } else if (*p>='a' && *p<='f') { md5pass[i]+=(*p-'a'+10); } else if (*p>='A' && *p<='F') { md5pass[i]+=(*p-'A'+10); } else { fprintf(stderr,"bad md5 definition (md5 should be given as 32 hex digits)\n"); return 1; } p++; } if (*p) { fprintf(stderr,"bad md5 definition (md5 should be given as 32 hex digits)\n"); return 1; } memset(mfsopts.md5pass,0,strlen(mfsopts.md5pass)); } if (mfsopts.delayedinit) { fs_init_master_connection(mfsopts.bindhost,mfsopts.masterhost,mfsopts.masterport,mfsopts.meta,mp,mfsopts.subfolder,(mfsopts.password||mfsopts.md5pass)?md5pass:NULL,mfsopts.donotrememberpassword,1); } else { if (fs_init_master_connection(mfsopts.bindhost,mfsopts.masterhost,mfsopts.masterport,mfsopts.meta,mp,mfsopts.subfolder,(mfsopts.password||mfsopts.md5pass)?md5pass:NULL,mfsopts.donotrememberpassword,0)<0) { return 1; } } memset(md5pass,0,16); if (fg==0) { openlog(STR(APPNAME), LOG_PID | LOG_NDELAY , LOG_DAEMON); } else { #if defined(LOG_PERROR) openlog(STR(APPNAME), LOG_PID | LOG_NDELAY | LOG_PERROR, LOG_USER); #else openlog(STR(APPNAME), LOG_PID | LOG_NDELAY, LOG_USER); #endif } i = mfsopts.nofile; while (1) { rls.rlim_cur = i; rls.rlim_max = i; if (setrlimit(RLIMIT_NOFILE,&rls)<0) { i /= 2; if (i<1000) { break; } } else { break; } } if (i != (int)(mfsopts.nofile)) { fprintf(stderr,"can't set open file limit to %d\n",mfsopts.nofile); if (i>=1000) { fprintf(stderr,"open file limit set to: %d\n",i); } } setpriority(PRIO_PROCESS,getpid(),mfsopts.nice); #ifdef MFS_USE_MEMLOCK if (mfsopts.memlock) { rls.rlim_cur = RLIM_INFINITY; rls.rlim_max = RLIM_INFINITY; if (setrlimit(RLIMIT_MEMLOCK,&rls)<0) { mfsopts.memlock=0; } } #endif piped[0] = piped[1] = -1; if (fg==0) { if (pipe(piped)<0) { fprintf(stderr,"pipe error\n"); return 1; } err = fork(); if (err<0) { fprintf(stderr,"fork error\n"); return 1; } else if (err>0) { close(piped[1]); err = read(piped[0],&s,1); if (err==0) { s=1; } return s; } close(piped[0]); s=1; } #ifdef MFS_USE_MEMLOCK if (mfsopts.memlock) { if (mlockall(MCL_CURRENT|MCL_FUTURE)==0) { syslog(LOG_NOTICE,"process memory was successfully locked in RAM"); } } #endif /* glibc malloc tuning */ #ifdef MFS_USE_MALLOPT if (mfsopts.limitarenas) { if (!getenv("MALLOC_ARENA_MAX")) { syslog(LOG_NOTICE,"setting glibc malloc arena max to 8"); mallopt(M_ARENA_MAX, mfsopts.limitarenas); } if (!getenv("MALLOC_ARENA_TEST")) { syslog(LOG_NOTICE,"setting glibc malloc arena test to 1"); mallopt(M_ARENA_TEST, 1); } } else { syslog(LOG_NOTICE,"setting glibc malloc arenas turned off"); } #endif /* glibc malloc tuning */ syslog(LOG_NOTICE,"monotonic clock function: %s",monotonic_method()); syslog(LOG_NOTICE,"monotonic clock speed: %"PRIu32" ops / 10 mili seconds",monotonic_speed()); conncache_init(200); chunkloc_cache_init(); symlink_cache_init(); negentry_cache_init(mfsopts.negentrycacheto); // dir_cache_init(); fs_init_threads(mfsopts.ioretries); if (masterproxy_init(mfsopts.proxyhost)<0) { fs_term(); // dir_cache_term(); negentry_cache_term(); symlink_cache_term(); chunkloc_cache_term(); return 1; } // fs_term(); // negentry_cache_term(); // symlink_cache_term(); // chunkloc_cache_term(); // return 1; if (mfsopts.meta==0) { csdb_init(); delay_init(); read_data_init(mfsopts.readaheadsize*1024*1024,mfsopts.readaheadleng,mfsopts.readaheadtrigger,mfsopts.ioretries); write_data_init(mfsopts.writecachesize*1024*1024,mfsopts.ioretries); } ch = fuse_mount(mp, args); if (ch==NULL) { fprintf(stderr,"error in fuse_mount\n"); if (piped[1]>=0) { if (write(piped[1],&s,1)!=1) { fprintf(stderr,"pipe write error\n"); } close(piped[1]); } if (mfsopts.meta==0) { write_data_term(); read_data_term(); delay_term(); csdb_term(); } masterproxy_term(); fs_term(); // dir_cache_term(); negentry_cache_term(); symlink_cache_term(); chunkloc_cache_term(); return 1; } if (mfsopts.meta) { mfs_meta_init(mfsopts.debug,mfsopts.entrycacheto,mfsopts.attrcacheto); se = fuse_lowlevel_new(args, &mfs_meta_oper, sizeof(mfs_meta_oper), (void*)piped); } else { mfs_init(mfsopts.debug,mfsopts.keepcache,mfsopts.direntrycacheto,mfsopts.entrycacheto,mfsopts.attrcacheto,mfsopts.xattrcacheto,mfsopts.groupscacheto,mfsopts.mkdircopysgid,mfsopts.sugidclearmode,1,mfsopts.fsyncbeforeclose,mfsopts.noxattrs,mfsopts.noposixlocks,mfsopts.nobsdlocks); //mfsopts.xattraclsupport); se = fuse_lowlevel_new(args, &mfs_oper, sizeof(mfs_oper), (void*)piped); } if (se==NULL) { fuse_unmount(mp,ch); fprintf(stderr,"error in fuse_lowlevel_new\n"); portable_usleep(100000); // time for print other error messages by FUSE if (piped[1]>=0) { if (write(piped[1],&s,1)!=1) { fprintf(stderr,"pipe write error\n"); } close(piped[1]); } if (mfsopts.meta==0) { write_data_term(); read_data_term(); delay_term(); csdb_term(); } masterproxy_term(); fs_term(); // dir_cache_term(); negentry_cache_term(); symlink_cache_term(); chunkloc_cache_term(); return 1; } // fprintf(stderr,"check\n"); fuse_session_add_chan(se, ch); if (fuse_set_signal_handlers(se)<0) { fprintf(stderr,"error in fuse_set_signal_handlers\n"); fuse_session_remove_chan(ch); fuse_session_destroy(se); fuse_unmount(mp,ch); if (piped[1]>=0) { if (write(piped[1],&s,1)!=1) { fprintf(stderr,"pipe write error\n"); } close(piped[1]); } if (mfsopts.meta==0) { write_data_term(); read_data_term(); delay_term(); csdb_term(); } masterproxy_term(); fs_term(); // dir_cache_term(); negentry_cache_term(); symlink_cache_term(); chunkloc_cache_term(); return 1; } if (mfsopts.debug==0 && fg==0) { setsid(); setpgid(0,getpid()); if ((i = open("/dev/null", O_RDWR, 0)) != -1) { (void)dup2(i, STDIN_FILENO); (void)dup2(i, STDOUT_FILENO); (void)dup2(i, STDERR_FILENO); if (i>2) close (i); } } if (mt) { err = fuse_session_loop_mt(se); } else { err = fuse_session_loop(se); } if (err) { if (piped[1]>=0) { if (write(piped[1],&s,1)!=1) { syslog(LOG_ERR,"pipe write error: %s",strerr(errno)); } close(piped[1]); } } fuse_remove_signal_handlers(se); fuse_session_remove_chan(ch); fuse_session_destroy(se); fuse_unmount(mp,ch); if (mfsopts.meta==0) { write_data_term(); read_data_term(); delay_term(); csdb_term(); } masterproxy_term(); fs_term(); // dir_cache_term(); negentry_cache_term(); symlink_cache_term(); chunkloc_cache_term(); return err ? 1 : 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; }
int main(int argc, char* argv[]) { struct fuse_args mount_args = FUSE_ARGS_INIT(0, NULL); struct fuse_args newfs_args = FUSE_ARGS_INIT(0, NULL); const char* spec = NULL; const char* mount_point = NULL; char* mount_options; int debug = 0; struct fuse_chan* fc = NULL; struct fuse* fh = NULL; int opt; printf("FUSE exfat %u.%u.%u\n", EXFAT_VERSION_MAJOR, EXFAT_VERSION_MINOR, EXFAT_VERSION_PATCH); mount_options = strdup(default_options); if (mount_options == NULL) { exfat_error("failed to allocate options string"); return 1; } while ((opt = getopt(argc, argv, "dno:Vv")) != -1) { switch (opt) { case 'd': debug = 1; break; case 'n': break; case 'o': mount_options = add_option(mount_options, optarg, NULL); if (mount_options == NULL) return 1; break; case 'V': free(mount_options); puts("Copyright (C) 2010-2014 Andrew Nayenko"); return 0; case 'v': break; default: free(mount_options); usage(argv[0]); break; } } if (argc - optind != 2) { free(mount_options); usage(argv[0]); } spec = argv[optind]; mount_point = argv[optind + 1]; if (exfat_mount(&ef, spec, mount_options) != 0) { free(mount_options); return 1; } if (ef.ro == -1) /* read-only fallback was used */ { mount_options = add_option(mount_options, "ro", NULL); if (mount_options == NULL) { exfat_unmount(&ef); return 1; } } mount_options = add_fuse_options(mount_options, spec); if (mount_options == NULL) { exfat_unmount(&ef); return 1; } /* create arguments for fuse_mount() */ if (fuse_opt_add_arg(&mount_args, "exfat") != 0 || fuse_opt_add_arg(&mount_args, "-o") != 0 || fuse_opt_add_arg(&mount_args, mount_options) != 0) { exfat_unmount(&ef); free(mount_options); return 1; } free(mount_options); /* create FUSE mount point */ fc = fuse_mount(mount_point, &mount_args); fuse_opt_free_args(&mount_args); if (fc == NULL) { exfat_unmount(&ef); return 1; } /* create arguments for fuse_new() */ if (fuse_opt_add_arg(&newfs_args, "") != 0 || (debug && fuse_opt_add_arg(&newfs_args, "-d") != 0)) { fuse_unmount(mount_point, fc); exfat_unmount(&ef); return 1; } /* create new FUSE file system */ fh = fuse_new(fc, &newfs_args, &fuse_exfat_ops, sizeof(struct fuse_operations), NULL); fuse_opt_free_args(&newfs_args); if (fh == NULL) { fuse_unmount(mount_point, fc); exfat_unmount(&ef); return 1; } /* exit session on HUP, TERM and INT signals and ignore PIPE signal */ if (fuse_set_signal_handlers(fuse_get_session(fh)) != 0) { fuse_unmount(mount_point, fc); fuse_destroy(fh); exfat_unmount(&ef); exfat_error("failed to set signal handlers"); return 1; } /* go to background (unless "-d" option is passed) and run FUSE main loop */ if (fuse_daemonize(debug) == 0) { if (fuse_loop(fh) != 0) exfat_error("FUSE loop failure"); } else exfat_error("failed to daemonize"); fuse_remove_signal_handlers(fuse_get_session(fh)); /* note that fuse_unmount() must be called BEFORE fuse_destroy() */ fuse_unmount(mount_point, fc); fuse_destroy(fh); return 0; }
/* * 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[]) { 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; }