📄 fusermount.c
字号:
/* FUSE: Filesystem in Userspace Copyright (C) 2001-2007 Miklos Szeredi <miklos@szeredi.hu> This program can be distributed under the terms of the GNU GPL. See the file COPYING.*//* This program does the mounting and unmounting of FUSE filesystems */#include <config.h>#include "mount_util.h"#include <stdio.h>#include <stdlib.h>#include <string.h>#include <ctype.h>#include <unistd.h>#include <getopt.h>#include <errno.h>#include <fcntl.h>#include <pwd.h>#include <mntent.h>#include <sys/wait.h>#include <sys/stat.h>#include <sys/mount.h>#include <sys/fsuid.h>#include <sys/socket.h>#include <sys/utsname.h>#include <grp.h>#define FUSE_DEV_NEW "/dev/fuse"#ifndef MS_DIRSYNC#define MS_DIRSYNC 128#endifstatic const char *progname = "ntfs-3g-mount";static int mount_max = 1000;int drop_privs(void);int restore_privs(void);static const char *get_user_name(void){ struct passwd *pw = getpwuid(getuid()); if (pw != NULL && pw->pw_name != NULL) return pw->pw_name; else { fprintf(stderr, "%s: could not determine username\n", progname); return NULL; }}int drop_privs(void){ if (!getegid()) { gid_t new_gid = getgid(); if (setresgid(-1, new_gid, getegid()) < 0) { perror("priv drop: setresgid failed"); return -1; } if (getegid() != new_gid){ perror("dropping group privilege failed"); return -1; } } if (!geteuid()) { uid_t new_uid = getuid(); if (setresuid(-1, new_uid, geteuid()) < 0) { perror("priv drop: setresuid failed"); return -1; } if (geteuid() != new_uid){ perror("dropping user privilege failed"); return -1; } } return 0;}int restore_privs(void){ if (geteuid()) { uid_t ruid, euid, suid; if (getresuid(&ruid, &euid, &suid) < 0) { perror("priv restore: getresuid failed"); return -1; } if (setresuid(-1, suid, -1) < 0) { perror("priv restore: setresuid failed"); return -1; } if (geteuid() != suid) { perror("restoring privilege failed"); return -1; } } if (getegid()) { gid_t rgid, egid, sgid; if (getresgid(&rgid, &egid, &sgid) < 0) { perror("priv restore: getresgid failed"); return -1; } if (setresgid(-1, sgid, -1) < 0) { perror("priv restore: setresgid failed"); return -1; } if (getegid() != sgid){ perror("restoring group privilege failed"); return -1; } } return 0;}#ifndef IGNORE_MTABstatic int add_mount(const char *source, const char *mnt, const char *type, const char *opts){ return fuse_mnt_add_mount(progname, source, mnt, type, opts);}static int count_fuse_fs(void){ struct mntent *entp; int count = 0; const char *mtab = _PATH_MOUNTED; FILE *fp = setmntent(mtab, "r"); if (fp == NULL) { fprintf(stderr, "%s: failed to open %s: %s\n", progname, mtab, strerror(errno)); return -1; } while ((entp = getmntent(fp)) != NULL) { if (strcmp(entp->mnt_type, "fuse") == 0 || strncmp(entp->mnt_type, "fuse.", 5) == 0) count ++; } endmntent(fp); return count;}#else /* IGNORE_MTAB */static int count_fuse_fs(){ return 0;}static int add_mount(const char *source, const char *mnt, const char *type, const char *opts){ (void) source; (void) mnt; (void) type; (void) opts; return 0;}#endif /* IGNORE_MTAB */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 get_string_opt(const char *s, unsigned len, const char *opt, char **val){ unsigned opt_len = strlen(opt); if (*val) free(*val); *val = (char *) malloc(len - opt_len + 1); if (!*val) { fprintf(stderr, "%s: failed to allocate memory\n", progname); return 0; } memcpy(*val, s + opt_len, len - opt_len); (*val)[len - opt_len] = '\0'; return 1;}static int do_mount(const char *mnt, char **typep, mode_t rootmode, int fd, const char *opts, const char *dev, char **sourcep, char **mnt_optsp){ int res; int flags = MS_NOSUID | MS_NODEV; char *optbuf; char *mnt_opts = NULL; const char *s; char *d; char *fsname = NULL; char *source = NULL; char *type = NULL; 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)) { if (!get_string_opt(s, len, fsname_str, &fsname)) goto err; } else if (opt_eq(s, len, "blkdev")) { blkdev = 1; } else if (!begins_with(s, "fd=") && !begins_with(s, "rootmode=") &&
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -