11 #include "fuse_config.h" 
   12 #include "mount_util.h" 
   23 #if !defined( __NetBSD__) && !defined(__FreeBSD__) && !defined(__DragonFly__) 
   30 #include <sys/mount.h> 
   31 #include <sys/param.h> 
   33 #if defined(__NetBSD__) || defined(__FreeBSD__) || defined(__DragonFly__) || defined(__FreeBSD_kernel__) 
   34 #define umount2(mnt, flags) unmount(mnt, ((flags) == 2) ? MNT_FORCE : 0) 
   38 #define mtab_needs_update(mnt) 0 
   40 static int mtab_needs_update(
const char *mnt)
 
   46         if (strncmp(mnt, _PATH_MOUNTED, strlen(mnt)) == 0 &&
 
   47             _PATH_MOUNTED[strlen(mnt)] == 
'/')
 
   57         res = lstat(_PATH_MOUNTED, &stbuf);
 
   65                 if (S_ISLNK(stbuf.st_mode))
 
   72                 res = access(_PATH_MOUNTED, W_OK);
 
   73                 err = (res == -1) ? errno : 0;
 
   85 static int add_mount(
const char *progname, 
const char *fsname,
 
   86                        const char *mnt, 
const char *type, 
const char *opts)
 
   93         sigemptyset(&blockmask);
 
   94         sigaddset(&blockmask, SIGCHLD);
 
   95         res = sigprocmask(SIG_BLOCK, &blockmask, &oldmask);
 
   97                 fprintf(stderr, 
"%s: sigprocmask: %s\n", progname, strerror(errno));
 
  103                 fprintf(stderr, 
"%s: fork: %s\n", progname, strerror(errno));
 
  109                 sigprocmask(SIG_SETMASK, &oldmask, NULL);
 
  111                 if(setuid(geteuid()) == -1) {
 
  112                         fprintf(stderr, 
"%s: setuid: %s\n", progname, strerror(errno));
 
  117                 execle(
"/bin/mount", 
"/bin/mount", 
"--no-canonicalize", 
"-i",
 
  118                        "-f", 
"-t", type, 
"-o", opts, fsname, mnt, NULL, &env);
 
  119                 fprintf(stderr, 
"%s: failed to execute /bin/mount: %s\n",
 
  120                         progname, strerror(errno));
 
  123         res = waitpid(res, &status, 0);
 
  125                 fprintf(stderr, 
"%s: waitpid: %s\n", progname, strerror(errno));
 
  131         sigprocmask(SIG_SETMASK, &oldmask, NULL);
 
  136 int fuse_mnt_add_mount(
const char *progname, 
const char *fsname,
 
  137                        const char *mnt, 
const char *type, 
const char *opts)
 
  139         if (!mtab_needs_update(mnt))
 
  142         return add_mount(progname, fsname, mnt, type, opts);
 
  145 static int exec_umount(
const char *progname, 
const char *rel_mnt, 
int lazy)
 
  152         sigemptyset(&blockmask);
 
  153         sigaddset(&blockmask, SIGCHLD);
 
  154         res = sigprocmask(SIG_BLOCK, &blockmask, &oldmask);
 
  156                 fprintf(stderr, 
"%s: sigprocmask: %s\n", progname, strerror(errno));
 
  162                 fprintf(stderr, 
"%s: fork: %s\n", progname, strerror(errno));
 
  168                 sigprocmask(SIG_SETMASK, &oldmask, NULL);
 
  170                 if(setuid(geteuid()) == -1) {
 
  171                         fprintf(stderr, 
"%s: setuid: %s\n", progname, strerror(errno));
 
  177                         execle(
"/bin/umount", 
"/bin/umount", 
"-i", rel_mnt,
 
  180                         execle(
"/bin/umount", 
"/bin/umount", 
"-i", rel_mnt,
 
  183                 fprintf(stderr, 
"%s: failed to execute /bin/umount: %s\n",
 
  184                         progname, strerror(errno));
 
  187         res = waitpid(res, &status, 0);
 
  189                 fprintf(stderr, 
"%s: waitpid: %s\n", progname, strerror(errno));
 
  196         sigprocmask(SIG_SETMASK, &oldmask, NULL);
 
  201 int fuse_mnt_umount(
const char *progname, 
const char *abs_mnt,
 
  202                     const char *rel_mnt, 
int lazy)
 
  206         if (!mtab_needs_update(abs_mnt)) {
 
  207                 res = umount2(rel_mnt, lazy ? 2 : 0);
 
  209                         fprintf(stderr, 
"%s: failed to unmount %s: %s\n",
 
  210                                 progname, abs_mnt, strerror(errno));
 
  214         return exec_umount(progname, rel_mnt, lazy);
 
  217 static int remove_mount(
const char *progname, 
const char *mnt)
 
  224         sigemptyset(&blockmask);
 
  225         sigaddset(&blockmask, SIGCHLD);
 
  226         res = sigprocmask(SIG_BLOCK, &blockmask, &oldmask);
 
  228                 fprintf(stderr, 
"%s: sigprocmask: %s\n", progname, strerror(errno));
 
  234                 fprintf(stderr, 
"%s: fork: %s\n", progname, strerror(errno));
 
  240                 sigprocmask(SIG_SETMASK, &oldmask, NULL);
 
  242                 if(setuid(geteuid()) == -1) {
 
  243                         fprintf(stderr, 
"%s: setuid: %s\n", progname, strerror(errno));
 
  248                 execle(
"/bin/umount", 
"/bin/umount", 
"--no-canonicalize", 
"-i",
 
  249                        "--fake", mnt, NULL, &env);
 
  250                 fprintf(stderr, 
"%s: failed to execute /bin/umount: %s\n",
 
  251                         progname, strerror(errno));
 
  254         res = waitpid(res, &status, 0);
 
  256                 fprintf(stderr, 
"%s: waitpid: %s\n", progname, strerror(errno));
 
  262         sigprocmask(SIG_SETMASK, &oldmask, NULL);
 
  266 int fuse_mnt_remove_mount(
const char *progname, 
const char *mnt)
 
  268         if (!mtab_needs_update(mnt))
 
  271         return remove_mount(progname, mnt);
 
  274 char *fuse_mnt_resolve_path(
const char *progname, 
const char *orig)
 
  281         const char *toresolv;
 
  284                 fprintf(stderr, 
"%s: invalid mountpoint '%s'\n", progname,
 
  291                 fprintf(stderr, 
"%s: failed to allocate memory\n", progname);
 
  297         for (end = copy + strlen(copy) - 1; end > copy && *end == 
'/'; end --);
 
  301                 tmp = strrchr(copy, 
'/');
 
  310                 if (strcmp(lastcomp, 
".") == 0 || strcmp(lastcomp, 
"..") == 0) {
 
  317         if (realpath(toresolv, buf) == NULL) {
 
  318                 fprintf(stderr, 
"%s: bad mount point %s: %s\n", progname, orig,
 
  323         if (lastcomp == NULL)
 
  326                 dst = (
char *) malloc(strlen(buf) + 1 + strlen(lastcomp) + 1);
 
  328                         unsigned buflen = strlen(buf);
 
  329                         if (buflen && buf[buflen-1] == 
'/')
 
  330                                 sprintf(dst, 
"%s%s", buf, lastcomp);
 
  332                                 sprintf(dst, 
"%s/%s", buf, lastcomp);
 
  337                 fprintf(stderr, 
"%s: failed to allocate memory\n", progname);
 
  341 int fuse_mnt_check_fuseblk(
void)
 
  344         FILE *f = fopen(
"/proc/filesystems", 
"r");
 
  348         while (fgets(buf, 
sizeof(buf), f))
 
  349                 if (strstr(buf, 
"fuseblk\n")) {
 
  358 int fuse_mnt_parse_fuse_fd(
const char *mountpoint)
 
  363         if (sscanf(mountpoint, 
"/dev/fd/%u%n", &fd, &len) == 1 &&
 
  364             len == strlen(mountpoint)) {