"Fossies" - the Fresh Open Source Software Archive

Member "fuse-3.2.3/util/mount.fuse.c" (11 May 2018, 4744 Bytes) of package /linux/misc/fuse-3.2.3.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. See also the latest Fossies "Diffs" side-by-side code changes report for "mount.fuse.c": 3.2.2_vs_3.2.3.

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