Example #1
0
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);
}
Example #3
0
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);
}
Example #4
0
/* ----------------------------------------------------- */
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;
}
Example #5
0
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;

}
Example #6
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;
}
Example #9
0
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;
}
Example #10
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;
}
Example #11
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_
}
Example #13
0
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;
}