11#include "fuse_config.h" 
   12#include "mount_util.h" 
   24#if !defined( __NetBSD__) && !defined(__FreeBSD__) && !defined(__DragonFly__) 
   32#include "fuse_mount_compat.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 
   43static 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;
 
   88static 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);
 
  139int 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);
 
  148static 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);
 
  204int 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);
 
  220static 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);
 
  269int fuse_mnt_remove_mount(
const char *progname, 
const char *mnt)
 
  271        if (!mtab_needs_update(mnt))
 
  274        return remove_mount(progname, mnt);
 
  277char *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);
 
  344int 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")) {
 
  361int fuse_mnt_parse_fuse_fd(
const char *mountpoint)
 
  366        if (sscanf(mountpoint, 
"/dev/fd/%u%n", &fd, &len) == 1 &&
 
  367            len == strlen(mountpoint)) {