More stuff.
diff --git a/Changelog b/Changelog
index 42b474d..cd0ca0a 100644
--- a/Changelog
+++ b/Changelog
@@ -4,12 +4,15 @@
 	* Fixed mkdir -m option so that it works.
 	* kill segfaulted w/o any arguments.  Now it doesn't do that.
 	* kill wasn't properly accepting signal names.  It does now.
-	* Added new apps chvt and deallocvt
-	* Major adjustment of init.c.  Code is now readable IMHO,
-	    and much more solid.
+	* Added new apps chvt and deallocvt (I should probably add open)
+	* Major rewrite of init.c.  Code is now readable by mere mortals IMHO.
 	* Wrote sed -- weighs only 1.8k (5.8k with full regular expressions!).
 	* Fixed a stupid seg-fault in sync
-	* Fixed mount -- mount -a always mounted rw despite /etc/fstab ro entries.
+	* Fixed mount -- mount -a failed to parse and apply mount options
+	* Added BB_MTAB, allowing (at the cost of ~1.5k and the need for a rw /etc)
+	    folks to use a real /etc/mtab file instead of a symlink to /proc/mounts.
+	    mount, and umount will add/remove entries and df will now use /etc/mtab 
+	    if BB_MTAB is defined. 
 
 	 -Erik Andersen
 
diff --git a/busybox.def.h b/busybox.def.h
index 0440b9f..8800463 100644
--- a/busybox.def.h
+++ b/busybox.def.h
@@ -38,6 +38,7 @@
 #define BB_MORE
 #define BB_MOUNT
 //#define BB_MT
+#define BB_MTAB
 #define BB_MV
 //#define BB_PRINTF
 #define BB_PS
diff --git a/coreutils/df.c b/coreutils/df.c
index f8a953f..94b6b82 100644
--- a/coreutils/df.c
+++ b/coreutils/df.c
@@ -31,6 +31,7 @@
 static const char df_usage[] = "df [filesystem ...]\n"
     "\n" "\tPrint the filesystem space used and space available.\n";
 
+extern const char mtab_file[]; /* Defined in utility.c */
 
 static int df(char *device, const char *mountPoint)
 {
@@ -113,7 +114,7 @@
 	int status;
 
 	while (argc > 1) {
-	    if ((mountEntry = findMountPoint(argv[1], "/proc/mounts")) ==
+	    if ((mountEntry = findMountPoint(argv[1], mtab_file)) ==
 		0) {
 		fprintf(stderr, "%s: can't find mount point.\n", argv[1]);
 		return 1;
@@ -129,9 +130,9 @@
 	FILE *mountTable;
 	struct mntent *mountEntry;
 
-	mountTable = setmntent("/proc/mounts", "r");
+	mountTable = setmntent(mtab_file, "r");
 	if (mountTable == 0) {
-	    perror("/proc/mounts");
+	    perror(mtab_file);
 	    exit(FALSE);
 	}
 
diff --git a/df.c b/df.c
index f8a953f..94b6b82 100644
--- a/df.c
+++ b/df.c
@@ -31,6 +31,7 @@
 static const char df_usage[] = "df [filesystem ...]\n"
     "\n" "\tPrint the filesystem space used and space available.\n";
 
+extern const char mtab_file[]; /* Defined in utility.c */
 
 static int df(char *device, const char *mountPoint)
 {
@@ -113,7 +114,7 @@
 	int status;
 
 	while (argc > 1) {
-	    if ((mountEntry = findMountPoint(argv[1], "/proc/mounts")) ==
+	    if ((mountEntry = findMountPoint(argv[1], mtab_file)) ==
 		0) {
 		fprintf(stderr, "%s: can't find mount point.\n", argv[1]);
 		return 1;
@@ -129,9 +130,9 @@
 	FILE *mountTable;
 	struct mntent *mountEntry;
 
-	mountTable = setmntent("/proc/mounts", "r");
+	mountTable = setmntent(mtab_file, "r");
 	if (mountTable == 0) {
-	    perror("/proc/mounts");
+	    perror(mtab_file);
 	    exit(FALSE);
 	}
 
diff --git a/internal.h b/internal.h
index 81271be..c66c9f1 100644
--- a/internal.h
+++ b/internal.h
@@ -47,7 +47,6 @@
 #define isWildCard(ch)  (((ch) == '*') || ((ch) == '?') || ((ch) == '['))
 
 
-
 struct Applet {
 	const	char*	name;
 	int	(*main)(int argc, char** argv);
@@ -147,6 +146,10 @@
 extern int get_kernel_revision();
 extern int get_console_fd(char* tty_name);
 
+extern void write_mtab(char* blockDevice, char* directory, 
+	char* filesystemType, long flags, char* string_flags);
+extern void erase_mtab(const char * name);
+
 
 #if defined (BB_FSCK_MINIX) || defined (BB_MKFS_MINIX)
 
diff --git a/mount.c b/mount.c
index 1efbdf4..8b5efe1 100644
--- a/mount.c
+++ b/mount.c
@@ -41,11 +41,17 @@
 #include <ctype.h>
 #include <fstab.h>
 
+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"
@@ -62,6 +68,7 @@
     "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;
@@ -84,6 +91,29 @@
     {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
@@ -126,9 +156,8 @@
 }
 
 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;
 
@@ -152,16 +181,16 @@
 		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) {
@@ -180,15 +209,17 @@
     char *device = NULL;
     char *directory = NULL;
     struct stat statBuf;
-    int all = 0;
+    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;
@@ -203,6 +234,8 @@
 			m->mnt_type, m->mnt_opts);
 	    }
 	    endmntent (mountTable);
+	} else {
+	    perror(mtab_file);
 	}
 	exit( TRUE);
     }
@@ -241,6 +274,14 @@
 	    case 'a':
 		all = TRUE;
 		break;
+#ifdef BB_MTAB
+	    case 'f':
+		fakeIt = TRUE;
+		break;
+	    case 'n':
+		useMtab = FALSE;
+		break;
+#endif
 	    case 'v':
 	    case 'h':
 	    case '-':
@@ -263,7 +304,6 @@
     }
 
     if (all == TRUE) {
-	long newFlags;
 	struct mntent *m;
 	FILE *f = setmntent ("/etc/fstab", "r");
 
@@ -279,17 +319,18 @@
 		    (!strstr (m->mnt_type, "swap")) && 
 		    (!strstr (m->mnt_type, "nfs"))) 
 	    {
-		newFlags = flags;
+		flags = 0;
 		*string_flags = '\0';
-		parse_mount_options(m->mnt_opts, &newFlags, string_flags);
-		mount_one (m->mnt_fsname, m->mnt_dir, m->mnt_type, newFlags, string_flags);
+		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);
diff --git a/umount.c b/umount.c
index 95f7dfb..e749c5f 100644
--- a/umount.c
+++ b/umount.c
@@ -29,24 +29,54 @@
 #include <errno.h>
 
 static const char umount_usage[] = 
-"Usage: umount filesystem\n"
-"   or: umount directory\n"
-"   or: umount -a"
-"to unmount all mounted file systems.\n";
+"Usage: umount [flags] filesystem|directory\n"
+"Optional Flags:\n"
+"\t-a:\tUnmount all file systems"
+#ifdef BB_MTAB
+" in /etc/mtab\n\t-n:\tDon't erase /etc/mtab entries\n"
+#else
+"\n"
+#endif
+;
+
+
+static int useMtab = TRUE;
+static int umountAll = FALSE;
+extern const char mtab_file[]; /* Defined in utility.c */
+
+#if ! defined BB_MTAB
+#define do_umount( blockDevice, useMtab) umount( blockDevice)
+#else
+static int 
+do_umount(const char* name, int useMtab)
+{
+    int status = umount(name);
+
+    if ( status == 0 ) {
+	if ( useMtab==TRUE )
+	    erase_mtab(name);
+	return 0;
+    }
+    else 
+	return( status);
+}
+#endif
 
 static int
-umount_all()
+umount_all(int useMtab)
 {
 	int status;
 	struct mntent *m;
         FILE *mountTable;
 
-        if ((mountTable = setmntent ("/proc/mounts", "r"))) {
+        if ((mountTable = setmntent (mtab_file, "r"))) {
             while ((m = getmntent (mountTable)) != 0) {
                 char *blockDevice = m->mnt_fsname;
+#if ! defined BB_MTAB
                 if (strcmp (blockDevice, "/dev/root") == 0)
                     blockDevice = (getfsfile ("/"))->fs_spec;
-		status=umount (m->mnt_dir);
+#endif
+		status=do_umount (m->mnt_dir, useMtab);
 		if (status!=0) {
 		    /* Don't bother retrying the umount on busy devices */
 		    if (errno==EBUSY) {
@@ -56,7 +86,7 @@
 		    printf ("Trying to umount %s failed: %s\n", 
 			    m->mnt_dir, strerror(errno)); 
 		    printf ("Instead trying to umount %s\n", blockDevice); 
-		    status=umount (blockDevice);
+		    status=do_umount (blockDevice, useMtab);
 		    if (status!=0) {
 			printf ("Couldn't umount %s on %s (type %s): %s\n", 
 				blockDevice, m->mnt_dir, m->mnt_type, strerror(errno));
@@ -69,27 +99,35 @@
 }
 
 extern int
-umount_main(int argc, char * * argv)
+umount_main(int argc, char** argv)
 {
 
     if (argc < 2) {
 	usage( umount_usage); 
     }
-    argc--;
-    argv++;
 
     /* Parse any options */
-    while (**argv == '-') {
+    while (argc-- > 0 && **(++argv) == '-') {
 	while (*++(*argv)) switch (**argv) {
 	    case 'a':
-		exit ( umount_all() );
+		umountAll = TRUE;
 		break;
+#ifdef BB_MTAB
+	    case 'n':
+		useMtab = FALSE;
+		break;
+#endif
 	    default:
 		usage( umount_usage);
 	}
     }
-    if ( umount(*argv) == 0 )
-	     exit (TRUE);
+
+
+    if(umountAll) {
+	exit(umount_all(useMtab));
+    }
+    if ( do_umount(*argv,useMtab) == 0 )
+	exit (TRUE);
     else {
 	perror("umount");
 	exit( FALSE);
diff --git a/util-linux/mount.c b/util-linux/mount.c
index 1efbdf4..8b5efe1 100644
--- a/util-linux/mount.c
+++ b/util-linux/mount.c
@@ -41,11 +41,17 @@
 #include <ctype.h>
 #include <fstab.h>
 
+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"
@@ -62,6 +68,7 @@
     "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;
@@ -84,6 +91,29 @@
     {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
@@ -126,9 +156,8 @@
 }
 
 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;
 
@@ -152,16 +181,16 @@
 		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) {
@@ -180,15 +209,17 @@
     char *device = NULL;
     char *directory = NULL;
     struct stat statBuf;
-    int all = 0;
+    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;
@@ -203,6 +234,8 @@
 			m->mnt_type, m->mnt_opts);
 	    }
 	    endmntent (mountTable);
+	} else {
+	    perror(mtab_file);
 	}
 	exit( TRUE);
     }
@@ -241,6 +274,14 @@
 	    case 'a':
 		all = TRUE;
 		break;
+#ifdef BB_MTAB
+	    case 'f':
+		fakeIt = TRUE;
+		break;
+	    case 'n':
+		useMtab = FALSE;
+		break;
+#endif
 	    case 'v':
 	    case 'h':
 	    case '-':
@@ -263,7 +304,6 @@
     }
 
     if (all == TRUE) {
-	long newFlags;
 	struct mntent *m;
 	FILE *f = setmntent ("/etc/fstab", "r");
 
@@ -279,17 +319,18 @@
 		    (!strstr (m->mnt_type, "swap")) && 
 		    (!strstr (m->mnt_type, "nfs"))) 
 	    {
-		newFlags = flags;
+		flags = 0;
 		*string_flags = '\0';
-		parse_mount_options(m->mnt_opts, &newFlags, string_flags);
-		mount_one (m->mnt_fsname, m->mnt_dir, m->mnt_type, newFlags, string_flags);
+		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);
diff --git a/util-linux/umount.c b/util-linux/umount.c
index 95f7dfb..e749c5f 100644
--- a/util-linux/umount.c
+++ b/util-linux/umount.c
@@ -29,24 +29,54 @@
 #include <errno.h>
 
 static const char umount_usage[] = 
-"Usage: umount filesystem\n"
-"   or: umount directory\n"
-"   or: umount -a"
-"to unmount all mounted file systems.\n";
+"Usage: umount [flags] filesystem|directory\n"
+"Optional Flags:\n"
+"\t-a:\tUnmount all file systems"
+#ifdef BB_MTAB
+" in /etc/mtab\n\t-n:\tDon't erase /etc/mtab entries\n"
+#else
+"\n"
+#endif
+;
+
+
+static int useMtab = TRUE;
+static int umountAll = FALSE;
+extern const char mtab_file[]; /* Defined in utility.c */
+
+#if ! defined BB_MTAB
+#define do_umount( blockDevice, useMtab) umount( blockDevice)
+#else
+static int 
+do_umount(const char* name, int useMtab)
+{
+    int status = umount(name);
+
+    if ( status == 0 ) {
+	if ( useMtab==TRUE )
+	    erase_mtab(name);
+	return 0;
+    }
+    else 
+	return( status);
+}
+#endif
 
 static int
-umount_all()
+umount_all(int useMtab)
 {
 	int status;
 	struct mntent *m;
         FILE *mountTable;
 
-        if ((mountTable = setmntent ("/proc/mounts", "r"))) {
+        if ((mountTable = setmntent (mtab_file, "r"))) {
             while ((m = getmntent (mountTable)) != 0) {
                 char *blockDevice = m->mnt_fsname;
+#if ! defined BB_MTAB
                 if (strcmp (blockDevice, "/dev/root") == 0)
                     blockDevice = (getfsfile ("/"))->fs_spec;
-		status=umount (m->mnt_dir);
+#endif
+		status=do_umount (m->mnt_dir, useMtab);
 		if (status!=0) {
 		    /* Don't bother retrying the umount on busy devices */
 		    if (errno==EBUSY) {
@@ -56,7 +86,7 @@
 		    printf ("Trying to umount %s failed: %s\n", 
 			    m->mnt_dir, strerror(errno)); 
 		    printf ("Instead trying to umount %s\n", blockDevice); 
-		    status=umount (blockDevice);
+		    status=do_umount (blockDevice, useMtab);
 		    if (status!=0) {
 			printf ("Couldn't umount %s on %s (type %s): %s\n", 
 				blockDevice, m->mnt_dir, m->mnt_type, strerror(errno));
@@ -69,27 +99,35 @@
 }
 
 extern int
-umount_main(int argc, char * * argv)
+umount_main(int argc, char** argv)
 {
 
     if (argc < 2) {
 	usage( umount_usage); 
     }
-    argc--;
-    argv++;
 
     /* Parse any options */
-    while (**argv == '-') {
+    while (argc-- > 0 && **(++argv) == '-') {
 	while (*++(*argv)) switch (**argv) {
 	    case 'a':
-		exit ( umount_all() );
+		umountAll = TRUE;
 		break;
+#ifdef BB_MTAB
+	    case 'n':
+		useMtab = FALSE;
+		break;
+#endif
 	    default:
 		usage( umount_usage);
 	}
     }
-    if ( umount(*argv) == 0 )
-	     exit (TRUE);
+
+
+    if(umountAll) {
+	exit(umount_all(useMtab));
+    }
+    if ( do_umount(*argv,useMtab) == 0 )
+	exit (TRUE);
     else {
 	perror("umount");
 	exit( FALSE);
diff --git a/utility.c b/utility.c
index 2656832..125e819 100644
--- a/utility.c
+++ b/utility.c
@@ -36,6 +36,15 @@
 #include <unistd.h>
 #include <ctype.h>
 
+#ifdef BB_MTAB
+const char mtab_file[] = "/etc/mtab";
+#else
+#if defined BB_MOUNT || defined BB_UMOUNT || defined BB_DF
+const char mtab_file[] = "/proc/mounts";
+#endif
+#endif
+
+
 /* volatile so gcc knows this is the enod of the line */
 volatile void usage(const char *usage)
 {