⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mount_bsd.c

📁 Linux下fuse用户文件系统的的源代码
💻 C
字号:
/*    FUSE: Filesystem in Userspace    Copyright (C) 2005-2006 Csaba Henk <csaba.henk@creo.hu>    This program can be distributed under the terms of the GNU LGPL.    See the file COPYING.LIB.*/#include "fuse_i.h"#include "fuse_opt.h"#include <sys/stat.h>#include <sys/wait.h>#include <sys/sysctl.h>#include <stdio.h>#include <stdlib.h>#include <unistd.h>#include <stddef.h>#include <fcntl.h>#include <errno.h>#include <string.h>#include <paths.h>#define FUSERMOUNT_PROG         "mount_fusefs"#define FUSE_DEV_TRUNK          "/dev/fuse"enum {    KEY_ALLOW_ROOT,    KEY_RO,    KEY_HELP,    KEY_VERSION,    KEY_KERN};struct mount_opts {    int allow_other;    int allow_root;    int ishelp;    char *kernel_opts;};static const struct fuse_opt fuse_mount_opts[] = {    { "allow_other", offsetof(struct mount_opts, allow_other), 1 },    { "allow_root", offsetof(struct mount_opts, allow_root), 1 },    FUSE_OPT_KEY("allow_root",          KEY_ALLOW_ROOT),    FUSE_OPT_KEY("-r",                  KEY_RO),    FUSE_OPT_KEY("-h",                  KEY_HELP),    FUSE_OPT_KEY("--help",              KEY_HELP),    FUSE_OPT_KEY("-V",                  KEY_VERSION),    FUSE_OPT_KEY("--version",           KEY_VERSION),    /* standard FreeBSD mount options */    FUSE_OPT_KEY("dev",                 KEY_KERN),    FUSE_OPT_KEY("async",               KEY_KERN),    FUSE_OPT_KEY("atime",               KEY_KERN),    FUSE_OPT_KEY("dev",                 KEY_KERN),    FUSE_OPT_KEY("exec",                KEY_KERN),    FUSE_OPT_KEY("suid",                KEY_KERN),    FUSE_OPT_KEY("symfollow",           KEY_KERN),    FUSE_OPT_KEY("rdonly",              KEY_KERN),    FUSE_OPT_KEY("sync",                KEY_KERN),    FUSE_OPT_KEY("union",               KEY_KERN),    FUSE_OPT_KEY("userquota",           KEY_KERN),    FUSE_OPT_KEY("groupquota",          KEY_KERN),    FUSE_OPT_KEY("clusterr",            KEY_KERN),    FUSE_OPT_KEY("clusterw",            KEY_KERN),    FUSE_OPT_KEY("suiddir",             KEY_KERN),    FUSE_OPT_KEY("snapshot",            KEY_KERN),    FUSE_OPT_KEY("multilabel",          KEY_KERN),    FUSE_OPT_KEY("acls",                KEY_KERN),    FUSE_OPT_KEY("force",               KEY_KERN),    FUSE_OPT_KEY("update",              KEY_KERN),    FUSE_OPT_KEY("ro",                  KEY_KERN),    FUSE_OPT_KEY("rw",                  KEY_KERN),    FUSE_OPT_KEY("auto",                KEY_KERN),    /* options supported under both Linux and FBSD */    FUSE_OPT_KEY("allow_other",         KEY_KERN),    FUSE_OPT_KEY("default_permissions", KEY_KERN),    /* FBSD FUSE specific mount options */    FUSE_OPT_KEY("private",             KEY_KERN),    FUSE_OPT_KEY("neglect_shares",      KEY_KERN),    FUSE_OPT_KEY("push_symlinks_in",    KEY_KERN),    /* stock FBSD mountopt parsing routine lets anything be negated... */    FUSE_OPT_KEY("nodev",               KEY_KERN),    FUSE_OPT_KEY("noasync",             KEY_KERN),    FUSE_OPT_KEY("noatime",             KEY_KERN),    FUSE_OPT_KEY("nodev",               KEY_KERN),    FUSE_OPT_KEY("noexec",              KEY_KERN),    FUSE_OPT_KEY("nosuid",              KEY_KERN),    FUSE_OPT_KEY("nosymfollow",         KEY_KERN),    FUSE_OPT_KEY("nordonly",            KEY_KERN),    FUSE_OPT_KEY("nosync",              KEY_KERN),    FUSE_OPT_KEY("nounion",             KEY_KERN),    FUSE_OPT_KEY("nouserquota",         KEY_KERN),    FUSE_OPT_KEY("nogroupquota",        KEY_KERN),    FUSE_OPT_KEY("noclusterr",          KEY_KERN),    FUSE_OPT_KEY("noclusterw",          KEY_KERN),    FUSE_OPT_KEY("nosuiddir",           KEY_KERN),    FUSE_OPT_KEY("nosnapshot",          KEY_KERN),    FUSE_OPT_KEY("nomultilabel",        KEY_KERN),    FUSE_OPT_KEY("noacls",              KEY_KERN),    FUSE_OPT_KEY("noforce",             KEY_KERN),    FUSE_OPT_KEY("noupdate",            KEY_KERN),    FUSE_OPT_KEY("noro",                KEY_KERN),    FUSE_OPT_KEY("norw",                KEY_KERN),    FUSE_OPT_KEY("noauto",              KEY_KERN),    FUSE_OPT_KEY("noallow_other",       KEY_KERN),    FUSE_OPT_KEY("nodefault_permissions", KEY_KERN),    FUSE_OPT_KEY("noprivate",           KEY_KERN),    FUSE_OPT_KEY("noneglect_shares",    KEY_KERN),    FUSE_OPT_KEY("nopush_symlinks_in",  KEY_KERN),    /* Linux specific mount options, but let just the mount util handle them */    FUSE_OPT_KEY("fsname=",             KEY_KERN),    FUSE_OPT_KEY("nonempty",            KEY_KERN),    FUSE_OPT_KEY("large_read",          KEY_KERN),    FUSE_OPT_KEY("max_read=",           KEY_KERN),    FUSE_OPT_END};static void mount_help(void){    fprintf(stderr,            "    -o allow_root          allow access to root\n"            );    system(FUSERMOUNT_PROG " --help");    fputc('\n', stderr);}static void mount_version(void){    system(FUSERMOUNT_PROG " --version");}static int fuse_mount_opt_proc(void *data, const char *arg, int key,                               struct fuse_args *outargs){    struct mount_opts *mo = data;    switch (key) {    case KEY_ALLOW_ROOT:        if (fuse_opt_add_opt(&mo->kernel_opts, "allow_other") == -1 ||            fuse_opt_add_arg(outargs, "-oallow_root") == -1)            return -1;        return 0;    case KEY_RO:        arg = "ro";        /* fall through */    case KEY_KERN:        return fuse_opt_add_opt(&mo->kernel_opts, arg);    case KEY_HELP:        mount_help();        mo->ishelp = 1;        break;    case KEY_VERSION:        mount_version();        mo->ishelp = 1;        break;    }    return 1;}void fuse_unmount_compat22(const char *mountpoint){    char dev[128];    char *ssc, *umount_cmd;    FILE *sf;    int rv;    char *seekscript =    "exec 2>/dev/null; " /* error message is annoying in help output */    "/usr/bin/fstat " FUSE_DEV_TRUNK "* | "    "/usr/bin/awk 'BEGIN{ getline; if (! ($3 == \"PID\" && $10 == \"NAME\")) exit 1; }; "    "              { if ($3 == %d) print $10; }' | "    "/usr/bin/sort | "    "/usr/bin/uniq | "    "/usr/bin/awk '{ i += 1; if (i > 1){ exit 1; }; printf; }; END{ if (i == 0) exit 1; }'";    (void) mountpoint;    /*     * If we don't know the fd, we have to resort to the scripted solution --     * iterating over the fd-s is unpractical, as we don't know how many of     * open files we have. (This could be looked up in procfs -- however,     * that's optional on FBSD; or read out from the kmem --  however, that's     * bound to privileges (in fact, that's what happens when we call the     * setgid kmem fstat(1) utility).     */    asprintf(&ssc, seekscript, getpid());    errno = 0;    sf = popen(ssc, "r");    if (! sf)        return;    fgets(dev, sizeof(dev), sf);    rv = pclose(sf);    if (rv)        return;    asprintf(&umount_cmd, "/sbin/umount %s", dev);    system(umount_cmd);}void fuse_kern_unmount(const char *mountpoint, int fd){    char *ep, *umount_cmd, dev[128];    struct stat sbuf;    (void)mountpoint;    if (fstat(fd, &sbuf) == -1)        return;    devname_r(sbuf.st_rdev, S_IFCHR, dev, 128);    if (strncmp(dev, "fuse", 4))        return;    strtol(dev + 4, &ep, 10);    if (*ep != '\0')        return;    asprintf(&umount_cmd, "/sbin/umount " _PATH_DEV "%s", dev);    system(umount_cmd);}/* Check if kernel is doing init in background */static int init_backgrounded(void){    int ibg, len;    len = sizeof(ibg);    if (sysctlbyname("vfs.fuse.init_backgrounded", &ibg, &len, NULL, 0))        return 0;    return ibg;}static int fuse_mount_core(const char *mountpoint, const char *opts){    const char *mountprog = FUSERMOUNT_PROG;    int fd;    char *fdnam, *dev;    int pid;    fdnam = getenv("FUSE_DEV_FD");    if (fdnam) {        char *ep;        fd = strtol(fdnam, &ep, 10);        if (*ep != '\0') {            fprintf(stderr, "invalid value given in FUSE_DEV_FD\n");            return -1;        }        if (fd < 0)            return -1;        goto mount;    }    dev = getenv("FUSE_DEV_NAME");    if (! dev)	dev = FUSE_DEV_TRUNK;    if ((fd = open(dev, O_RDWR)) < 0) {        perror("fuse: failed to open fuse device");        return -1;    }mount:    if (getenv("FUSE_NO_MOUNT") || ! mountpoint)        goto out;    pid = fork();    if (pid == -1) {        perror("fuse: fork() failed");        close(fd);        return -1;    }    if (pid == 0) {        if (! init_backgrounded()) {            /*             * If init is not backgrounded, we have to call the mount util             * backgrounded, to avoid deadlock.             */            pid = fork();                if (pid == -1) {                perror("fuse: fork() failed");                close(fd);                exit(1);            }        }        if (pid == 0) {            const char *argv[32];            int a = 0;            if (! fdnam)                asprintf(&fdnam, "%d", fd);            argv[a++] = mountprog;            if (opts) {                argv[a++] = "-o";                argv[a++] = opts;            }            argv[a++] = fdnam;            argv[a++] = mountpoint;            argv[a++] = NULL;            execvp(mountprog, (char **) argv);            perror("fuse: failed to exec mount program");            exit(1);        }        exit(0);    }    waitpid(pid, NULL, 0);out:    return fd;}int fuse_kern_mount(const char *mountpoint, struct fuse_args *args){    struct mount_opts mo;    int res = -1;    memset(&mo, 0, sizeof(mo));    /* mount util should not try to spawn the daemon */    setenv("MOUNT_FUSEFS_SAFE", "1", 1);    /* to notify the mount util it's called from lib */    setenv("MOUNT_FUSEFS_CALL_BY_LIB", "1", 1);    if (args &&        fuse_opt_parse(args, &mo, fuse_mount_opts, fuse_mount_opt_proc) == -1)        return -1;    if (mo.allow_other && mo.allow_root) {        fprintf(stderr, "fuse: 'allow_other' and 'allow_root' options are mutually exclusive\n");        goto out;    }    if (mo.ishelp)        return 0;    res = fuse_mount_core(mountpoint, mo.kernel_opts); out:    free(mo.kernel_opts);    return res;}__asm__(".symver fuse_unmount_compat22,fuse_unmount@FUSE_2.2");

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -