92
static int do_unmount(const char *mnt, int quiet, int lazy)
94
int res = umount2(mnt, lazy ? 2 : 0);
97
fprintf(stderr, "%s: failed to unmount %s: %s\n",
98
progname, mnt, strerror(errno));
103
76
#ifndef IGNORE_MTAB
104
/* use a lock file so that multiple fusermount processes don't try and
105
modify the mtab file at once! */
106
static int lock_mtab(void)
108
const char *mtab_lock = _PATH_MOUNTED ".fuselock";
111
struct stat mtab_stat;
113
/* /etc/mtab could be a symlink to /proc/mounts */
114
if (!lstat(_PATH_MOUNTED, &mtab_stat)) {
115
if (S_ISLNK(mtab_stat.st_mode))
119
mtablock = open(mtab_lock, O_RDWR | O_CREAT, 0600);
121
res = lockf(mtablock, F_LOCK, 0);
123
fprintf(stderr, "%s: error getting lock", progname);
125
fprintf(stderr, "%s: unable to open fuse lock file\n", progname);
130
static void unlock_mtab(int mtablock)
133
lockf(mtablock, F_ULOCK, 0);
138
/* Glibc addmntent() doesn't encode '\n', misencodes '\t' as '\n'
139
(version 2.3.2), and encodes '\\' differently as mount(8). So
140
let's not allow those characters, they are not all that usual in
142
static int check_name(const char *name)
145
for (s = "\n\t\\"; *s; s++) {
146
if (strchr(name, *s)) {
147
fprintf(stderr, "%s: illegal character 0x%02x in mount entry\n",
155
static int add_mount(const char *fsname, const char *mnt, const char *type,
77
static int add_mount(const char *source, const char *mnt, const char *type,
159
const char *mtab = _PATH_MOUNTED;
163
if (check_name(fsname) == -1 || check_name(mnt) == -1 ||
164
check_name(type) == -1 || check_name(opts) == -1)
167
fp = setmntent(mtab, "a");
169
fprintf(stderr, "%s: failed to open %s: %s\n", progname, mtab,
174
ent.mnt_fsname = (char *) fsname;
175
ent.mnt_dir = (char *) mnt;
176
ent.mnt_type = (char *) type;
177
ent.mnt_opts = (char *) opts;
180
res = addmntent(fp, &ent);
182
fprintf(stderr, "%s: failed to add entry to %s: %s\n", progname,
183
mtab, strerror(errno));
191
static int unmount_rename(const char *mtab, const char *mtab_new)
196
if (stat(mtab, &sbuf) == 0)
197
chown(mtab_new, sbuf.st_uid, sbuf.st_gid);
199
#ifdef HAVE_LIBSELINUX
201
security_context_t filecon;
203
if (getfilecon(mtab, &filecon) > 0) {
204
setfilecon(mtab_new, filecon);
211
res = rename(mtab_new, mtab);
213
fprintf(stderr, "%s: failed to rename %s to %s: %s\n", progname,
214
mtab_new, mtab, strerror(errno));
80
return fuse_mnt_add_mount(progname, source, mnt, type, opts);
220
83
static int unmount_fuse(const char *mnt, int quiet, int lazy)
226
const char *user = NULL;
232
const char *mtab = _PATH_MOUNTED;
233
const char *mtab_new = _PATH_MOUNTED "~fuse~";
235
if (lstat(mtab, &stbuf) != -1 && S_ISLNK(stbuf.st_mode))
238
fp = setmntent(mtab, "r");
240
fprintf(stderr, "%s: failed to open %s: %s\n", progname, mtab,
246
newfp = setmntent(mtab_new, "w");
248
fprintf(stderr, "%s: failed to open %s: %s\n", progname, mtab_new,
255
85
if (getuid() != 0) {
88
const char *user = NULL;
92
const char *mtab = _PATH_MOUNTED;
256
94
user = get_user_name();
98
fp = setmntent(mtab, "r");
100
fprintf(stderr, "%s: failed to open %s: %s\n", progname, mtab,
260
105
uidlen = sprintf(uidstr, "%u", getuid());
264
while ((entp = getmntent(fp)) != NULL) {
266
if (!found && strcmp(entp->mnt_dir, mnt) == 0 &&
267
(strcmp(entp->mnt_type, "fuse") == 0 ||
268
strcmp(entp->mnt_type, "fuseblk") == 0)) {
108
while ((entp = getmntent(fp)) != NULL) {
109
if (!found && strcmp(entp->mnt_dir, mnt) == 0 &&
110
(strcmp(entp->mnt_type, "fuse") == 0 ||
111
strcmp(entp->mnt_type, "fuseblk") == 0 ||
112
strncmp(entp->mnt_type, "fuse.", 5) == 0 ||
113
strncmp(entp->mnt_type, "fuseblk.", 8) == 0)) {
272
114
char *p = strstr(entp->mnt_opts, "user=");
273
115
if (p && (p == entp->mnt_opts || *(p-1) == ',') &&
274
strcmp(p + 5, user) == 0)
116
strcmp(p + 5, user) == 0) {
276
120
/* /etc/mtab is a link pointing to /proc/mounts: */
277
121
else if ((p = strstr(entp->mnt_opts, "user_id=")) &&
278
122
(p == entp->mnt_opts || *(p-1) == ',') &&
279
123
strncmp(p + 8, uidstr, uidlen) == 0 &&
280
(*(p+8+uidlen) == ',' || *(p+8+uidlen) == '\0'))
286
else if (!issymlink) {
287
res = addmntent(newfp, entp);
289
fprintf(stderr, "%s: failed to add entry to %s: %s\n",
290
progname, mtab_new, strerror(errno));
301
fprintf(stderr, "%s: entry for %s not found in %s\n", progname,
307
res = do_unmount(mnt, quiet, lazy);
313
res = unmount_rename(mtab, mtab_new);
124
(*(p+8+uidlen) == ',' || *(p+8+uidlen) == '\0')) {
134
fprintf(stderr, "%s: entry for %s not found in %s\n", progname,
140
return fuse_mnt_umount(progname, mnt, lazy);
329
143
static int count_fuse_fs(void)
546
static int check_mountpoint_empty(const char *mnt, mode_t rootmode,
351
static int get_string_opt(const char *s, unsigned len, const char *opt,
551
if (S_ISDIR(rootmode)) {
553
DIR *dp = opendir(mnt);
555
fprintf(stderr, "%s: failed to open mountpoint for reading: %s\n",
556
progname, strerror(errno));
559
while ((ent = readdir(dp)) != NULL) {
560
if (strcmp(ent->d_name, ".") != 0 &&
561
strcmp(ent->d_name, "..") != 0) {
571
fprintf(stderr, "%s: mountpoint is not empty\n", progname);
572
fprintf(stderr, "%s: if you are sure this is safe, use the 'nonempty' mount option\n", progname);
354
unsigned opt_len = strlen(opt);
358
*val = (char *) malloc(len - opt_len + 1);
360
fprintf(stderr, "%s: failed to allocate memory\n", progname);
578
static int has_fuseblk(void)
581
FILE *f = fopen("/proc/filesystems", "r");
585
while (fgets(buf, sizeof(buf), f))
586
if (strstr(buf, "fuseblk\n")) {
595
static int do_mount(const char *mnt, const char **type, mode_t rootmode,
596
int fd, const char *opts, const char *dev, char **fsnamep,
364
memcpy(*val, s + opt_len, len - opt_len);
365
(*val)[len - opt_len] = '\0';
369
static int do_mount(const char *mnt, char **typep, mode_t rootmode,
370
int fd, const char *opts, const char *dev, char **sourcep,
597
371
char **mnt_optsp, off_t rootsize)
684
457
sprintf(d, "fd=%i,rootmode=%o,user_id=%i,group_id=%i",
685
458
fd, rootmode, getuid(), getgid());
686
if (fsname == NULL) {
687
fsname = strdup(dev);
689
fprintf(stderr, "%s: failed to allocate memory\n", progname);
461
fuse_mnt_check_empty(progname, mnt, rootmode, rootsize) == -1)
464
source = malloc((fsname ? strlen(fsname) : 0) +
465
(subtype ? strlen(subtype) : 0) + strlen(dev) + 32);
467
type = malloc((subtype ? strlen(subtype) : 0) + 32);
468
if (!type || !source) {
469
fprintf(stderr, "%s: failed to allocate memory\n", progname);
474
sprintf(type, "%s.%s", blkdev ? "fuseblk" : "fuse", subtype);
476
strcpy(type, blkdev ? "fuseblk" : "fuse");
479
strcpy(source, fsname);
481
strcpy(source, subtype ? subtype : dev);
483
res = mount(source, mnt, type, flags, optbuf);
484
if (res == -1 && errno == ENODEV && subtype) {
485
/* Probably missing subtype support */
486
strcpy(type, blkdev ? "fuseblk" : "fuse");
489
sprintf(source, "%s#%s", subtype, fsname);
491
strcpy(source, type);
494
res = mount(source, mnt, type, flags, optbuf);
694
if (check_empty && check_mountpoint_empty(mnt, rootmode, rootsize) == -1)
699
res = mount(fsname, mnt, *type, flags, optbuf);
700
496
if (res == -1 && errno == EINVAL) {
701
497
/* It could be an old version not supporting group_id */
702
498
sprintf(d, "fd=%i,rootmode=%o,user_id=%i", fd, rootmode, getuid());
703
res = mount(fsname, mnt, *type, flags, optbuf);
499
res = mount(source, mnt, type, flags, optbuf);
706
502
int errno_save = errno;
707
if (blkdev && errno == ENODEV && !has_fuseblk())
708
fprintf(stderr, "%s: 'fuseblk' support missing; try the kernel module from fuse-2.6.0 or later\n", progname);
503
if (blkdev && errno == ENODEV && !fuse_mnt_check_fuseblk())
504
fprintf(stderr, "%s: 'fuseblk' support missing\n", progname);
710
506
fprintf(stderr, "%s: mount failed: %s\n", progname, strerror(errno_save));
714
511
*mnt_optsp = mnt_opts;
967
static char *resolve_path(const char *orig)
974
const char *toresolv;
977
fprintf(stderr, "%s: invalid mountpoint '%s'\n", progname, orig);
983
fprintf(stderr, "%s: failed to allocate memory\n", progname);
989
for (end = copy + strlen(copy) - 1; end > copy && *end == '/'; end --);
993
tmp = strrchr(copy, '/');
1002
if (strcmp(lastcomp, ".") == 0 || strcmp(lastcomp, "..") == 0) {
1009
if (realpath(toresolv, buf) == NULL) {
1010
fprintf(stderr, "%s: bad mount point %s: %s\n", progname, orig,
1015
if (lastcomp == NULL)
1018
dst = (char *) malloc(strlen(buf) + 1 + strlen(lastcomp) + 1);
1020
unsigned buflen = strlen(buf);
1021
if (buflen && buf[buflen-1] == '/')
1022
sprintf(dst, "%s%s", buf, lastcomp);
1024
sprintf(dst, "%s/%s", buf, lastcomp);
1029
fprintf(stderr, "%s: failed to allocate memory\n", progname);
1033
761
static int send_fd(int sock_fd, int fd)