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

📄 fusermount.c

📁 file system in user space ! It s very good!
💻 C
📖 第 1 页 / 共 3 页
字号:
    else if(line[0])        fprintf(stderr, "%s: unknown parameter in %s at line %i: '%s'\n",                progname, FUSE_CONF, linenum, line);}static void read_conf(void){    FILE *fp = fopen(FUSE_CONF, "r");    if (fp != NULL) {        int linenum = 1;        char line[256];        int isnewline = 1;        while (fgets(line, sizeof(line), fp) != NULL) {            if (isnewline) {                if (line[strlen(line)-1] == '\n') {                    strip_line(line);                    parse_line(line, linenum);                } else {                    fprintf(stderr, "%s: reading %s: line %i too long\n",                            progname, FUSE_CONF, linenum);                    isnewline = 0;                }            } else if(line[strlen(line)-1] == '\n')                isnewline = 1;            if (isnewline)                linenum ++;        }        fclose(fp);    } else if (errno != ENOENT) {        fprintf(stderr, "%s: failed to open %s: %s\n", progname, FUSE_CONF,                strerror(errno));    }}static int begins_with(const char *s, const char *beg){    if (strncmp(s, beg, strlen(beg)) == 0)        return 1;    else        return 0;}struct mount_flags {    const char *opt;    unsigned long flag;    int on;    int safe;};static struct mount_flags mount_flags[] = {    {"rw",      MS_RDONLY,      0, 1},    {"ro",      MS_RDONLY,      1, 1},    {"suid",    MS_NOSUID,      0, 0},    {"nosuid",  MS_NOSUID,      1, 1},    {"dev",     MS_NODEV,       0, 0},    {"nodev",   MS_NODEV,       1, 1},    {"exec",    MS_NOEXEC,      0, 1},    {"noexec",  MS_NOEXEC,      1, 1},    {"async",   MS_SYNCHRONOUS, 0, 1},    {"sync",    MS_SYNCHRONOUS, 1, 1},    {"atime",   MS_NOATIME,     0, 1},    {"noatime", MS_NOATIME,     1, 1},    {"dirsync", MS_DIRSYNC,     1, 1},    {NULL,      0,              0, 0}};static int find_mount_flag(const char *s, unsigned len, int *on, int *flag){    int i;    for (i = 0; mount_flags[i].opt != NULL; i++) {        const char *opt = mount_flags[i].opt;        if (strlen(opt) == len && strncmp(opt, s, len) == 0) {            *on = mount_flags[i].on;            *flag = mount_flags[i].flag;            if (!mount_flags[i].safe && getuid() != 0) {                *flag = 0;                fprintf(stderr, "%s: unsafe option %s ignored\n",                        progname, opt);            }            return 1;        }    }    return 0;}static int add_option(char **optsp, const char *opt, unsigned expand){    char *newopts;    if (*optsp == NULL)        newopts = strdup(opt);    else {        unsigned oldsize = strlen(*optsp);        unsigned newsize = oldsize + 1 + strlen(opt) + expand + 1;        newopts = (char *) realloc(*optsp, newsize);        if (newopts)            sprintf(newopts + oldsize, ",%s", opt);    }    if (newopts == NULL) {        fprintf(stderr, "%s: failed to allocate memory\n", progname);        return -1;    }    *optsp = newopts;    return 0;}static int get_mnt_opts(int flags, char *opts, char **mnt_optsp){    int i;    int l;    if (!(flags & MS_RDONLY) && add_option(mnt_optsp, "rw", 0) == -1)        return -1;    for (i = 0; mount_flags[i].opt != NULL; i++) {        if (mount_flags[i].on && (flags & mount_flags[i].flag) &&            add_option(mnt_optsp, mount_flags[i].opt, 0) == -1)            return -1;    }    if (add_option(mnt_optsp, opts, 0) == -1)        return -1;    /* remove comma from end of opts*/    l = strlen(*mnt_optsp);    if ((*mnt_optsp)[l-1] == ',')        (*mnt_optsp)[l-1] = '\0';    if (getuid() != 0) {        const char *user = get_user_name();        if (user == NULL)            return -1;        if (add_option(mnt_optsp, "user=", strlen(user)) == -1)            return -1;        strcat(*mnt_optsp, user);    }    return 0;}static int opt_eq(const char *s, unsigned len, const char *opt){    if(strlen(opt) == len && strncmp(s, opt, len) == 0)        return 1;    else        return 0;}static int check_mountpoint_empty(const char *mnt, mode_t rootmode,                                  off_t rootsize){    int isempty = 1;    if (S_ISDIR(rootmode)) {        struct dirent *ent;        DIR *dp = opendir(mnt);        if (dp == NULL) {            fprintf(stderr, "%s: failed to open mountpoint for reading: %s\n",                    progname, strerror(errno));            return -1;        }        while ((ent = readdir(dp)) != NULL) {            if (strcmp(ent->d_name, ".") != 0 &&                strcmp(ent->d_name, "..") != 0) {                isempty = 0;                break;            }        }        closedir(dp);    } else if (rootsize)        isempty = 0;    if (!isempty) {        fprintf(stderr, "%s: mountpoint is not empty\n", progname);        fprintf(stderr, "%s: if you are sure this is safe, use the 'nonempty' mount option\n", progname);        return -1;    }    return 0;}static int has_fuseblk(void){    char buf[256];    FILE *f = fopen("/proc/filesystems", "r");    if (!f)        return 1;    while (fgets(buf, sizeof(buf), f))        if (strstr(buf, "fuseblk\n")) {            fclose(f);            return 1;        }    fclose(f);    return 0;}static int do_mount(const char *mnt, const char **type, mode_t rootmode,                    int fd, const char *opts, const char *dev, char **fsnamep,                    char **mnt_optsp, off_t rootsize){    int res;    int flags = MS_NOSUID | MS_NODEV;    char *optbuf;    char *mnt_opts = NULL;    const char *s;    char *d;    char *fsname = NULL;    int check_empty = 1;    int blkdev = 0;    optbuf = (char *) malloc(strlen(opts) + 128);    if (!optbuf) {        fprintf(stderr, "%s: failed to allocate memory\n", progname);        return -1;    }    for (s = opts, d = optbuf; *s;) {        unsigned len;        const char *fsname_str = "fsname=";        for (len = 0; s[len] && s[len] != ','; len++);        if (begins_with(s, fsname_str)) {            unsigned fsname_str_len = strlen(fsname_str);            if (fsname)                free(fsname);            fsname = (char *) malloc(len - fsname_str_len + 1);            if (!fsname) {                fprintf(stderr, "%s: failed to allocate memory\n", progname);                goto err;            }            memcpy(fsname, s + fsname_str_len, len - fsname_str_len);            fsname[len - fsname_str_len] = '\0';        } else if (opt_eq(s, len, "blkdev")) {            if (getuid() != 0) {                fprintf(stderr, "%s: option blkdev is privileged\n", progname);                goto err;            }            blkdev = 1;        } else if (opt_eq(s, len, "nonempty")) {            check_empty = 0;        } else if (!begins_with(s, "fd=") &&                   !begins_with(s, "rootmode=") &&                   !begins_with(s, "user_id=") &&                   !begins_with(s, "group_id=")) {            int on;            int flag;            int skip_option = 0;            if (opt_eq(s, len, "large_read")) {                struct utsname utsname;                unsigned kmaj, kmin;                res = uname(&utsname);                if (res == 0 &&                    sscanf(utsname.release, "%u.%u", &kmaj, &kmin) == 2 &&                    (kmaj > 2 || (kmaj == 2 && kmin > 4))) {                    fprintf(stderr, "%s: note: 'large_read' mount option is deprecated for %i.%i kernels\n", progname, kmaj, kmin);                    skip_option = 1;                }            }            if (getuid() != 0 && !user_allow_other &&                (opt_eq(s, len, "allow_other") ||                 opt_eq(s, len, "allow_root"))) {                fprintf(stderr, "%s: option %.*s only allowed if 'user_allow_other' is set in /etc/fuse.conf\n", progname, len, s);                goto err;            }            if (!skip_option) {                if (find_mount_flag(s, len, &on, &flag)) {                    if (on)                        flags |= flag;                    else                        flags  &= ~flag;                } else {                    memcpy(d, s, len);                    d += len;                    *d++ = ',';                }            }        }        s += len;        if (*s)            s++;    }    *d = '\0';    res = get_mnt_opts(flags, optbuf, &mnt_opts);    if (res == -1)        goto err;    sprintf(d, "fd=%i,rootmode=%o,user_id=%i,group_id=%i",            fd, rootmode, getuid(), getgid());    if (fsname == NULL) {        fsname = strdup(dev);        if (!fsname) {            fprintf(stderr, "%s: failed to allocate memory\n", progname);            goto err;        }    }    if (check_empty && check_mountpoint_empty(mnt, rootmode, rootsize) == -1)        goto err;    if (blkdev)        *type = "fuseblk";    res = mount(fsname, mnt, *type, flags, optbuf);    if (res == -1 && errno == EINVAL) {        /* It could be an old version not supporting group_id */        sprintf(d, "fd=%i,rootmode=%o,user_id=%i", fd, rootmode, getuid());        res = mount(fsname, mnt, *type, flags, optbuf);    }    if (res == -1) {        int errno_save = errno;        if (blkdev && errno == ENODEV && !has_fuseblk())            fprintf(stderr, "%s: 'fuseblk' support missing; try the kernel module from fuse-2.6.0 or later\n", progname);        else            fprintf(stderr, "%s: mount failed: %s\n", progname, strerror(errno_save));        goto err;    } else {        *fsnamep = fsname;        *mnt_optsp = mnt_opts;    }    free(optbuf);    return res; err:    free(fsname);    free(mnt_opts);    free(optbuf);    return -1;}static int check_version(const char *dev){    int res;    int majorver;    int minorver;    const char *version_file;    FILE *vf;    if (strcmp(dev, FUSE_DEV_OLD) != 0)        return 0;    version_file = FUSE_VERSION_FILE_OLD;    vf = fopen(version_file, "r");    if (vf == NULL) {        fprintf(stderr, "%s: kernel interface too old\n", progname);        return -1;    }    res = fscanf(vf, "%i.%i", &majorver, &minorver);    fclose(vf);    if (res != 2) {        fprintf(stderr, "%s: error reading %s\n", progname, version_file);        return -1;    }     if (majorver < 3) {        fprintf(stderr, "%s: kernel interface too old\n", progname);        return -1;    }    return 0;}static int check_perm(const char **mntp, struct stat *stbuf, int *currdir_fd,                      int *mountpoint_fd){    int res;    const char *mnt = *mntp;    const char *origmnt = mnt;    res = lstat(mnt, stbuf);    if (res == -1) {        fprintf(stderr, "%s: failed to access mountpoint %s: %s\n",                progname, mnt, strerror(errno));        return -1;    }    /* No permission checking is done for root */    if (getuid() == 0)        return 0;    if (S_ISDIR(stbuf->st_mode)) {        *currdir_fd = open(".", O_RDONLY);        if (*currdir_fd == -1) {            fprintf(stderr, "%s: failed to open current directory: %s\n",                    progname, strerror(errno));            return -1;        }        res = chdir(mnt);        if (res == -1) {            fprintf(stderr, "%s: failed to chdir to mountpoint: %s\n",                    progname, strerror(errno));            return -1;        }        mnt = *mntp = ".";        res = lstat(mnt, stbuf);        if (res == -1) {            fprintf(stderr, "%s: failed to access mountpoint %s: %s\n",                    progname, origmnt, strerror(errno));            return -1;        }        if ((stbuf->st_mode & S_ISVTX) && stbuf->st_uid != getuid()) {            fprintf(stderr, "%s: mountpoint %s not owned by user\n",                    progname, origmnt);

⌨️ 快捷键说明

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