17#include "fuse_mount_compat.h" 
   21#include <sys/sysctl.h> 
   33#define FUSERMOUNT_PROG         "mount_fusefs" 
   34#define FUSE_DEV_TRUNK          "/dev/fuse" 
   47#define FUSE_DUAL_OPT_KEY(templ, key)                           \ 
   48        FUSE_OPT_KEY(templ, key), FUSE_OPT_KEY("no" templ, key)
 
   50static const struct fuse_opt fuse_mount_opts[] = {
 
   51        { 
"allow_other", offsetof(
struct mount_opts, allow_other), 1 },
 
   52        { 
"max_read=%u", offsetof(
struct mount_opts, max_read), 1 },
 
   55        FUSE_DUAL_OPT_KEY(
"dev",                KEY_KERN),
 
   56        FUSE_DUAL_OPT_KEY(
"async",              KEY_KERN),
 
   57        FUSE_DUAL_OPT_KEY(
"atime",              KEY_KERN),
 
   58        FUSE_DUAL_OPT_KEY(
"dev",                KEY_KERN),
 
   59        FUSE_DUAL_OPT_KEY(
"exec",               KEY_KERN),
 
   60        FUSE_DUAL_OPT_KEY(
"suid",               KEY_KERN),
 
   61        FUSE_DUAL_OPT_KEY(
"symfollow",          KEY_KERN),
 
   62        FUSE_DUAL_OPT_KEY(
"rdonly",             KEY_KERN),
 
   63        FUSE_DUAL_OPT_KEY(
"sync",               KEY_KERN),
 
   64        FUSE_DUAL_OPT_KEY(
"union",              KEY_KERN),
 
   65        FUSE_DUAL_OPT_KEY(
"userquota",          KEY_KERN),
 
   66        FUSE_DUAL_OPT_KEY(
"groupquota",         KEY_KERN),
 
   67        FUSE_DUAL_OPT_KEY(
"clusterr",           KEY_KERN),
 
   68        FUSE_DUAL_OPT_KEY(
"clusterw",           KEY_KERN),
 
   69        FUSE_DUAL_OPT_KEY(
"suiddir",            KEY_KERN),
 
   70        FUSE_DUAL_OPT_KEY(
"snapshot",           KEY_KERN),
 
   71        FUSE_DUAL_OPT_KEY(
"multilabel",         KEY_KERN),
 
   72        FUSE_DUAL_OPT_KEY(
"acls",               KEY_KERN),
 
   73        FUSE_DUAL_OPT_KEY(
"force",              KEY_KERN),
 
   74        FUSE_DUAL_OPT_KEY(
"update",             KEY_KERN),
 
   75        FUSE_DUAL_OPT_KEY(
"ro",                 KEY_KERN),
 
   76        FUSE_DUAL_OPT_KEY(
"rw",                 KEY_KERN),
 
   77        FUSE_DUAL_OPT_KEY(
"auto",               KEY_KERN),
 
   78        FUSE_DUAL_OPT_KEY(
"automounted",        KEY_KERN),
 
   80        FUSE_DUAL_OPT_KEY(
"allow_other",        KEY_KERN),
 
   81        FUSE_DUAL_OPT_KEY(
"default_permissions",KEY_KERN),
 
   85        FUSE_DUAL_OPT_KEY(
"private",            KEY_KERN),
 
   86        FUSE_DUAL_OPT_KEY(
"neglect_shares",     KEY_KERN),
 
   87        FUSE_DUAL_OPT_KEY(
"push_symlinks_in",   KEY_KERN),
 
   89#if __FreeBSD_version >= 1200519 
   90        FUSE_DUAL_OPT_KEY(
"intr",               KEY_KERN),
 
  101void fuse_mount_version(
void)
 
  103        system(FUSERMOUNT_PROG 
" --version");
 
  106unsigned get_max_read(
struct mount_opts *o)
 
  111static int fuse_mount_opt_proc(
void *data, 
const char *arg, 
int key,
 
  115        struct mount_opts *mo = data;
 
  130void fuse_kern_unmount(
const char *mountpoint, 
int fd)
 
  133        unmount(mountpoint, MNT_FORCE);
 
  137static int init_backgrounded(
void)
 
  144        if (sysctlbyname(
"vfs.fuse.init_backgrounded", &ibg, &len, NULL, 0))
 
  151static int fuse_mount_core(
const char *mountpoint, 
const char *opts)
 
  153        const char *mountprog = FUSERMOUNT_PROG;
 
  159        fdnam = getenv(
"FUSE_DEV_FD");
 
  164                fd = strtol(fdnam, &ep, 10);
 
  167                        fuse_log(FUSE_LOG_ERR, 
"invalid value given in FUSE_DEV_FD\n");
 
  177        dev = getenv(
"FUSE_DEV_NAME");
 
  180                dev = (
char *)FUSE_DEV_TRUNK;
 
  182        if ((fd = open(dev, O_RDWR)) < 0) {
 
  183                perror(
"fuse: failed to open fuse device");
 
  188        if (getenv(
"FUSE_NO_MOUNT") || ! mountpoint)
 
  195                perror(
"fuse: fork() failed");
 
  201                if (! init_backgrounded()) {
 
  211                                perror(
"fuse: fork() failed");
 
  218                        const char *argv[32];
 
  224                                ret = asprintf(&fdnam, 
"%d", fd); 
 
  227                                        perror(
"fuse: failed to assemble mount arguments");
 
  233                        argv[a++] = mountprog;
 
  239                        argv[a++] = mountpoint;
 
  241                        execvp(mountprog, (
char **) argv);
 
  242                        perror(
"fuse: failed to exec mount program");
 
  250        if (waitpid(cpid, &status, 0) == -1 || WEXITSTATUS(status) != 0) {
 
  251                perror(
"fuse: failed to mount file system");
 
  260struct mount_opts *parse_mount_opts(
struct fuse_args *args)
 
  262        struct mount_opts *mo;
 
  264        mo = (
struct mount_opts*) malloc(
sizeof(
struct mount_opts));
 
  268        memset(mo, 0, 
sizeof(
struct mount_opts));
 
  271            fuse_opt_parse(args, mo, fuse_mount_opts, fuse_mount_opt_proc) == -1)
 
  277        destroy_mount_opts(mo);
 
  281void destroy_mount_opts(
struct mount_opts *mo)
 
  283        free(mo->kernel_opts);
 
  287int fuse_kern_mount(
const char *mountpoint, 
struct mount_opts *mo)
 
  290        setenv(
"MOUNT_FUSEFS_SAFE", 
"1", 1);
 
  292        setenv(
"MOUNT_FUSEFS_CALL_BY_LIB", 
"1", 1);
 
  294        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)