11#include "fuse_config.h" 
   12#include "mount_util.h" 
   24#if !defined( __NetBSD__) && !defined(__FreeBSD__) && !defined(__DragonFly__) && !defined(__ANDROID__) 
   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)] == 
'/')
 
   59        res = lstat(_PATH_MOUNTED, &stbuf);
 
   71                res = access(_PATH_MOUNTED, W_OK);
 
   72                err = (res == -1) ? errno : 0;
 
   84static int add_mount(
const char *progname, 
const char *fsname,
 
   85                       const char *mnt, 
const char *type, 
const char *opts)
 
   92        sigemptyset(&blockmask);
 
   93        sigaddset(&blockmask, SIGCHLD);
 
   94        res = sigprocmask(SIG_BLOCK, &blockmask, &oldmask);
 
   96                fprintf(stderr, 
"%s: sigprocmask: %s\n", progname, strerror(errno));
 
  102                fprintf(stderr, 
"%s: fork: %s\n", progname, strerror(errno));
 
  108                sigprocmask(SIG_SETMASK, &oldmask, NULL);
 
  110                if(setuid(geteuid()) == -1) {
 
  111                        fprintf(stderr, 
"%s: setuid: %s\n", progname, strerror(errno));
 
  116                execle(
"/bin/mount", 
"/bin/mount", 
"--no-canonicalize", 
"-i",
 
  117                       "-f", 
"-t", type, 
"-o", opts, fsname, mnt, NULL, &env);
 
  118                fprintf(stderr, 
"%s: failed to execute /bin/mount: %s\n",
 
  119                        progname, strerror(errno));
 
  122        res = waitpid(res, &status, 0);
 
  124                fprintf(stderr, 
"%s: waitpid: %s\n", progname, strerror(errno));
 
  130        sigprocmask(SIG_SETMASK, &oldmask, NULL);
 
  135int fuse_mnt_add_mount(
const char *progname, 
const char *fsname,
 
  136                       const char *mnt, 
const char *type, 
const char *opts)
 
  138        if (!mtab_needs_update(mnt))
 
  141        return add_mount(progname, fsname, mnt, type, opts);
 
  144static int exec_umount(
const char *progname, 
const char *rel_mnt, 
int lazy)
 
  151        sigemptyset(&blockmask);
 
  152        sigaddset(&blockmask, SIGCHLD);
 
  153        res = sigprocmask(SIG_BLOCK, &blockmask, &oldmask);
 
  155                fprintf(stderr, 
"%s: sigprocmask: %s\n", progname, strerror(errno));
 
  161                fprintf(stderr, 
"%s: fork: %s\n", progname, strerror(errno));
 
  167                sigprocmask(SIG_SETMASK, &oldmask, NULL);
 
  169                if(setuid(geteuid()) == -1) {
 
  170                        fprintf(stderr, 
"%s: setuid: %s\n", progname, strerror(errno));
 
  176                        execle(
"/bin/umount", 
"/bin/umount", 
"-i", rel_mnt,
 
  179                        execle(
"/bin/umount", 
"/bin/umount", 
"-i", rel_mnt,
 
  182                fprintf(stderr, 
"%s: failed to execute /bin/umount: %s\n",
 
  183                        progname, strerror(errno));
 
  186        res = waitpid(res, &status, 0);
 
  188                fprintf(stderr, 
"%s: waitpid: %s\n", progname, strerror(errno));
 
  195        sigprocmask(SIG_SETMASK, &oldmask, NULL);
 
  200int fuse_mnt_umount(
const char *progname, 
const char *abs_mnt,
 
  201                    const char *rel_mnt, 
int lazy)
 
  205        if (!mtab_needs_update(abs_mnt)) {
 
  206                res = umount2(rel_mnt, lazy ? 2 : 0);
 
  208                        fprintf(stderr, 
"%s: failed to unmount %s: %s\n",
 
  209                                progname, abs_mnt, strerror(errno));
 
  213        return exec_umount(progname, rel_mnt, lazy);
 
  216static int remove_mount(
const char *progname, 
const char *mnt)
 
  223        sigemptyset(&blockmask);
 
  224        sigaddset(&blockmask, SIGCHLD);
 
  225        res = sigprocmask(SIG_BLOCK, &blockmask, &oldmask);
 
  227                fprintf(stderr, 
"%s: sigprocmask: %s\n", progname, strerror(errno));
 
  233                fprintf(stderr, 
"%s: fork: %s\n", progname, strerror(errno));
 
  239                sigprocmask(SIG_SETMASK, &oldmask, NULL);
 
  241                if(setuid(geteuid()) == -1) {
 
  242                        fprintf(stderr, 
"%s: setuid: %s\n", progname, strerror(errno));
 
  247                execle(
"/bin/umount", 
"/bin/umount", 
"--no-canonicalize", 
"-i",
 
  248                       "--fake", mnt, NULL, &env);
 
  249                fprintf(stderr, 
"%s: failed to execute /bin/umount: %s\n",
 
  250                        progname, strerror(errno));
 
  253        res = waitpid(res, &status, 0);
 
  255                fprintf(stderr, 
"%s: waitpid: %s\n", progname, strerror(errno));
 
  261        sigprocmask(SIG_SETMASK, &oldmask, NULL);
 
  265int fuse_mnt_remove_mount(
const char *progname, 
const char *mnt)
 
  267        if (!mtab_needs_update(mnt))
 
  270        return remove_mount(progname, mnt);
 
  273char *fuse_mnt_resolve_path(
const char *progname, 
const char *orig)
 
  280        const char *toresolv;
 
  283                fprintf(stderr, 
"%s: invalid mountpoint '%s'\n", progname,
 
  290                fprintf(stderr, 
"%s: failed to allocate memory\n", progname);
 
  296        for (end = copy + strlen(copy) - 1; end > copy && *end == 
'/'; end --);
 
  300                tmp = strrchr(copy, 
'/');
 
  309                if (strcmp(lastcomp, 
".") == 0 || strcmp(lastcomp, 
"..") == 0) {
 
  316        if (realpath(toresolv, buf) == NULL) {
 
  317                fprintf(stderr, 
"%s: bad mount point %s: %s\n", progname, orig,
 
  322        if (lastcomp == NULL)
 
  325                dst = (
char *) malloc(strlen(buf) + 1 + strlen(lastcomp) + 1);
 
  327                        unsigned buflen = strlen(buf);
 
  328                        if (buflen && buf[buflen-1] == 
'/')
 
  329                                sprintf(dst, 
"%s%s", buf, lastcomp);
 
  331                                sprintf(dst, 
"%s/%s", buf, lastcomp);
 
  336                fprintf(stderr, 
"%s: failed to allocate memory\n", progname);
 
  340int fuse_mnt_check_fuseblk(
void)
 
  343        FILE *f = fopen(
"/proc/filesystems", 
"r");
 
  347        while (fgets(buf, 
sizeof(buf), f))
 
  348                if (strstr(buf, 
"fuseblk\n")) {
 
  357int fuse_mnt_parse_fuse_fd(
const char *mountpoint)
 
  362        if (mountpoint == NULL) {
 
  363                fprintf(stderr, 
"Invalid null-ptr mount-point!\n");
 
  367        if (sscanf(mountpoint, 
"/dev/fd/%u%n", &fd, &len) == 1 &&
 
  368            len == strlen(mountpoint)) {