17 static char *progname;
19 static char *xstrdup(
const char *s)
23 fprintf(stderr,
"%s: failed to allocate memory\n", progname);
29 static void *xrealloc(
void *oldptr,
size_t size)
31 void *ptr = realloc(oldptr, size);
33 fprintf(stderr,
"%s: failed to allocate memory\n", progname);
39 static void add_arg(
char **cmdp,
const char *opt)
41 size_t optlen = strlen(opt);
42 size_t cmdlen = *cmdp ? strlen(*cmdp) : 0;
43 char *cmd = xrealloc(*cmdp, cmdlen + optlen * 4 + 4);
64 static char *add_option(
const char *opt,
char *options)
66 int oldlen = options ? strlen(options) : 0;
68 options = xrealloc(options, oldlen + 1 + strlen(opt) + 1);
78 int main(
int argc,
char *argv[])
82 const char *mountpoint;
92 basename = strrchr(argv[0],
'/');
98 if (strncmp(basename,
"mount.fuse.", 11) == 0)
100 if (strncmp(basename,
"mount.fuseblk.", 14) == 0)
101 type = basename + 14;
103 if (type && !type[0])
108 "usage: %s %s destination [-t type] [-o opt[,opts...]]\n",
109 progname, type ?
"source" :
"type#[source]");
117 mountpoint = argv[2];
119 for (i = 3; i < argc; i++) {
120 if (strcmp(argv[i],
"-v") == 0) {
122 }
else if (strcmp(argv[i],
"-t") == 0) {
127 "%s: missing argument to option '-t'\n",
132 if (strncmp(type,
"fuse.", 5) == 0)
134 else if (strncmp(type,
"fuseblk.", 8) == 0)
139 "%s: empty type given as argument to option '-t'\n",
143 }
else if (strcmp(argv[i],
"-o") == 0) {
150 opts = xstrdup(argv[i]);
151 opt = strtok(opts,
",");
155 const char *ignore_opts[] = {
"",
164 if (strncmp(opt,
"setuid=", 7) == 0) {
165 setuid = xstrdup(opt + 7);
168 for (j = 0; ignore_opts[j]; j++)
169 if (strcmp(opt, ignore_opts[j]) == 0)
173 if (strcmp(opt,
"nodev") == 0)
175 else if (strcmp(opt,
"nosuid") == 0)
178 options = add_option(opt, options);
180 opt = strtok(NULL,
",");
186 options = add_option(
"dev", options);
188 options = add_option(
"suid", options);
192 type = xstrdup(source);
193 source = strchr(type,
'#');
197 fprintf(stderr,
"%s: empty filesystem type\n",
202 fprintf(stderr,
"%s: empty source\n", progname);
207 add_arg(&command, type);
209 add_arg(&command, source);
210 add_arg(&command, mountpoint);
212 add_arg(&command,
"-o");
213 add_arg(&command, options);
216 if (setuid && setuid[0]) {
217 char *sucommand = command;
219 add_arg(&command,
"su");
220 add_arg(&command,
"-");
221 add_arg(&command, setuid);
222 add_arg(&command,
"-c");
223 add_arg(&command, sucommand);
224 }
else if (!getenv(
"HOME")) {
226 setenv(
"HOME",
"/root", 0);
229 execl(
"/bin/sh",
"/bin/sh",
"-c", command, NULL);
230 fprintf(stderr,
"%s: failed to execute /bin/sh: %s\n", progname,