11#include "fuse_config.h" 
   18#include "fuse_mount_compat.h" 
   29#define FUSERMOUNT_PROG         "mount_fusefs" 
   30#define FUSE_DEV_TRUNK          "/dev/fuse" 
   43#define FUSE_DUAL_OPT_KEY(templ, key)                           \ 
   44        FUSE_OPT_KEY(templ, key), FUSE_OPT_KEY("no" templ, key) 
   46static const struct fuse_opt fuse_mount_opts[] = {
 
   47        { 
"allow_other", offsetof(
struct mount_opts, allow_other), 1 },
 
   48        { 
"max_read=%u", offsetof(
struct mount_opts, max_read), 1 },
 
   51        FUSE_DUAL_OPT_KEY(
"dev",                KEY_KERN),
 
   52        FUSE_DUAL_OPT_KEY(
"async",              KEY_KERN),
 
   53        FUSE_DUAL_OPT_KEY(
"atime",              KEY_KERN),
 
   54        FUSE_DUAL_OPT_KEY(
"dev",                KEY_KERN),
 
   55        FUSE_DUAL_OPT_KEY(
"exec",               KEY_KERN),
 
   56        FUSE_DUAL_OPT_KEY(
"suid",               KEY_KERN),
 
   57        FUSE_DUAL_OPT_KEY(
"symfollow",          KEY_KERN),
 
   58        FUSE_DUAL_OPT_KEY(
"rdonly",             KEY_KERN),
 
   59        FUSE_DUAL_OPT_KEY(
"sync",               KEY_KERN),
 
   60        FUSE_DUAL_OPT_KEY(
"union",              KEY_KERN),
 
   61        FUSE_DUAL_OPT_KEY(
"userquota",          KEY_KERN),
 
   62        FUSE_DUAL_OPT_KEY(
"groupquota",         KEY_KERN),
 
   63        FUSE_DUAL_OPT_KEY(
"clusterr",           KEY_KERN),
 
   64        FUSE_DUAL_OPT_KEY(
"clusterw",           KEY_KERN),
 
   65        FUSE_DUAL_OPT_KEY(
"suiddir",            KEY_KERN),
 
   66        FUSE_DUAL_OPT_KEY(
"snapshot",           KEY_KERN),
 
   67        FUSE_DUAL_OPT_KEY(
"multilabel",         KEY_KERN),
 
   68        FUSE_DUAL_OPT_KEY(
"acls",               KEY_KERN),
 
   69        FUSE_DUAL_OPT_KEY(
"force",              KEY_KERN),
 
   70        FUSE_DUAL_OPT_KEY(
"update",             KEY_KERN),
 
   71        FUSE_DUAL_OPT_KEY(
"ro",                 KEY_KERN),
 
   72        FUSE_DUAL_OPT_KEY(
"rw",                 KEY_KERN),
 
   73        FUSE_DUAL_OPT_KEY(
"auto",               KEY_KERN),
 
   74        FUSE_DUAL_OPT_KEY(
"automounted",        KEY_KERN),
 
   76        FUSE_DUAL_OPT_KEY(
"allow_other",        KEY_KERN),
 
   77        FUSE_DUAL_OPT_KEY(
"default_permissions",KEY_KERN),
 
   81        FUSE_DUAL_OPT_KEY(
"private",            KEY_KERN),
 
   82        FUSE_DUAL_OPT_KEY(
"neglect_shares",     KEY_KERN),
 
   83        FUSE_DUAL_OPT_KEY(
"push_symlinks_in",   KEY_KERN),
 
   84#if __FreeBSD_version >= 1200519 
   85        FUSE_DUAL_OPT_KEY(
"intr",               KEY_KERN),
 
   96void fuse_mount_version(
void)
 
   98        system(FUSERMOUNT_PROG 
" --version");
 
  101unsigned get_max_read(
struct mount_opts *o)
 
  106static int fuse_mount_opt_proc(
void *data, 
const char *arg, 
int key,
 
  110        struct mount_opts *mo = data;
 
  125void fuse_kern_unmount(
const char *mountpoint, 
int fd)
 
  128                fuse_log(FUSE_LOG_ERR, 
"closing FD %d failed: %s", fd, strerror(errno));
 
  129        if (unmount(mountpoint, MNT_FORCE) < 0)
 
  130                fuse_log(FUSE_LOG_ERR, 
"unmounting %s failed: %s",
 
  131                        mountpoint, strerror(errno));
 
  134static int fuse_mount_core(
const char *mountpoint, 
const char *opts)
 
  136        const char *mountprog = FUSERMOUNT_PROG;
 
  143        fdnam = getenv(
"FUSE_DEV_FD");
 
  146                err = libfuse_strtol(fdnam, &fd);
 
  148                        fuse_log(FUSE_LOG_ERR, 
"invalid value given in FUSE_DEV_FD\n");
 
  155        dev = getenv(
"FUSE_DEV_NAME");
 
  158                dev = (
char *)FUSE_DEV_TRUNK;
 
  160        if ((fd = open(dev, O_RDWR)) < 0) {
 
  161                perror(
"fuse: failed to open fuse device");
 
  166        if (getenv(
"FUSE_NO_MOUNT") || ! mountpoint)
 
  173                perror(
"fuse: fork() failed");
 
  182                        perror(
"fuse: fork() failed");
 
  188                        const char *argv[32];
 
  194                                ret = asprintf(&fdnam, 
"%ld", fd);
 
  197                                        perror(
"fuse: failed to assemble mount arguments");
 
  203                        argv[a++] = mountprog;
 
  209                        argv[a++] = mountpoint;
 
  211                        execvp(mountprog, (
char **) argv);
 
  212                        perror(
"fuse: failed to exec mount program");
 
  220        if (waitpid(cpid, &status, 0) == -1 || WEXITSTATUS(status) != 0) {
 
  221                perror(
"fuse: failed to mount file system");
 
  223                        perror(
"fuse: closing FD");
 
  231struct mount_opts *parse_mount_opts(
struct fuse_args *args)
 
  233        struct mount_opts *mo;
 
  235        mo = (
struct mount_opts*) malloc(
sizeof(
struct mount_opts));
 
  239        memset(mo, 0, 
sizeof(
struct mount_opts));
 
  242            fuse_opt_parse(args, mo, fuse_mount_opts, fuse_mount_opt_proc) == -1)
 
  248        destroy_mount_opts(mo);
 
  252void destroy_mount_opts(
struct mount_opts *mo)
 
  254        free(mo->kernel_opts);
 
  258int fuse_kern_mount(
const char *mountpoint, 
struct mount_opts *mo)
 
  261        setenv(
"MOUNT_FUSEFS_SAFE", 
"1", 1);
 
  263        setenv(
"MOUNT_FUSEFS_CALL_BY_LIB", 
"1", 1);
 
  265        return fuse_mount_core(mountpoint, mo->kernel_opts);
 
void fuse_log(enum fuse_log_level level, const char *fmt,...)
#define FUSE_OPT_KEY(templ, key)
int fuse_opt_parse(struct fuse_args *args, void *data, const struct fuse_opt opts[], fuse_opt_proc_t proc)
int fuse_opt_add_opt(char **opts, const char *opt)