void parse(struct fuse_args &args, config::Config &config) { fuse_opt_parse(&args, &config, NULL, ::option_processor); set_fsname(args,config); config.updateReadStr(); }
void parse(fuse_args &args, Config &config) { const struct fuse_opt opts[] = { FUSE_OPT_KEY("-h",MERGERFS_OPT_HELP), FUSE_OPT_KEY("--help",MERGERFS_OPT_HELP), FUSE_OPT_KEY("-v",MERGERFS_OPT_VERSION), FUSE_OPT_KEY("-V",MERGERFS_OPT_VERSION), FUSE_OPT_KEY("--version",MERGERFS_OPT_VERSION), {NULL,-1U,0} }; fuse_opt_parse(&args, &config, opts, ::option_processor); set_fsname(args,config.srcmounts); set_subtype(args); }
/* Check mount point and FS type. * Also return the associated device number. * (for STAY_IN_FS security option). */ int CheckFSInfo( char *path, char *expected_type, dev_t * p_fs_dev, int check_mounted, int save_fs ) { FILE *fp; struct mntent *p_mnt; struct mntent mnt_ent; char mnt_buff[4096]; char rpath[RBH_PATH_MAX]; char mntdir[RBH_PATH_MAX]; char tmp_buff[RBH_PATH_MAX]; char *parentmntdir; char fs_spec[RBH_PATH_MAX]; #ifdef _HAVE_FID char *ptr; #endif char type[256]; struct stat pathstat; struct stat parentmntstat; size_t pathlen, outlen; if ( ( expected_type == NULL ) || ( expected_type[0] == '\0' ) ) { DisplayLog( LVL_CRIT, "CheckFS", "/!\\ ERROR /!\\ No filesystem type specified" ); return EINVAL; } /* convert to canonic path */ if ( !realpath( path, rpath ) ) { DisplayLog( LVL_CRIT, "CheckFS", "Error %d in realpath(%s): %s", errno, ( path ? path : "<null>" ), strerror( errno ) ); return errno; } /* open mount tab and look for the given path */ outlen = 0; fp = setmntent( MOUNTED, "r" ); if ( fp == NULL ) { DisplayLog( LVL_CRIT, "CheckFS", "Error %d in setmntent(%s): %s", errno, MOUNTED, strerror( errno ) ); return errno; } while ( ( p_mnt = getmntent_r( fp, &mnt_ent, mnt_buff, 4096 ) ) != NULL ) { /* get the longest matching path */ if ( p_mnt->mnt_dir != NULL ) { pathlen = strlen( p_mnt->mnt_dir ); /* if check_mounted is FALSE, root filesystem is allowed */ if ( !check_mounted && ( pathlen > outlen ) && !strcmp( p_mnt->mnt_dir, "/" ) ) { DisplayLog( LVL_DEBUG, "CheckFS", "Root mountpoint is allowed for matching %s, type=%s, fs=%s", rpath, p_mnt->mnt_type, p_mnt->mnt_fsname ); outlen = pathlen; strncpy( mntdir, p_mnt->mnt_dir, RBH_PATH_MAX ); strncpy( type, p_mnt->mnt_type, 256 ); strncpy( fs_spec, p_mnt->mnt_fsname, RBH_PATH_MAX ); } /* in other cases, the filesystem must be <mountpoint>/<smthg> or <mountpoint>\0 */ else if ( ( pathlen > outlen ) && !strncmp( rpath, p_mnt->mnt_dir, pathlen ) && ( ( rpath[pathlen] == '/' ) || ( rpath[pathlen] == '\0' ) ) ) { DisplayLog( LVL_FULL, "CheckFS", "%s is under mountpoint %s, type=%s, fs=%s", rpath, p_mnt->mnt_dir, p_mnt->mnt_type, p_mnt->mnt_fsname ); outlen = pathlen; strncpy( mntdir, p_mnt->mnt_dir, RBH_PATH_MAX ); strncpy( type, p_mnt->mnt_type, 256 ); strncpy( fs_spec, p_mnt->mnt_fsname, RBH_PATH_MAX ); } } } if ( outlen <= 0 ) { DisplayLog( LVL_CRIT, "CheckFS", "No mount entry matches '%s' in %s", rpath, MOUNTED ); DisplayLog( LVL_CRIT, "CheckFS", "Set 'check_mounted = FALSE' in configuration to force using root filesystem" ); endmntent( fp ); return ENOENT; } /* display the matching entry */ DisplayLog( LVL_EVENT, "CheckFS", "'%s' matches mount point '%s', type=%s, fs=%s", rpath, mntdir, type, fs_spec ); /* check filesystem type */ if ( strcasecmp( type, expected_type ) ) { if (check_mounted) { DisplayLog( LVL_CRIT, "CheckFS", "/!\\ ERROR /!\\ The specified type for '%s' (%s) does not match actual filesystem type (%s)", rpath, expected_type, type ); endmntent( fp ); return EINVAL; } else { DisplayLog( LVL_MAJOR, "CheckFS", "/!\\ WARNING /!\\ The specified type for '%s' (%s) " "does not match actual filesystem type (%s).", rpath, expected_type, type ); DisplayLog( LVL_MAJOR, "CheckFS", "check_mounted is disabled: continuing." ); } } /* stat the given fs_path */ if ( stat( rpath, &pathstat ) != 0 ) { DisplayLog( LVL_CRIT, "CheckFS", "/!\\ ERROR /!\\ Couldn't stat '%s': %s", rpath, strerror( errno ) ); endmntent( fp ); return errno; } /* Stat upper level of mount point, to check if * the filesystem is mounted (device must be different). * (dirname modifies string content, so we work on a copy * in tmp_buff). */ strcpy( tmp_buff, mntdir ); parentmntdir = dirname( tmp_buff ); if ( lstat( parentmntdir, &parentmntstat ) != 0 ) { DisplayLog( LVL_CRIT, "CheckFS", "/!\\ ERROR /!\\ Couldn't stat %s: %s", parentmntdir, strerror( errno ) ); endmntent( fp ); return errno; } /* check that filesystem device is different from root (except if check_mounted is disabled) */ if ( ( pathstat.st_dev == parentmntstat.st_dev ) && check_mounted ) { DisplayLog( LVL_CRIT, "CheckFS", "/!\\ ERROR /!\\ Filesystem '%s' is not mounted ! dev(%s)=dev(%s)=%#" PRIx64, mntdir, parentmntdir, rpath, (uint64_t)parentmntstat.st_dev ); endmntent( fp ); return ENOENT; } #ifdef _HAVE_FID if ( save_fs ) { set_mount_point( mntdir ); ptr = strstr( fs_spec, ":/" ); if ( ptr != NULL ) { set_fsname( ptr + 2 ); } } #endif /* all checks are OK */ if ( p_fs_dev != NULL ) *p_fs_dev = pathstat.st_dev; endmntent( fp ); return 0; } /* CheckFSInfo */