]> git.decadent.org.uk Git - nfs-utils.git/blobdiff - utils/mount/mount.c
Add support for quoted mount options
[nfs-utils.git] / utils / mount / mount.c
index 71a87375868322c3dacebf86f92b5a0cad16adb5..487c0a62bc20f5d7edf02a72334423c1ee30702a 100644 (file)
@@ -261,18 +261,30 @@ static void parse_opts (const char *options, int *flags, char **extra_opts)
 {
        if (options != NULL) {
                char *opts = xstrdup(options);
-               char *opt;
-               int len = strlen(opts) + 20;
+               char *opt, *p;
+               int len = strlen(opts);
+               int open_quote = 0;
 
                *extra_opts = xmalloc(len);
                **extra_opts = '\0';
 
-               for (opt = strtok(opts, ","); opt; opt = strtok(NULL, ","))
-                       parse_opt(opt, flags, *extra_opts, len);
-
+               for (p=opts, opt=NULL; p && *p; p++) {
+                       if (!opt)
+                               opt = p;                /* begin of the option item */
+                       if (*p == '"')
+                               open_quote ^= 1;        /* reverse the status */
+                       if (open_quote)
+                               continue;               /* still in a quoted block */
+                       if (*p == ',')
+                               *p = '\0';              /* terminate the option item */
+                       /* end of option item or last item */
+                       if (*p == '\0' || *(p+1) == '\0') {
+                               parse_opt(opt, flags, *extra_opts, len);
+                               opt = NULL;
+                       }
+               }
                free(opts);
        }
-
 }
 
 static void mount_error(char *node)
@@ -350,6 +362,7 @@ int main(int argc, char *argv[])
        spec = argv[1];
        mount_point = argv[2];
 
+       argv[2] = argv[0]; /* so that getopt error messages are correct */
        while ((c = getopt_long (argc - 2, argv + 2, "rt:vVwfno:hs",
                                longopts, NULL)) != -1) {
                switch (c) {
@@ -435,12 +448,18 @@ int main(int argc, char *argv[])
 
                if ((mc = getfsfile(mount_point)) == NULL ||
                    strcmp(mc->m.mnt_fsname, spec) != 0 ||
-                   strcmp(mc->m.mnt_type, (nfs_mount_vers == 4 ? "nfs4":"nfs")) != 0 || 
-                   strcmp(mc->m.mnt_opts, mount_opts) != 0) {
+                   strcmp(mc->m.mnt_type, (nfs_mount_vers == 4 ? "nfs4":"nfs")) != 0
+                   ) {
                        fprintf(stderr, "%s: permission died - no match for fstab\n",
                                progname);
                        exit(1);
                }
+               /* 'mount' munges the options from fstab before passing them
+                * to us, so it is non-trivial to test that we have the correct
+                * set of options and we don't want to trust what the user
+                * gave us, so just take whatever is in fstab
+                */
+               mount_opts = strdup(mc->m.mnt_opts);
                mounttype = 0;
        }
 
@@ -448,7 +467,7 @@ int main(int argc, char *argv[])
        if (mount_point == NULL ||
            mount_point[0] != '/') {
                fprintf(stderr, "%s: unknown mount point %s\n",
-                       progname, argv[2]);
+                       progname, mount_point ? : "");
                exit(1);
        }
        
@@ -478,7 +497,8 @@ int main(int argc, char *argv[])
        if (!fake) {
                mnt_err = do_mount_syscall(spec, mount_point,
                                           nfs_mount_vers == 4 ? "nfs4" : "nfs",
-                                          flags, mount_opts);
+                                          flags & ~(MS_USER|MS_USERS) ,
+                                          mount_opts);
 
                if (mnt_err) {
                        mount_error(mount_point);