~james-w/+junk/fuse-ubuntu-upstream

« back to all changes in this revision

Viewing changes to util/fusermount.c

  • Committer: James Westby
  • Date: 2008-05-16 12:58:06 UTC
  • Revision ID: jw+debian@jameswestby.net-20080516125806-ij1d8h7ihcwsv3ck
Tags: upstream-debian-2.5.1
Import upstream from fuse_2.5.1.orig.tar.gz

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
/*
2
2
    FUSE: Filesystem in Userspace
3
 
    Copyright (C) 2001-2005  Miklos Szeredi <miklos@szeredi.hu>
 
3
    Copyright (C) 2001-2006  Miklos Szeredi <miklos@szeredi.hu>
4
4
 
5
5
    This program can be distributed under the terms of the GNU GPL.
6
6
    See the file COPYING.
46
46
#define FUSE_VERSION_FILE_OLD "/proc/fs/fuse/version"
47
47
#define FUSE_CONF "/etc/fuse.conf"
48
48
 
 
49
#ifndef MS_DIRSYNC
 
50
#define MS_DIRSYNC 128
 
51
#endif
 
52
 
49
53
static const char *progname;
50
54
 
51
55
static int user_allow_other = 0;
120
124
    }
121
125
}
122
126
 
 
127
/* Glibc addmntent() doesn't encode '\n', misencodes '\t' as '\n'
 
128
   (version 2.3.2), and encodes '\\' differently as mount(8).  So
 
129
   let's not allow those characters, they are not all that usual in
 
130
   filenames. */
 
131
static int check_name(const char *name)
 
132
{
 
133
    char *s;
 
134
    for (s = "\n\t\\"; *s; s++) {
 
135
        if (strchr(name, *s)) {
 
136
            fprintf(stderr, "%s: illegal character 0x%02x in mount entry\n",
 
137
                    progname, *s);
 
138
            return -1;
 
139
        }
 
140
    }
 
141
    return 0;
 
142
}
 
143
 
123
144
static int add_mount(const char *fsname, const char *mnt, const char *type,
124
145
                     const char *opts)
125
146
{
128
149
    struct mntent ent;
129
150
    FILE *fp;
130
151
 
 
152
    if (check_name(fsname) == -1 || check_name(mnt) == -1 ||
 
153
        check_name(type) == -1 || check_name(opts) == -1)
 
154
        return -1;
 
155
 
131
156
    fp = setmntent(mtab, "a");
132
157
    if (fp == NULL) {
133
158
        fprintf(stderr, "%s: failed to open %s: %s\n", progname, mtab,
152
177
    return 0;
153
178
}
154
179
 
155
 
static int remove_mount(const char *mnt, int quiet, const char *mtab,
156
 
                        const char *mtab_new)
 
180
static int unmount_rename(const char *mtab, const char *mtab_new)
 
181
{
 
182
    int res;
 
183
    struct stat sbuf;
 
184
 
 
185
    if (stat(mtab, &sbuf) == 0)
 
186
        chown(mtab_new, sbuf.st_uid, sbuf.st_gid);
 
187
 
 
188
    res = rename(mtab_new, mtab);
 
189
    if (res == -1) {
 
190
        fprintf(stderr, "%s: failed to rename %s to %s: %s\n", progname,
 
191
                mtab_new, mtab, strerror(errno));
 
192
        return -1;
 
193
    }
 
194
    return 0;
 
195
}
 
196
 
 
197
static int unmount_fuse(const char *mnt, int quiet, int lazy)
157
198
{
158
199
    int res;
159
200
    struct mntent *entp;
160
201
    FILE *fp;
161
 
    FILE *newfp;
 
202
    FILE *newfp = NULL;
162
203
    const char *user = NULL;
163
204
    char uidstr[32];
164
205
    unsigned uidlen = 0;
165
206
    int found;
 
207
    int issymlink = 0;
 
208
    struct stat stbuf;
 
209
    const char *mtab = _PATH_MOUNTED;
 
210
    const char *mtab_new = _PATH_MOUNTED "~fuse~";
 
211
 
 
212
    if (lstat(mtab, &stbuf) != -1 && S_ISLNK(stbuf.st_mode))
 
213
        issymlink = 1;
166
214
 
167
215
    fp = setmntent(mtab, "r");
168
216
    if (fp == NULL) {
171
219
        return -1;
172
220
    }
173
221
 
174
 
    newfp = setmntent(mtab_new, "w");
175
 
    if (newfp == NULL) {
176
 
        fprintf(stderr, "%s: failed to open %s: %s\n", progname, mtab_new,
177
 
                strerror(errno));
178
 
        return -1;
 
222
    if (!issymlink) {
 
223
        newfp = setmntent(mtab_new, "w");
 
224
        if (newfp == NULL) {
 
225
            fprintf(stderr, "%s: failed to open %s: %s\n", progname, mtab_new,
 
226
                    strerror(errno));
 
227
            endmntent(fp);
 
228
            return -1;
 
229
        }
179
230
    }
180
231
 
181
232
    if (getuid() != 0) {
182
233
        user = get_user_name();
183
234
        if (user == NULL)
184
 
            return -1;
 
235
            goto err_endmntent;
185
236
 
186
237
        uidlen = sprintf(uidstr, "%u", getuid());
187
238
    }
208
259
        }
209
260
        if (removed)
210
261
            found = 1;
211
 
        else {
 
262
        else if (!issymlink) {
212
263
            res = addmntent(newfp, entp);
213
264
            if (res != 0) {
214
265
                fprintf(stderr, "%s: failed to add entry to %s: %s\n",
218
269
    }
219
270
 
220
271
    endmntent(fp);
221
 
    endmntent(newfp);
 
272
    if (!issymlink)
 
273
        endmntent(newfp);
222
274
 
223
275
    if (!found) {
224
276
        if (!quiet)
225
277
            fprintf(stderr, "%s: entry for %s not found in %s\n", progname,
226
278
                    mnt, mtab);
 
279
        goto err;
 
280
    }
 
281
 
 
282
    drop_privs();
 
283
    res = do_unmount(mnt, quiet, lazy);
 
284
    restore_privs();
 
285
    if (res == -1)
 
286
        goto err;
 
287
 
 
288
    if (!issymlink) {
 
289
        res = unmount_rename(mtab, mtab_new);
 
290
        if (res == -1)
 
291
            goto err;
 
292
    }
 
293
    return 0;
 
294
 
 
295
 err_endmntent:
 
296
    if (!issymlink)
 
297
        endmntent(newfp);
 
298
    endmntent(fp);
 
299
 err:
 
300
    if (!issymlink)
227
301
        unlink(mtab_new);
228
 
        return -1;
229
 
    }
230
 
 
231
 
    return 0;
 
302
    return -1;
232
303
}
233
304
 
234
305
static int count_fuse_fs(void)
250
321
    return count;
251
322
}
252
323
 
253
 
static int unmount_rename(const char *mnt, int quiet, int lazy,
254
 
                          const char *mtab, const char *mtab_new)
255
 
{
256
 
    int res;
257
 
    struct stat sbuf;
258
 
 
259
 
    drop_privs();
260
 
    res = do_unmount(mnt, quiet, lazy);
261
 
    restore_privs();
262
 
    if (res == -1)
263
 
        return -1;
264
 
 
265
 
    if (stat(mtab, &sbuf) == 0)
266
 
        chown(mtab_new, sbuf.st_uid, sbuf.st_gid);
267
 
 
268
 
    res = rename(mtab_new, mtab);
269
 
    if (res == -1) {
270
 
        fprintf(stderr, "%s: failed to rename %s to %s: %s\n", progname,
271
 
                mtab_new, mtab, strerror(errno));
272
 
        return -1;
273
 
    }
274
 
    return 0;
275
 
}
276
 
 
277
 
static int unmount_fuse(const char *mnt, int quiet, int lazy)
278
 
{
279
 
    int res;
280
 
    const char *mtab = _PATH_MOUNTED;
281
 
    const char *mtab_new = _PATH_MOUNTED "~fuse~";
282
 
 
283
 
    res = remove_mount(mnt, quiet, mtab, mtab_new);
284
 
    if (res == -1)
285
 
        return -1;
286
 
 
287
 
    res = unmount_rename(mnt, quiet, lazy, mtab, mtab_new);
288
 
    if (res == -1) {
289
 
        unlink(mtab_new);
290
 
        return -1;
291
 
    }
292
 
    return 0;
293
 
}
 
324
 
294
325
#else /* IGNORE_MTAB */
295
326
static int lock_mtab()
296
327
{
404
435
    {"sync",    MS_SYNCHRONOUS, 1, 1},
405
436
    {"atime",   MS_NOATIME,     0, 1},
406
437
    {"noatime", MS_NOATIME,     1, 1},
 
438
    {"dirsync", MS_DIRSYNC,     1, 1},
407
439
    {NULL,      0,              0, 0}
408
440
};
409
441
 
991
1023
            "%s: [options] mountpoint\n"
992
1024
            "Options:\n"
993
1025
            " -h                print help\n"
994
 
            " -v                print version\n"
 
1026
            " -V                print version\n"
995
1027
            " -o opt[,opt...]   mount options\n"
996
1028
            " -u                unmount\n"
997
1029
            " -q                quiet\n"
1002
1034
 
1003
1035
static void show_version(void)
1004
1036
{
1005
 
    printf("%s\n", PACKAGE_STRING);
 
1037
    printf("fusermount version: %s\n", PACKAGE_VERSION);
1006
1038
    exit(0);
1007
1039
}
1008
1040
 
1025
1057
        {"lazy",    no_argument, NULL, 'z'},
1026
1058
        {"quiet",   no_argument, NULL, 'q'},
1027
1059
        {"help",    no_argument, NULL, 'h'},
1028
 
        {"version", no_argument, NULL, 'v'},
 
1060
        {"version", no_argument, NULL, 'V'},
1029
1061
        {0, 0, 0, 0}};
1030
1062
 
1031
1063
    progname = strdup(argv[0]);
1034
1066
        exit(1);
1035
1067
    }
1036
1068
 
1037
 
    while ((ch = getopt_long(argc, argv, "hvo:uzq", long_opts, NULL)) != -1) {
 
1069
    while ((ch = getopt_long(argc, argv, "hVo:uzq", long_opts, NULL)) != -1) {
1038
1070
        switch (ch) {
1039
1071
        case 'h':
1040
1072
            usage();
1041
1073
            break;
1042
1074
 
1043
 
        case 'v':
 
1075
        case 'V':
1044
1076
            show_version();
1045
1077
            break;
1046
1078