11 #include "fuse_config.h" 
   12 #include "mount_util.h" 
   24 #if !defined( __NetBSD__) && !defined(__FreeBSD__) && !defined(__DragonFly__) 
   32 #include "fuse_mount_compat.h" 
   34 #include <sys/param.h> 
   36 #if defined(__NetBSD__) || defined(__FreeBSD__) || defined(__DragonFly__) || defined(__FreeBSD_kernel__) 
   37 #define umount2(mnt, flags) unmount(mnt, ((flags) == 2) ? MNT_FORCE : 0) 
   41 #define mtab_needs_update(mnt) 0 
   43 static int mtab_needs_update(
const char *mnt)
 
   49         if (strncmp(mnt, _PATH_MOUNTED, strlen(mnt)) == 0 &&
 
   50             _PATH_MOUNTED[strlen(mnt)] == 
'/')
 
   60         res = lstat(_PATH_MOUNTED, &stbuf);
 
   68                 if (S_ISLNK(stbuf.st_mode))
 
   75                 res = access(_PATH_MOUNTED, W_OK);
 
   76                 err = (res == -1) ? errno : 0;
 
   88 static int add_mount(
const char *progname, 
const char *fsname,
 
   89                        const char *mnt, 
const char *type, 
const char *opts)
 
   96         sigemptyset(&blockmask);
 
   97         sigaddset(&blockmask, SIGCHLD);
 
   98         res = sigprocmask(SIG_BLOCK, &blockmask, &oldmask);
 
  100                 fprintf(stderr, 
"%s: sigprocmask: %s\n", progname, strerror(errno));
 
  106                 fprintf(stderr, 
"%s: fork: %s\n", progname, strerror(errno));
 
  112                 sigprocmask(SIG_SETMASK, &oldmask, NULL);
 
  114                 if(setuid(geteuid()) == -1) {
 
  115                         fprintf(stderr, 
"%s: setuid: %s\n", progname, strerror(errno));
 
  120                 execle(
"/bin/mount", 
"/bin/mount", 
"--no-canonicalize", 
"-i",
 
  121                        "-f", 
"-t", type, 
"-o", opts, fsname, mnt, NULL, &env);
 
  122                 fprintf(stderr, 
"%s: failed to execute /bin/mount: %s\n",
 
  123                         progname, strerror(errno));
 
  126         res = waitpid(res, &status, 0);
 
  128                 fprintf(stderr, 
"%s: waitpid: %s\n", progname, strerror(errno));
 
  134         sigprocmask(SIG_SETMASK, &oldmask, NULL);
 
  139 int fuse_mnt_add_mount(
const char *progname, 
const char *fsname,
 
  140                        const char *mnt, 
const char *type, 
const char *opts)
 
  142         if (!mtab_needs_update(mnt))
 
  145         return add_mount(progname, fsname, mnt, type, opts);
 
  148 static int exec_umount(
const char *progname, 
const char *rel_mnt, 
int lazy)
 
  155         sigemptyset(&blockmask);
 
  156         sigaddset(&blockmask, SIGCHLD);
 
  157         res = sigprocmask(SIG_BLOCK, &blockmask, &oldmask);
 
  159                 fprintf(stderr, 
"%s: sigprocmask: %s\n", progname, strerror(errno));
 
  165                 fprintf(stderr, 
"%s: fork: %s\n", progname, strerror(errno));
 
  171                 sigprocmask(SIG_SETMASK, &oldmask, NULL);
 
  173                 if(setuid(geteuid()) == -1) {
 
  174                         fprintf(stderr, 
"%s: setuid: %s\n", progname, strerror(errno));
 
  180                         execle(
"/bin/umount", 
"/bin/umount", 
"-i", rel_mnt,
 
  183                         execle(
"/bin/umount", 
"/bin/umount", 
"-i", rel_mnt,
 
  186                 fprintf(stderr, 
"%s: failed to execute /bin/umount: %s\n",
 
  187                         progname, strerror(errno));
 
  190         res = waitpid(res, &status, 0);
 
  192                 fprintf(stderr, 
"%s: waitpid: %s\n", progname, strerror(errno));
 
  199         sigprocmask(SIG_SETMASK, &oldmask, NULL);
 
  204 int fuse_mnt_umount(
const char *progname, 
const char *abs_mnt,
 
  205                     const char *rel_mnt, 
int lazy)
 
  209         if (!mtab_needs_update(abs_mnt)) {
 
  210                 res = umount2(rel_mnt, lazy ? 2 : 0);
 
  212                         fprintf(stderr, 
"%s: failed to unmount %s: %s\n",
 
  213                                 progname, abs_mnt, strerror(errno));
 
  217         return exec_umount(progname, rel_mnt, lazy);
 
  220 static int remove_mount(
const char *progname, 
const char *mnt)
 
  227         sigemptyset(&blockmask);
 
  228         sigaddset(&blockmask, SIGCHLD);
 
  229         res = sigprocmask(SIG_BLOCK, &blockmask, &oldmask);
 
  231                 fprintf(stderr, 
"%s: sigprocmask: %s\n", progname, strerror(errno));
 
  237                 fprintf(stderr, 
"%s: fork: %s\n", progname, strerror(errno));
 
  243                 sigprocmask(SIG_SETMASK, &oldmask, NULL);
 
  245                 if(setuid(geteuid()) == -1) {
 
  246                         fprintf(stderr, 
"%s: setuid: %s\n", progname, strerror(errno));
 
  251                 execle(
"/bin/umount", 
"/bin/umount", 
"--no-canonicalize", 
"-i",
 
  252                        "--fake", mnt, NULL, &env);
 
  253                 fprintf(stderr, 
"%s: failed to execute /bin/umount: %s\n",
 
  254                         progname, strerror(errno));
 
  257         res = waitpid(res, &status, 0);
 
  259                 fprintf(stderr, 
"%s: waitpid: %s\n", progname, strerror(errno));
 
  265         sigprocmask(SIG_SETMASK, &oldmask, NULL);
 
  269 int fuse_mnt_remove_mount(
const char *progname, 
const char *mnt)
 
  271         if (!mtab_needs_update(mnt))
 
  274         return remove_mount(progname, mnt);
 
  277 char *fuse_mnt_resolve_path(
const char *progname, 
const char *orig)
 
  284         const char *toresolv;
 
  287                 fprintf(stderr, 
"%s: invalid mountpoint '%s'\n", progname,
 
  294                 fprintf(stderr, 
"%s: failed to allocate memory\n", progname);
 
  300         for (end = copy + strlen(copy) - 1; end > copy && *end == 
'/'; end --);
 
  304                 tmp = strrchr(copy, 
'/');
 
  313                 if (strcmp(lastcomp, 
".") == 0 || strcmp(lastcomp, 
"..") == 0) {
 
  320         if (realpath(toresolv, buf) == NULL) {
 
  321                 fprintf(stderr, 
"%s: bad mount point %s: %s\n", progname, orig,
 
  326         if (lastcomp == NULL)
 
  329                 dst = (
char *) malloc(strlen(buf) + 1 + strlen(lastcomp) + 1);
 
  331                         unsigned buflen = strlen(buf);
 
  332                         if (buflen && buf[buflen-1] == 
'/')
 
  333                                 sprintf(dst, 
"%s%s", buf, lastcomp);
 
  335                                 sprintf(dst, 
"%s/%s", buf, lastcomp);
 
  340                 fprintf(stderr, 
"%s: failed to allocate memory\n", progname);
 
  344 int fuse_mnt_check_fuseblk(
void)
 
  347         FILE *f = fopen(
"/proc/filesystems", 
"r");
 
  351         while (fgets(buf, 
sizeof(buf), f))
 
  352                 if (strstr(buf, 
"fuseblk\n")) {
 
  361 int fuse_mnt_parse_fuse_fd(
const char *mountpoint)
 
  366         if (sscanf(mountpoint, 
"/dev/fd/%u%n", &fd, &len) == 1 &&
 
  367             len == strlen(mountpoint)) {