~barry/ubuntu/maverick/fuse/bug-697792-m

« back to all changes in this revision

Viewing changes to util/mount.fuse.c

  • Committer: Bazaar Package Importer
  • Author(s): Colin Watson
  • Date: 2007-08-04 08:09:00 UTC
  • mfrom: (1.1.8 upstream)
  • Revision ID: james.westby@ubuntu.com-20070804080900-m1e9xpk5eitzmelg
Tags: 2.7.0-1ubuntu1
* Resynchronise with Debian (LP: #128292). Remaining changes:
  - Don't install the init script; install the udev rule and the module
    configuration file instead.
  - debian/45-fuse.rules: set /dev/fuse group to fuse.
  - debian/fuse-utils.modprobe: module configuration file that mounts the
    control filesystem when fuse is loaded and unmounts it when fuse is
    unloaded, along with checking that the control FS is mounting before
    unmounting it.
  - debian/fuse-utils.install: add the udev rule, the module configuration
    file, and ulockmgr_server.
  - Load fuse on install, and set it so it gets loaded on reboot.
  - Move fusermount and ulockmgr_server to /bin and associated libraries
    to /lib.
* Use dpkg-query to fetch conffile md5sums rather than parsing
  /var/lib/dpkg/status directly.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
#include <stdio.h>
 
2
#include <stdlib.h>
 
3
#include <string.h>
 
4
#include <unistd.h>
 
5
#include <errno.h>
 
6
 
 
7
static char *progname;
 
8
 
 
9
static char *xstrdup(const char *s)
 
10
{
 
11
    char *t = strdup(s);
 
12
    if (!t) {
 
13
        fprintf(stderr, "%s: failed to allocate memory\n", progname);
 
14
        exit(1);
 
15
    }
 
16
    return t;
 
17
}
 
18
 
 
19
static void *xrealloc(void *oldptr, size_t size)
 
20
{
 
21
    void *ptr = realloc(oldptr, size);
 
22
    if (!ptr) {
 
23
        fprintf(stderr, "%s: failed to allocate memory\n", progname);
 
24
        exit(1);
 
25
    }
 
26
    return ptr;
 
27
}
 
28
 
 
29
static void add_arg(char **cmdp, const char *opt)
 
30
{
 
31
    size_t optlen = strlen(opt);
 
32
    size_t cmdlen = *cmdp ? strlen(*cmdp) : 0;
 
33
    char *cmd = xrealloc(*cmdp, cmdlen + optlen * 4 + 4);
 
34
    char *s;
 
35
    s = cmd + cmdlen;
 
36
    if (*cmdp)
 
37
        *s++ = ' ';
 
38
 
 
39
    *s++ = '\'';
 
40
    for (; *opt; opt++) {
 
41
        if (*opt == '\'') {
 
42
            *s++ = '\'';
 
43
            *s++ = '\\';
 
44
            *s++ = '\'';
 
45
            *s++ = '\'';
 
46
        } else
 
47
            *s++ = *opt;
 
48
    }
 
49
    *s++ = '\'';
 
50
    *s = '\0';
 
51
    *cmdp = cmd;
 
52
}
 
53
 
 
54
int main(int argc, char *argv[])
 
55
{
 
56
    char *type = NULL;
 
57
    char *source;
 
58
    const char *mountpoint;
 
59
    char *basename;
 
60
    char *options = NULL;
 
61
    char *command = NULL;
 
62
    char *setuid = NULL;
 
63
    int i;
 
64
 
 
65
    progname = argv[0];
 
66
    basename = strrchr(argv[0], '/');
 
67
    if (basename)
 
68
        basename++;
 
69
    else
 
70
        basename = argv[0];
 
71
 
 
72
    if (strncmp(basename, "mount.fuse.", 11) == 0)
 
73
        type = basename + 11;
 
74
    if (strncmp(basename, "mount.fuseblk.", 14) == 0)
 
75
        type = basename + 14;
 
76
 
 
77
    if (type && !type[0])
 
78
        type = NULL;
 
79
 
 
80
    if (argc < 3) {
 
81
        fprintf(stderr, "usage: %s %s destination [-t type] [-o opt[,opts...]]\n",
 
82
                progname, type ? "source" : "type#[source]");
 
83
        exit(1);
 
84
    }
 
85
 
 
86
    source = argv[1];
 
87
    if (!source[0])
 
88
        source = NULL;
 
89
 
 
90
    mountpoint = argv[2];
 
91
 
 
92
    for (i = 3; i < argc; i++) {
 
93
        if (strcmp(argv[i], "-v") == 0) {
 
94
            continue;
 
95
        } else if (strcmp(argv[i], "-t") == 0) {
 
96
            i++;
 
97
 
 
98
            if (i == argc) {
 
99
                fprintf(stderr,
 
100
                        "%s: missing argument to option '-t'\n", progname);
 
101
                exit(1);
 
102
            }
 
103
            type = argv[i];
 
104
            if (strncmp(type, "fuse.", 5) == 0)
 
105
                type += 5;
 
106
            else if (strncmp(type, "fuseblk.", 8) == 0)
 
107
                type += 8;
 
108
 
 
109
            if (!type[0]) {
 
110
                fprintf(stderr,
 
111
                        "%s: empty type given as argument to option '-t'\n",
 
112
                        progname);
 
113
                exit(1);
 
114
            }
 
115
        } else  if (strcmp(argv[i], "-o") == 0) {
 
116
            char *opts;
 
117
            char *opt;
 
118
            i++;
 
119
            if (i == argc)
 
120
                break;
 
121
 
 
122
            opts = xstrdup(argv[i]);
 
123
            opt = strtok(opts, ",");
 
124
            while (opt) {
 
125
                int j;
 
126
                int ignore = 0;
 
127
                const char *ignore_opts[] = { "", "user", "nouser", "users",
 
128
                                              "auto", "noauto", "_netdev",
 
129
                                              NULL};
 
130
                if (strncmp(opt, "setuid=", 7) == 0) {
 
131
                    setuid = xstrdup(opt + 7);
 
132
                    ignore = 1;
 
133
                }
 
134
                for (j = 0; ignore_opts[j]; j++)
 
135
                    if (strcmp(opt, ignore_opts[j]) == 0)
 
136
                        ignore = 1;
 
137
 
 
138
                if (!ignore) {
 
139
                    int oldlen = options ? strlen(options) : 0;
 
140
                    options = xrealloc(options, oldlen + 1 + strlen(opt) + 1);
 
141
                    if (!oldlen)
 
142
                        strcpy(options, opt);
 
143
                    else {
 
144
                        strcat(options, ",");
 
145
                        strcat(options, opt);
 
146
                    }
 
147
                }
 
148
                opt = strtok(NULL, ",");
 
149
            }
 
150
        }
 
151
    }
 
152
 
 
153
    if (!type) {
 
154
        type = xstrdup(source);
 
155
        source = strchr(type, '#');
 
156
        if (source)
 
157
            *source++ = '\0';
 
158
 
 
159
        if (!type[0]) {
 
160
            fprintf(stderr, "%s: empty filesystem type\n", progname);
 
161
            exit(1);
 
162
        }
 
163
    }
 
164
 
 
165
    add_arg(&command, type);
 
166
    if (source)
 
167
        add_arg(&command, source);
 
168
    add_arg(&command, mountpoint);
 
169
    if (options) {
 
170
        add_arg(&command, "-o");
 
171
        add_arg(&command, options);
 
172
    }
 
173
 
 
174
    if (setuid && setuid[0]) {
 
175
        char *sucommand = command;
 
176
        command = NULL;
 
177
        add_arg(&command, "su");
 
178
        add_arg(&command, "-");
 
179
        add_arg(&command, setuid);
 
180
        add_arg(&command, "-c");
 
181
        add_arg(&command, sucommand);
 
182
    } else if (!getenv("HOME")) {
 
183
        /* Hack to make filesystems work in the boot environment */
 
184
        setenv("HOME", "/root", 0);
 
185
    }
 
186
 
 
187
    execl("/bin/sh", "/bin/sh", "-c", command, NULL);
 
188
    fprintf(stderr, "%s: failed to execute /bin/sh: %s\n", progname,
 
189
            strerror(errno));
 
190
    return 1;
 
191
}