18 static char *progname;
20 static char *xstrdup(
const char *s)
24 fprintf(stderr,
"%s: failed to allocate memory\n", progname);
30 static void *xrealloc(
void *oldptr,
size_t size)
32 void *ptr = realloc(oldptr, size);
34 fprintf(stderr,
"%s: failed to allocate memory\n", progname);
40 static void add_arg(
char **cmdp,
const char *opt)
42 size_t optlen = strlen(opt);
43 size_t cmdlen = *cmdp ? strlen(*cmdp) : 0;
44 if (optlen >= (SIZE_MAX - cmdlen - 4)/4) {
45 fprintf(stderr,
"%s: argument too long\n", progname);
48 char *cmd = xrealloc(*cmdp, cmdlen + optlen * 4 + 4);
69 static char *add_option(
const char *opt,
char *options)
71 int oldlen = options ? strlen(options) : 0;
73 options = xrealloc(options, oldlen + 1 + strlen(opt) + 1);
83 int main(
int argc,
char *argv[])
87 const char *mountpoint;
97 basename = strrchr(argv[0],
'/');
103 if (strncmp(basename,
"mount.fuse.", 11) == 0)
104 type = basename + 11;
105 if (strncmp(basename,
"mount.fuseblk.", 14) == 0)
106 type = basename + 14;
108 if (type && !type[0])
113 "usage: %s %s destination [-t type] [-o opt[,opts...]]\n",
114 progname, type ?
"source" :
"type#[source]");
122 mountpoint = argv[2];
124 for (i = 3; i < argc; i++) {
125 if (strcmp(argv[i],
"-v") == 0) {
127 }
else if (strcmp(argv[i],
"-t") == 0) {
132 "%s: missing argument to option '-t'\n",
137 if (strncmp(type,
"fuse.", 5) == 0)
139 else if (strncmp(type,
"fuseblk.", 8) == 0)
144 "%s: empty type given as argument to option '-t'\n",
148 }
else if (strcmp(argv[i],
"-o") == 0) {
155 opts = xstrdup(argv[i]);
156 opt = strtok(opts,
",");
160 const char *ignore_opts[] = {
"",
169 if (strncmp(opt,
"setuid=", 7) == 0) {
170 setuid = xstrdup(opt + 7);
173 for (j = 0; ignore_opts[j]; j++)
174 if (strcmp(opt, ignore_opts[j]) == 0)
178 if (strcmp(opt,
"nodev") == 0)
180 else if (strcmp(opt,
"nosuid") == 0)
183 options = add_option(opt, options);
185 opt = strtok(NULL,
",");
191 options = add_option(
"dev", options);
193 options = add_option(
"suid", options);
197 type = xstrdup(source);
198 source = strchr(type,
'#');
202 fprintf(stderr,
"%s: empty filesystem type\n",
207 fprintf(stderr,
"%s: empty source\n", progname);
212 add_arg(&command, type);
214 add_arg(&command, source);
215 add_arg(&command, mountpoint);
217 add_arg(&command,
"-o");
218 add_arg(&command, options);
221 if (setuid && setuid[0]) {
222 char *sucommand = command;
224 add_arg(&command,
"su");
225 add_arg(&command,
"-");
226 add_arg(&command, setuid);
227 add_arg(&command,
"-c");
228 add_arg(&command, sucommand);
229 }
else if (!getenv(
"HOME")) {
231 setenv(
"HOME",
"/root", 0);
234 execl(
"/bin/sh",
"/bin/sh",
"-c", command, NULL);
235 fprintf(stderr,
"%s: failed to execute /bin/sh: %s\n", progname,