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)) {