Update
[oweals/busybox.git] / mount.c
diff --git a/mount.c b/mount.c
index d7b2682ced75076eb1fe71b58774e59ad367ba90..8b5efe14f93e4f45b1c95553ad17610410fa86e2 100644 (file)
--- a/mount.c
+++ b/mount.c
@@ -1,7 +1,7 @@
 /*
  * Mini mount implementation for busybox
  *
- * Copyright (C) 1999 by Erik Andersen <andersee@debian.org>
+ * Copyright (C) 1995, 1996 by Bruce Perens <bruce@pixar.com>.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
  *             will try mounting stuff with all fses when passed -t auto
  *
  * 1999-04-17  Dave Cinege...Rewrote -t auto. Fixed ro mtab.
- * 1999-10-07  Erik Andersen.  Rewrote of a lot of code. Removed mtab 
- *              usage, major adjustments, and some serious dieting all around.
+ *
+ * 1999-10-07  Erik Andersen <andersen@lineo.com>, <andersee@debian.org>.
+ *              Rewrote of a lot of code. Removed mtab usage (I plan on
+ *              putting it back as a compile-time option some time), 
+ *              major adjustments to option parsing, and some serious 
+ *              dieting all around.
 */
 
 #include "internal.h"
 #include <ctype.h>
 #include <fstab.h>
 
-const char mount_usage[] = "Usage:\tmount [flags]\n"
+extern const char mtab_file[]; /* Defined in utility.c */
+
+static const char mount_usage[] = "Usage:\tmount [flags]\n"
     "\tmount [flags] device directory [-o options,more-options]\n"
     "\n"
     "Flags:\n"
     "\t-a:\tMount all file systems in fstab.\n"
+#ifdef BB_MTAB
+    "\t-f:\t\"Fake\" mount. Add entry to mount table but don't mount it.\n"
+    "\t-n:\tDon't write a mount table entry.\n"
+#endif
     "\t-o option:\tOne of many filesystem options, listed below.\n"
     "\t-r:\tMount the filesystem read-only.\n"
     "\t-t filesystem-type:\tSpecify the filesystem type.\n"
@@ -58,6 +68,7 @@ const char mount_usage[] = "Usage:\tmount [flags]\n"
     "There are EVEN MORE flags that are specific to each filesystem.\n"
     "You'll have to see the written documentation for those.\n";
 
+
 struct mount_options {
     const char *name;
     unsigned long and;
@@ -80,6 +91,29 @@ static const struct mount_options mount_options[] = {
     {0, 0, 0}
 };
 
+#if ! defined BB_MTAB
+#define do_mount(specialfile, dir, filesystemtype, flags, string_flags, useMtab, fakeIt) \
+       mount(specialfile, dir, filesystemtype, flags, string_flags)
+#else
+static int
+do_mount(char* specialfile, char* dir, char* filesystemtype, 
+       long flags, void* string_flags, int useMtab, int fakeIt)
+{
+    int status=0;
+
+    if (fakeIt==FALSE)
+       status=mount(specialfile, dir, filesystemtype, flags, string_flags);
+
+    if ( status == 0 ) {
+       if ( useMtab==TRUE )
+           write_mtab(specialfile, dir, filesystemtype, flags, string_flags);
+       return 0;
+    }
+    else 
+       return( status);
+}
+#endif
+
 
 /* Seperate standard mount options from the nonstandard string options */
 static void
@@ -94,6 +128,7 @@ parse_mount_options ( char *options, unsigned long *flags, char *strflags)
 
        while (f->name != 0) {
            if (strcasecmp (f->name, options) == 0) {
+
                *flags &= f->and;
                *flags |= f->or;
                gotone=TRUE;
@@ -121,9 +156,8 @@ parse_mount_options ( char *options, unsigned long *flags, char *strflags)
 }
 
 int
-mount_one (
-          char *blockDevice, char *directory, char *filesystemType,
-          unsigned long flags, char *string_flags)
+mount_one(char *blockDevice, char *directory, char *filesystemType,
+          unsigned long flags, char *string_flags, int useMtab, int fakeIt)
 {
     int status = 0;
 
@@ -147,16 +181,16 @@ mount_one (
                filesystemType = buf;
                filesystemType++;       // hop past tab
 
-               status = mount (blockDevice, directory, filesystemType,
-                               flags | MS_MGC_VAL, string_flags);
+               status = do_mount (blockDevice, directory, filesystemType,
+                               flags | MS_MGC_VAL, string_flags, useMtab, fakeIt);
                if (status == 0)
                    break;
            }
        }
        fclose (f);
     } else {
-       status = mount (blockDevice, directory, filesystemType,
-                       flags | MS_MGC_VAL, string_flags);
+       status = do_mount (blockDevice, directory, filesystemType,
+                       flags | MS_MGC_VAL, string_flags, useMtab, fakeIt);
     }
 
     if (status) {
@@ -174,21 +208,34 @@ extern int mount_main (int argc, char **argv)
     char *filesystemType = "auto";
     char *device = NULL;
     char *directory = NULL;
-    int all = 0;
+    struct stat statBuf;
+    int all = FALSE;
+    int fakeIt = FALSE;
+    int useMtab = TRUE;
     int i;
 
+    if (stat("/etc/fstab", &statBuf) < 0) 
+       fprintf(stderr, "/etc/fstab file missing -- Please install one.\n\n");
+
     if (argc == 1) {
-       FILE *mountTable;
-       if ((mountTable = setmntent ("/proc/mounts", "r"))) {
+       FILE *mountTable = setmntent (mtab_file, "r");
+       if (mountTable) {
            struct mntent *m;
            while ((m = getmntent (mountTable)) != 0) {
+               struct fstab* fstabItem;
                char *blockDevice = m->mnt_fsname;
-               if (strcmp (blockDevice, "/dev/root") == 0)
-                   blockDevice = (getfsfile ("/"))->fs_spec;
+               /* Note that if /etc/fstab is missing, libc can't fix up /dev/root for us */
+               if (strcmp (blockDevice, "/dev/root") == 0) {
+                   fstabItem = getfsfile ("/");
+                   if (fstabItem != NULL)
+                       blockDevice = fstabItem->fs_spec;
+               }
                printf ("%s on %s type %s (%s)\n", blockDevice, m->mnt_dir,
                        m->mnt_type, m->mnt_opts);
            }
            endmntent (mountTable);
+       } else {
+           perror(mtab_file);
        }
        exit( TRUE);
     }
@@ -225,8 +272,16 @@ extern int mount_main (int argc, char **argv)
                flags &= ~MS_RDONLY;
                break;
            case 'a':
-               all = 1;
+               all = TRUE;
+               break;
+#ifdef BB_MTAB
+           case 'f':
+               fakeIt = TRUE;
+               break;
+           case 'n':
+               useMtab = FALSE;
                break;
+#endif
            case 'v':
            case 'h':
            case '-':
@@ -248,7 +303,7 @@ extern int mount_main (int argc, char **argv)
        argv++;
     }
 
-    if (all == 1) {
+    if (all == TRUE) {
        struct mntent *m;
        FILE *f = setmntent ("/etc/fstab", "r");
 
@@ -257,21 +312,25 @@ extern int mount_main (int argc, char **argv)
            exit( FALSE); 
        }
        while ((m = getmntent (f)) != NULL) {
-           // If the file system isn't noauto, and isn't mounted on /, mount 
-           // it
-           if ((!strstr (m->mnt_opts, "noauto"))
-               && (m->mnt_dir[1] != '\0') && !((m->mnt_type[0] == 's')
-                                               && (m->mnt_type[1] == 'w'))
-               && !((m->mnt_type[0] == 'n') && (m->mnt_type[1] == 'f'))) {
-               mount_one (m->mnt_fsname, m->mnt_dir, m->mnt_type, flags,
-                          m->mnt_opts);
+           // If the file system isn't noauto, and isn't mounted on /, 
+           // and isn't swap or nfs, then mount it
+           if ((!strstr (m->mnt_opts, "noauto")) &&
+                   (m->mnt_dir[1] != '\0') && 
+                   (!strstr (m->mnt_type, "swap")) && 
+                   (!strstr (m->mnt_type, "nfs"))) 
+           {
+               flags = 0;
+               *string_flags = '\0';
+               parse_mount_options(m->mnt_opts, &flags, string_flags);
+               mount_one (m->mnt_fsname, m->mnt_dir, m->mnt_type, 
+                       flags, string_flags, useMtab, fakeIt);
            }
        }
        endmntent (f);
     } else {
        if (device && directory) {
            exit (mount_one (device, directory, filesystemType, 
-                       flags, string_flags));
+                       flags, string_flags, useMtab, fakeIt));
        } else {
            fprintf (stderr, "%s\n", mount_usage);
            exit( FALSE);