mount: support -i; pass through -f and -n to helpers as necessary
authorDenys Vlasenko <vda.linux@googlemail.com>
Fri, 19 Jun 2009 09:48:29 +0000 (11:48 +0200)
committerDenys Vlasenko <vda.linux@googlemail.com>
Fri, 19 Jun 2009 09:48:29 +0000 (11:48 +0200)
function                                             old     new   delta
mount_it_now                                         298     345     +47
singlemount                                          776     772      -4

Signed-off-by: Colin Watson <cjwatson@ubuntu.com>
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
include/usage.h
util-linux/mount.c

index 0f6378e06711f92ab2fa26a9a60bfb1d4562fa72..c6006aa659567d6f99a82d24531d827715b9a205 100644 (file)
        IF_NOT_FEATURE_MTAB_SUPPORT( \
      "\n       -f              Dry run" \
        ) \
+       ) \
+       IF_FEATURE_MOUNT_HELPERS( \
+     "\n       -i              Don't run mount helper" \
        ) \
        IF_FEATURE_MTAB_SUPPORT( \
      "\n       -n              Don't update /etc/mtab" \
index ab249642b3c6ddcf702854f8bf032a6af2f6f8eb..72dabd8408f5a8666793ef703432aa93856b9128 100644 (file)
@@ -79,15 +79,21 @@ enum {
 };
 
 #if ENABLE_FEATURE_MTAB_SUPPORT
-#define useMtab (!(option_mask32 & OPT_n))
+#define USE_MTAB (!(option_mask32 & OPT_n))
 #else
-#define useMtab 0
+#define USE_MTAB 0
 #endif
 
 #if ENABLE_FEATURE_MOUNT_FAKE
-#define fakeIt (option_mask32 & OPT_f)
+#define FAKE_IT (option_mask32 & OPT_f)
 #else
-#define fakeIt 0
+#define FAKE_IT 0
+#endif
+
+#if ENABLE_FEATURE_MOUNT_HELPERS
+#define HELPERS_ALLOWED (!(option_mask32 & OPT_i))
+#else
+#define HELPERS_ALLOWED 0
 #endif
 
 
@@ -360,7 +366,7 @@ static llist_t *get_block_backed_filesystems(void)
                "/proc/filesystems",
        };
        char *fs, *buf;
-       llist_t *list = 0;
+       llist_t *list = NULL;
        int i;
        FILE *f;
 
@@ -369,10 +375,11 @@ static llist_t *get_block_backed_filesystems(void)
                if (!f) continue;
 
                while ((buf = xmalloc_fgetline(f)) != NULL) {
-                       if (!strncmp(buf, "nodev", 5) && isspace(buf[5]))
+                       if (strncmp(buf, "nodev", 5) == 0 && isspace(buf[5]))
                                continue;
                        fs = skip_whitespace(buf);
-                       if (*fs=='#' || *fs=='*' || !*fs) continue;
+                       if (*fs == '#' || *fs == '*' || !*fs)
+                               continue;
 
                        llist_add_to_end(&list, xstrdup(fs));
                        free(buf);
@@ -398,7 +405,7 @@ static int mount_it_now(struct mntent *mp, long vfsflags, char *filteropts)
 {
        int rc = 0;
 
-       if (fakeIt) {
+       if (FAKE_IT) {
                if (verbose >= 2)
                        bb_error_msg("would do mount('%s','%s','%s',0x%08lx,'%s')",
                                mp->mnt_fsname, mp->mnt_dir, mp->mnt_type,
@@ -414,11 +421,15 @@ static int mount_it_now(struct mntent *mp, long vfsflags, char *filteropts)
 
                // If mount failed, try
                // helper program mount.<mnt_type>
-               if (ENABLE_FEATURE_MOUNT_HELPERS && rc) {
-                       char *args[6];
+               if (HELPERS_ALLOWED && rc) {
+                       char *args[8];
                        int errno_save = errno;
                        args[0] = xasprintf("mount.%s", mp->mnt_type);
                        rc = 1;
+                       if (FAKE_IT)
+                               args[rc++] = (char *)"-f";
+                       if (ENABLE_FEATURE_MTAB_SUPPORT && !USE_MTAB)
+                               args[rc++] = (char *)"-n";
                        args[rc++] = mp->mnt_fsname;
                        args[rc++] = mp->mnt_dir;
                        if (filteropts) {
@@ -449,7 +460,7 @@ static int mount_it_now(struct mntent *mp, long vfsflags, char *filteropts)
        // If the mount was successful, and we're maintaining an old-style
        // mtab file by hand, add the new entry to it now.
  mtab:
-       if (useMtab && !rc && !(vfsflags & MS_REMOUNT)) {
+       if (USE_MTAB && !rc && !(vfsflags & MS_REMOUNT)) {
                char *fsname;
                FILE *mountTable = setmntent(bb_path_mtab_file, "a+");
                const char *option_str = mount_option_str;
@@ -1570,8 +1581,8 @@ static int singlemount(struct mntent *mp, int ignore_busy)
 {
        int rc = -1;
        long vfsflags;
-       char *loopFile = 0, *filteropts = 0;
-       llist_t *fl = 0;
+       char *loopFile = NULL, *filteropts = NULL;
+       llist_t *fl = NULL;
        struct stat st;
 
        vfsflags = parse_mount_options(mp->mnt_opts, &filteropts);
@@ -1581,21 +1592,28 @@ static int singlemount(struct mntent *mp, int ignore_busy)
                mp->mnt_type = NULL;
 
        // Might this be a virtual filesystem?
-       if (ENABLE_FEATURE_MOUNT_HELPERS
-        && (strchr(mp->mnt_fsname, '#'))
-       ) {
-               char *s, *p, *args[35];
-               int n = 0;
-// FIXME: does it allow execution of arbitrary commands?!
-// What args[0] can end up with?
-               for (s = p = mp->mnt_fsname; *s && n < 35-3; ++s) {
-                       if (s[0] == '#' && s[1] != '#') {
-                               *s = '\0';
-                               args[n++] = p;
-                               p = s + 1;
+       if (ENABLE_FEATURE_MOUNT_HELPERS && strchr(mp->mnt_fsname, '#')) {
+               char *args[35];
+               char *s;
+               int n;
+               // fsname: "cmd#arg1#arg2..."
+               // WARNING: allows execution of arbitrary commands!
+               // Try "mount 'sh#-c#sh' bogus_dir".
+               // It is safe ONLY because non-root
+               // cannot use two-argument mount command
+               // and using one-argument "mount 'sh#-c#sh'" doesn't work:
+               // "mount: can't find sh#-c#sh in /etc/fstab"
+               // (if /etc/fstab has it, it's ok: root sets up /etc/fstab).
+
+               s = mp->mnt_fsname;
+               n = 0;
+               args[n++] = s;
+               while (*s && n < 35 - 2) {
+                       if (*s++ == '#' && *s != '#') {
+                               s[-1] = '\0';
+                               args[n++] = s;
                        }
                }
-               args[n++] = p;
                args[n++] = mp->mnt_dir;
                args[n] = NULL;
                rc = wait4pid(xspawn(args));
@@ -1704,7 +1722,8 @@ static int singlemount(struct mntent *mp, int ignore_busy)
                for (fl = fslist; fl; fl = fl->link) {
                        mp->mnt_type = fl->data;
                        rc = mount_it_now(mp, vfsflags, filteropts);
-                       if (!rc) break;
+                       if (!rc)
+                               break;
                }
        }