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