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; }
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; }
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 main( int argc, char * const argv[] ) #endif { libregf_error_t *error = NULL; system_character_t *mount_point = NULL; system_character_t *option_codepage = NULL; system_character_t *option_extended_options = NULL; system_character_t *source = NULL; char *program = "regfmount"; system_integer_t option = 0; int result = 0; int verbose = 0; #if defined( HAVE_LIBFUSE ) || defined( HAVE_LIBOSXFUSE ) struct fuse_operations regfmount_fuse_operations; struct fuse_args regfmount_fuse_arguments = FUSE_ARGS_INIT(0, NULL); struct fuse_chan *regfmount_fuse_channel = NULL; struct fuse *regfmount_fuse_handle = NULL; #elif defined( HAVE_LIBDOKAN ) DOKAN_OPERATIONS regfmount_dokan_operations; DOKAN_OPTIONS regfmount_dokan_options; #endif libcnotify_stream_set( stderr, NULL ); libcnotify_verbose_set( 1 ); if( libclocale_initialize( "regftools", &error ) != 1 ) { fprintf( stderr, "Unable to initialize locale values.\n" ); goto on_error; } if( regftools_output_initialize( _IONBF, &error ) != 1 ) { fprintf( stderr, "Unable to initialize output settings.\n" ); goto on_error; } regftools_output_version_fprint( stdout, program ); while( ( option = regftools_getopt( argc, argv, _SYSTEM_STRING( "c:hvVX:" ) ) ) != (system_integer_t) -1 ) { switch( option ) { case (system_integer_t) '?': default: fprintf( stderr, "Invalid argument: %" PRIs_SYSTEM "\n", argv[ optind - 1 ] ); usage_fprint( stdout ); return( EXIT_FAILURE ); case (system_integer_t) 'c': option_codepage = optarg; break; case (system_integer_t) 'h': usage_fprint( stdout ); return( EXIT_SUCCESS ); case (system_integer_t) 'v': verbose = 1; break; case (system_integer_t) 'V': regftools_output_copyright_fprint( stdout ); return( EXIT_SUCCESS ); case (system_integer_t) 'X': option_extended_options = optarg; break; } } if( optind == argc ) { fprintf( stderr, "Missing source file.\n" ); usage_fprint( stdout ); return( EXIT_FAILURE ); } source = argv[ optind++ ]; if( optind == argc ) { fprintf( stderr, "Missing mount point.\n" ); usage_fprint( stdout ); return( EXIT_FAILURE ); } mount_point = argv[ optind ]; libcnotify_verbose_set( verbose ); libregf_notify_set_stream( stderr, NULL ); libregf_notify_set_verbose( verbose ); if( mount_handle_initialize( ®fmount_mount_handle, &error ) != 1 ) { fprintf( stderr, "Unable to initialize mount handle.\n" ); goto on_error; } if( option_codepage != NULL ) { result = mount_handle_set_ascii_codepage( regfmount_mount_handle, option_codepage, &error ); if( result == -1 ) { fprintf( stderr, "Unable to set ASCII codepage in mount handle.\n" ); goto on_error; } else if( result == 0 ) { fprintf( stderr, "Unsupported ASCII codepage defaulting to: windows-1252.\n" ); } } if( mount_handle_open( regfmount_mount_handle, source, &error ) != 1 ) { fprintf( stderr, "Unable to open source file\n" ); goto on_error; } #if defined( HAVE_LIBFUSE ) || defined( HAVE_LIBOSXFUSE ) if( option_extended_options != NULL ) { /* This argument is required but ignored */ if( fuse_opt_add_arg( ®fmount_fuse_arguments, "" ) != 0 ) { fprintf( stderr, "Unable add fuse arguments.\n" ); goto on_error; } if( fuse_opt_add_arg( ®fmount_fuse_arguments, "-o" ) != 0 ) { fprintf( stderr, "Unable add fuse arguments.\n" ); goto on_error; } if( fuse_opt_add_arg( ®fmount_fuse_arguments, option_extended_options ) != 0 ) { fprintf( stderr, "Unable add fuse arguments.\n" ); goto on_error; } } if( memory_set( ®fmount_fuse_operations, 0, sizeof( struct fuse_operations ) ) == NULL ) { fprintf( stderr, "Unable to clear fuse operations.\n" ); goto on_error; } regfmount_fuse_operations.open = &mount_fuse_open; regfmount_fuse_operations.read = &mount_fuse_read; regfmount_fuse_operations.release = &mount_fuse_release; regfmount_fuse_operations.opendir = &mount_fuse_opendir; regfmount_fuse_operations.readdir = &mount_fuse_readdir; regfmount_fuse_operations.releasedir = &mount_fuse_releasedir; regfmount_fuse_operations.getattr = &mount_fuse_getattr; regfmount_fuse_operations.destroy = &mount_fuse_destroy; regfmount_fuse_channel = fuse_mount( mount_point, ®fmount_fuse_arguments ); if( regfmount_fuse_channel == NULL ) { fprintf( stderr, "Unable to create fuse channel.\n" ); goto on_error; } regfmount_fuse_handle = fuse_new( regfmount_fuse_channel, ®fmount_fuse_arguments, ®fmount_fuse_operations, sizeof( struct fuse_operations ), regfmount_mount_handle ); if( regfmount_fuse_handle == NULL ) { fprintf( stderr, "Unable to create fuse handle.\n" ); goto on_error; } if( verbose == 0 ) { if( fuse_daemonize( 0 ) != 0 ) { fprintf( stderr, "Unable to daemonize fuse.\n" ); goto on_error; } } result = fuse_loop( regfmount_fuse_handle ); if( result != 0 ) { fprintf( stderr, "Unable to run fuse loop.\n" ); goto on_error; } fuse_destroy( regfmount_fuse_handle ); fuse_opt_free_args( ®fmount_fuse_arguments ); return( EXIT_SUCCESS ); #elif defined( HAVE_LIBDOKAN ) if( memory_set( ®fmount_dokan_operations, 0, sizeof( DOKAN_OPERATIONS ) ) == NULL ) { fprintf( stderr, "Unable to clear dokan operations.\n" ); goto on_error; } if( memory_set( ®fmount_dokan_options, 0, sizeof( DOKAN_OPTIONS ) ) == NULL ) { fprintf( stderr, "Unable to clear dokan options.\n" ); goto on_error; } regfmount_dokan_options.Version = DOKAN_VERSION; regfmount_dokan_options.ThreadCount = 0; regfmount_dokan_options.MountPoint = mount_point; if( verbose != 0 ) { regfmount_dokan_options.Options |= DOKAN_OPTION_STDERR; #if defined( HAVE_DEBUG_OUTPUT ) regfmount_dokan_options.Options |= DOKAN_OPTION_DEBUG; #endif } /* This will only affect the drive properties regfmount_dokan_options.Options |= DOKAN_OPTION_REMOVABLE; */ #if ( DOKAN_VERSION >= 600 ) && ( DOKAN_VERSION < 800 ) regfmount_dokan_options.Options |= DOKAN_OPTION_KEEP_ALIVE; regfmount_dokan_operations.CreateFile = &mount_dokan_CreateFile; regfmount_dokan_operations.OpenDirectory = &mount_dokan_OpenDirectory; regfmount_dokan_operations.CreateDirectory = NULL; regfmount_dokan_operations.Cleanup = NULL; regfmount_dokan_operations.CloseFile = &mount_dokan_CloseFile; regfmount_dokan_operations.ReadFile = &mount_dokan_ReadFile; regfmount_dokan_operations.WriteFile = NULL; regfmount_dokan_operations.FlushFileBuffers = NULL; regfmount_dokan_operations.GetFileInformation = &mount_dokan_GetFileInformation; regfmount_dokan_operations.FindFiles = &mount_dokan_FindFiles; regfmount_dokan_operations.FindFilesWithPattern = NULL; regfmount_dokan_operations.SetFileAttributes = NULL; regfmount_dokan_operations.SetFileTime = NULL; regfmount_dokan_operations.DeleteFile = NULL; regfmount_dokan_operations.DeleteDirectory = NULL; regfmount_dokan_operations.MoveFile = NULL; regfmount_dokan_operations.SetEndOfFile = NULL; regfmount_dokan_operations.SetAllocationSize = NULL; regfmount_dokan_operations.LockFile = NULL; regfmount_dokan_operations.UnlockFile = NULL; regfmount_dokan_operations.GetFileSecurity = NULL; regfmount_dokan_operations.SetFileSecurity = NULL; regfmount_dokan_operations.GetDiskFreeSpace = NULL; regfmount_dokan_operations.GetVolumeInformation = &mount_dokan_GetVolumeInformation; regfmount_dokan_operations.Unmount = &mount_dokan_Unmount; #else regfmount_dokan_operations.ZwCreateFile = &mount_dokan_ZwCreateFile; regfmount_dokan_operations.Cleanup = NULL; regfmount_dokan_operations.CloseFile = &mount_dokan_CloseFile; regfmount_dokan_operations.ReadFile = &mount_dokan_ReadFile; regfmount_dokan_operations.WriteFile = NULL; regfmount_dokan_operations.FlushFileBuffers = NULL; regfmount_dokan_operations.GetFileInformation = &mount_dokan_GetFileInformation; regfmount_dokan_operations.FindFiles = &mount_dokan_FindFiles; regfmount_dokan_operations.FindFilesWithPattern = NULL; regfmount_dokan_operations.SetFileAttributes = NULL; regfmount_dokan_operations.SetFileTime = NULL; regfmount_dokan_operations.DeleteFile = NULL; regfmount_dokan_operations.DeleteDirectory = NULL; regfmount_dokan_operations.MoveFile = NULL; regfmount_dokan_operations.SetEndOfFile = NULL; regfmount_dokan_operations.SetAllocationSize = NULL; regfmount_dokan_operations.LockFile = NULL; regfmount_dokan_operations.UnlockFile = NULL; regfmount_dokan_operations.GetFileSecurity = NULL; regfmount_dokan_operations.SetFileSecurity = NULL; regfmount_dokan_operations.GetDiskFreeSpace = NULL; regfmount_dokan_operations.GetVolumeInformation = &mount_dokan_GetVolumeInformation; regfmount_dokan_operations.Unmounted = NULL; regfmount_dokan_operations.FindStreams = NULL; regfmount_dokan_operations.Mounted = NULL; #endif /* ( DOKAN_VERSION >= 600 ) && ( DOKAN_VERSION < 800 ) */ result = DokanMain( ®fmount_dokan_options, ®fmount_dokan_operations ); switch( result ) { case DOKAN_SUCCESS: break; case DOKAN_ERROR: fprintf( stderr, "Unable to run dokan main: generic error\n" ); break; case DOKAN_DRIVE_LETTER_ERROR: fprintf( stderr, "Unable to run dokan main: bad drive letter\n" ); break; case DOKAN_DRIVER_INSTALL_ERROR: fprintf( stderr, "Unable to run dokan main: unable to load driver\n" ); break; case DOKAN_START_ERROR: fprintf( stderr, "Unable to run dokan main: driver error\n" ); break; case DOKAN_MOUNT_ERROR: fprintf( stderr, "Unable to run dokan main: unable to assign drive letter\n" ); break; case DOKAN_MOUNT_POINT_ERROR: fprintf( stderr, "Unable to run dokan main: mount point error\n" ); break; default: fprintf( stderr, "Unable to run dokan main: unknown error: %d\n", result ); break; } return( EXIT_SUCCESS ); #else fprintf( stderr, "No sub system to mount REGF format.\n" ); return( EXIT_FAILURE ); #endif on_error: if( error != NULL ) { libcnotify_print_error_backtrace( error ); libcerror_error_free( &error ); } #if defined( HAVE_LIBFUSE ) || defined( HAVE_LIBOSXFUSE ) if( regfmount_fuse_handle != NULL ) { fuse_destroy( regfmount_fuse_handle ); } fuse_opt_free_args( ®fmount_fuse_arguments ); #endif if( regfmount_mount_handle != NULL ) { mount_handle_free( ®fmount_mount_handle, NULL ); } return( EXIT_FAILURE ); }
// 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) { 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; }
/*{{{ application_finish_initialization_and_run */ static gint application_finish_initialization_and_run (Application *app) { struct sigaction sigact; /*{{{ create Pools */ // create ClientPool for reading operations app->read_client_pool = client_pool_create (app, conf_get_int (app->conf, "pool.readers"), http_connection_create, http_connection_destroy, http_connection_set_on_released_cb, http_connection_check_rediness, http_connection_get_stats_info_caption, http_connection_get_stats_info_data ); if (!app->read_client_pool) { LOG_err (APP_LOG, "Failed to create ClientPool !"); application_exit (app); return -1; } // create ClientPool for writing operations app->write_client_pool = client_pool_create (app, conf_get_int (app->conf, "pool.writers"), http_connection_create, http_connection_destroy, http_connection_set_on_released_cb, http_connection_check_rediness, http_connection_get_stats_info_caption, http_connection_get_stats_info_data ); if (!app->write_client_pool) { LOG_err (APP_LOG, "Failed to create ClientPool !"); application_exit (app); return -1; } // create ClientPool for various operations app->ops_client_pool = client_pool_create (app, conf_get_int (app->conf, "pool.operations"), http_connection_create, http_connection_destroy, http_connection_set_on_released_cb, http_connection_check_rediness, http_connection_get_stats_info_caption, http_connection_get_stats_info_data ); if (!app->ops_client_pool) { LOG_err (APP_LOG, "Failed to create ClientPool !"); application_exit (app); return -1; } /*}}}*/ /*{{{ CacheMng */ app->cmng = cache_mng_create (app); if (!app->cmng) { LOG_err (APP_LOG, "Failed to create CacheMng !"); application_exit (app); return -1; } /*}}}*/ /*{{{ DirTree*/ app->dir_tree = dir_tree_create (app); if (!app->dir_tree) { LOG_err (APP_LOG, "Failed to create DirTree !"); application_exit (app); return -1; } /*}}}*/ /*{{{ FUSE*/ app->rfuse = rfuse_new (app, conf_get_string (app->conf, "app.mountpoint"), app->fuse_opts); if (!app->rfuse) { LOG_err (APP_LOG, "Failed to create FUSE fs ! Mount point: %s", conf_get_string (app->conf, "app.mountpoint")); application_exit (app); return -1; } /*}}}*/ // set global App variable _app = app; /*{{{ signal handlers*/ // SIGINT app->sigint_ev = evsignal_new (app->evbase, SIGINT, sigint_cb, app); event_add (app->sigint_ev, NULL); // SIGSEGV sigact.sa_sigaction = sigsegv_cb; sigact.sa_flags = (int)SA_RESETHAND | SA_SIGINFO; sigemptyset (&sigact.sa_mask); if (sigaction (SIGSEGV, &sigact, (struct sigaction *) NULL) != 0) { LOG_err (APP_LOG, "error setting signal handler for %d (%s)\n", SIGSEGV, strsignal(SIGSEGV)); application_exit (app); return 1; } // SIGTERM app->sigterm_ev = evsignal_new (app->evbase, SIGTERM, sigterm_cb, app); event_add (app->sigterm_ev, NULL); // SIGABRT sigact.sa_sigaction = sigsegv_cb; sigact.sa_flags = (int)SA_RESETHAND | SA_SIGINFO; sigemptyset (&sigact.sa_mask); if (sigaction (SIGABRT, &sigact, (struct sigaction *) NULL) != 0) { LOG_err (APP_LOG, "error setting signal handler for %d (%s)\n", SIGABRT, strsignal(SIGABRT)); application_exit (app); return 1; } // SIGPIPE app->sigpipe_ev = evsignal_new (app->evbase, SIGPIPE, sigpipe_cb, app); event_add (app->sigpipe_ev, NULL); // SIGUSR1 app->sigusr1_ev = evsignal_new (app->evbase, SIGUSR1, sigusr1_cb, app); event_add (app->sigusr1_ev, NULL); // SIGUSR2 app->sigusr2_ev = evsignal_new (app->evbase, SIGUSR2, sigusr2_cb, app); event_add (app->sigusr2_ev, NULL); /*}}}*/ if (!conf_get_boolean (app->conf, "app.foreground")) fuse_daemonize (0); return 0; }