"Fossies" - the Fresh Open Source Software Archive

Member "fuse-3.2.1/util/mount.fuse.c" (14 Nov 2017, 4587 Bytes) of package /linux/misc/fuse-3.2.1.tar.xz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file.

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