void
    parse(struct fuse_args &args,
          config::Config   &config)
    {

      fuse_opt_parse(&args,
                     &config,
                     NULL,
                     ::option_processor);

      set_fsname(args,config);

      config.updateReadStr();
    }
Beispiel #2
0
    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);
    }
Beispiel #3
0
/* 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 */