Fixed the init problem where it wouldn't unmount filesystems
authorErik Andersen <andersen@codepoet.org>
Wed, 9 Feb 2000 04:16:43 +0000 (04:16 -0000)
committerErik Andersen <andersen@codepoet.org>
Wed, 9 Feb 2000 04:16:43 +0000 (04:16 -0000)
on reboot.  Also fixed swapoff -a so it works.
 -Erik

13 files changed:
Changelog
Makefile
busybox.def.h
init.c
init/init.c
internal.h
mount.c
swaponoff.c
umount.c
util-linux/mount.c
util-linux/swaponoff.c
util-linux/umount.c
utility.c

index 7ecc4fb..42ec296 100644 (file)
--- a/Changelog
+++ b/Changelog
@@ -84,6 +84,8 @@
            - `fdflush', `length' and `printf' crashed when run without arguments
            - `fdflush' tried to flush itself using *argv
            - added "skip" and "seek" to dd.
+       * swapoff -a was not working.  Now it is.
+       * init did not cleanly unmount filesystems on reboot.  Now it does.
 
 
        -Erik Andersen
index 490d393..6543e1f 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -62,7 +62,7 @@ endif
 
 # -D_GNU_SOURCE is needed because environ is used in init.c
 ifeq ($(DODEBUG),true)
-    CFLAGS += -Wall -g -D_GNU_SOURCE -DDEBUG_INIT
+    CFLAGS += -Wall -g -D_GNU_SOURCE
     STRIP   =
     LDFLAGS =
 else
index f8c6e6e..e2f5dd3 100644 (file)
@@ -59,7 +59,6 @@
 #define BB_MOUNT
 #define BB_NFSMOUNT
 //#define BB_MT
-//#define BB_MTAB
 #define BB_NSLOOKUP
 #define BB_PING
 #define BB_POWEROFF
diff --git a/init.c b/init.c
index 899dca4..2f2203b 100644 (file)
--- a/init.c
+++ b/init.c
  *
  */
 
+/* Turn this on to disable all the dangerous 
+   rebooting stuff when debugging.
+#define DEBUG_INIT
+*/
+
 #include "internal.h"
 #include <stdio.h>
 #include <string.h>
@@ -78,7 +83,8 @@ typedef enum {
        RESPAWN,
        ASKFIRST,
        WAIT,
-       ONCE
+       ONCE,
+       CTRLALTDEL
 } initActionEnum;
 
 /* And now a list of the actions we support in the version of init */
@@ -93,6 +99,7 @@ static const struct initActionType actions[] = {
        {"askfirst", ASKFIRST},
        {"wait", WAIT},
        {"once", ONCE},
+       {"ctrlaltdel", CTRLALTDEL},
        {0}
 };
 
@@ -113,6 +120,7 @@ static char *log = VT_LOG;
 static int kernelVersion = 0;
 static char termType[32] = "TERM=ansi";
 static char console[32] = _PATH_CONSOLE;
+static void delete_initAction(initAction * action);
 
 
 /* print a message to the specified device:
@@ -131,8 +139,8 @@ void message(int device, char *fmt, ...)
                va_start(arguments, fmt);
                vsnprintf(msg, sizeof(msg), fmt, arguments);
                va_end(arguments);
-               openlog("init", 0, LOG_DAEMON);
-               syslog(LOG_DAEMON | LOG_NOTICE, msg);
+               openlog("init", 0, LOG_USER);
+               syslog(LOG_USER|LOG_INFO, msg);
                closelog();
        }
 #else
@@ -146,11 +154,12 @@ void message(int device, char *fmt, ...)
                        log_fd = -2;
                        /* log to main console instead */
                        device = CONSOLE;
-               } else if ((log_fd = device_open(log, O_RDWR | O_NDELAY)) < 0) {
-                       log_fd = -1;
+               } else if ((log_fd = device_open(log, O_RDWR|O_NDELAY)) < 0) {
+                       log_fd = -2;
                        fprintf(stderr, "Bummer, can't write to log on %s!\r\n", log);
                        fflush(stderr);
-                       return;
+                       log = NULL;
+                       device = CONSOLE;
                }
        }
        if ((device & LOG) && (log_fd >= 0)) {
@@ -303,10 +312,10 @@ static void console_init()
                /* check for serial console and disable logging to tty3 & running a
                   * shell to tty2 */
                if (ioctl(0, TIOCGSERIAL, &sr) == 0) {
-                       message(LOG | CONSOLE,
-                                       "serial console detected.  Disabling virtual terminals.\r\n");
                        log = NULL;
                        secondConsole = NULL;
+                       message(LOG | CONSOLE,
+                                       "serial console detected.  Disabling virtual terminals.\r\n");
                }
                close(fd);
        }
@@ -319,6 +328,7 @@ static pid_t run(char *command, char *terminal, int get_enter)
        pid_t pid;
        char *tmpCmd;
        char *cmd[255];
+       char buf[255];
        static const char press_enter[] =
 
                "\nPlease press Enter to activate this console. ";
@@ -333,7 +343,9 @@ static pid_t run(char *command, char *terminal, int get_enter)
 
 
        if ((pid = fork()) == 0) {
+#ifdef DEBUG_INIT
                pid_t shell_pgid = getpid();
+#endif
 
                /* Clean up */
                close(0);
@@ -369,30 +381,40 @@ static pid_t run(char *command, char *terminal, int get_enter)
                         */
                        char c;
 
+#ifdef DEBUG_INIT
                        message(LOG, "Waiting for enter to start '%s' (pid %d, console %s)\r\n",
                                        command, shell_pgid, terminal);
+#endif
                        write(fileno(stdout), press_enter, sizeof(press_enter) - 1);
                        read(fileno(stdin), &c, 1);
                }
 
+#ifdef DEBUG_INIT
                /* Log the process name and args */
-               message(LOG, "Starting pid %d, console %s: '",
+               message(LOG, "Starting pid %d, console %s: '%s'\r\n",
                                shell_pgid, terminal, command);
-
-               /* Convert command (char*) into cmd (char**, one word per string) */
-               for (tmpCmd = command, i = 0;
-                        (tmpCmd = strsep(&command, " \t")) != NULL;) {
-                       if (*tmpCmd != '\0') {
-                               cmd[i] = tmpCmd;
-#ifdef DEBUG_INIT
-                               message(LOG, "%s ", tmpCmd);
 #endif
-                               tmpCmd++;
-                               i++;
+
+               /* See if any special /bin/sh requiring characters are present */
+               if (strpbrk(command, "~`!$^&*()=|\\{}[];\"'<>?") != NULL) {
+                       cmd[0] = SHELL;
+                       cmd[1] = "-c";
+                       strcpy(buf, "exec ");
+                       strncat(buf, command, sizeof(buf) - strlen(buf) - 1);
+                       cmd[2] = buf;
+                       cmd[3] = NULL;
+               } else {
+                       /* Convert command (char*) into cmd (char**, one word per string) */
+                       for (tmpCmd = command, i = 0;
+                                (tmpCmd = strsep(&command, " \t")) != NULL;) {
+                               if (*tmpCmd != '\0') {
+                                       cmd[i] = tmpCmd;
+                                       tmpCmd++;
+                                       i++;
+                               }
                        }
+                       cmd[i] = NULL;
                }
-               cmd[i] = NULL;
-               message(LOG, "'\r\n");
 
                /* Now run it.  The new program will take over this PID, 
                 * so nothing further in init.c should be run. */
@@ -413,9 +435,8 @@ static int waitfor(char *command, char *terminal, int get_enter)
 
        while (1) {
                wpid = wait(&status);
-               if (wpid > 0) {
-                       message(LOG, "Process '%s' (pid %d) exited.\n", command, wpid);
-                       break;
+               if (wpid > 0 && wpid != pid) {
+                       continue;
                }
                if (wpid == pid)
                        break;
@@ -424,7 +445,7 @@ static int waitfor(char *command, char *terminal, int get_enter)
 }
 
 /* Make sure there is enough memory to do something useful. *
- * Calls swapon if needed so be sure /proc is mounted. */
+ * Calls "swapon -a" if needed so be sure /etc/fstab is present... */
 static void check_memory()
 {
        struct stat statBuf;
@@ -434,7 +455,7 @@ static void check_memory()
 
        if (stat("/etc/fstab", &statBuf) == 0) {
                /* Try to turn on swap */
-               waitfor("/bin/swapon swapon -a", log, FALSE);
+               system("/sbin/swapon swapon -a");
                if (mem_total() < 3500)
                        goto goodnight;
        } else
@@ -448,31 +469,45 @@ static void check_memory()
                sleep(1);
 }
 
+/* Run all commands to be run right before halt/reboot */
+static void run_lastAction(void)
+{
+       initAction *a;
+       for (a = initActionList; a; a = a->nextPtr) {
+               if (a->action == CTRLALTDEL) {
+                       waitfor(a->process, a->console, FALSE);
+                       delete_initAction(a);
+               }
+       }
+}
+
+
 #ifndef DEBUG_INIT
 static void shutdown_system(void)
 {
+
        /* first disable our SIGHUP signal */
        signal(SIGHUP, SIG_DFL);
 
        /* Allow Ctrl-Alt-Del to reboot system. */
        reboot(RB_ENABLE_CAD);
-       message(CONSOLE, "\r\nThe system is going down NOW !!\r\n");
+
+       message(CONSOLE|LOG, "\r\nThe system is going down NOW !!\r\n");
        sync();
 
        /* Send signals to every process _except_ pid 1 */
-       message(CONSOLE, "Sending SIGTERM to all processes.\r\n");
+       message(CONSOLE|LOG, "Sending SIGTERM to all processes.\r\n");
        kill(-1, SIGTERM);
-       sleep(5);
+       sleep(1);
        sync();
 
-       message(CONSOLE, "Sending SIGKILL to all processes.\r\n");
+       message(CONSOLE|LOG, "Sending SIGKILL to all processes.\r\n");
        kill(-1, SIGKILL);
-       sleep(5);
+       sleep(1);
+
+       /* run everything to be run at "ctrlaltdel" */
+       run_lastAction();
 
-       message(CONSOLE, "Disabling swap.\r\n");
-       waitfor("swapoff -a", console, FALSE);
-       message(CONSOLE, "Unmounting filesystems.\r\n");
-       waitfor("umount -a -r", console, FALSE);
        sync();
        if (kernelVersion > 0 && kernelVersion <= 2 * 65536 + 2 * 256 + 11) {
                /* bdflush, kupdate not needed for kernels >2.2.11 */
@@ -484,14 +519,14 @@ static void shutdown_system(void)
 static void halt_signal(int sig)
 {
        shutdown_system();
-       message(CONSOLE,
+       message(CONSOLE|LOG,
                        "The system is halted. Press %s or turn off power\r\n",
                        (secondConsole == NULL) /* serial console */
                        ? "Reset" : "CTRL-ALT-DEL");
        sync();
 
        /* allow time for last message to reach serial console */
-       sleep(5);
+       sleep(2);
 
 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,2,0)
        if (sig == SIGUSR2)
@@ -505,7 +540,7 @@ static void halt_signal(int sig)
 static void reboot_signal(int sig)
 {
        shutdown_system();
-       message(CONSOLE, "Please stand by while rebooting the system.\r\n");
+       message(CONSOLE|LOG, "Please stand by while rebooting the system.\r\n");
        sync();
 
        /* allow time for last message to reach serial console */
@@ -631,7 +666,7 @@ void new_initAction(initActionEnum action, char *process, char *cons)
 //      newAction->process, newAction->action, newAction->console);
 }
 
-void delete_initAction(initAction * action)
+static void delete_initAction(initAction * action)
 {
        initAction *a, *b = NULL;
 
@@ -669,6 +704,10 @@ void parse_inittab(void)
        if (file == NULL) {
                /* No inittab file -- set up some default behavior */
 #endif
+               /* Swapoff on halt/reboot */
+               new_initAction(CTRLALTDEL, "/bin/umount -a -r > /dev/null 2>&1", console);
+               /* Umount all filesystems on halt/reboot */
+               new_initAction(CTRLALTDEL, "/bin/umount -a -r > /dev/null 2>&1", console);
                /* Askfirst shell on tty1 */
                new_initAction(ASKFIRST, SHELL, console);
                /* Askfirst shell on tty2 */
@@ -756,6 +795,8 @@ void parse_inittab(void)
 #endif
 }
 
+
+
 extern int init_main(int argc, char **argv)
 {
        initAction *a;
@@ -768,9 +809,6 @@ extern int init_main(int argc, char **argv)
                usage("init\n\nInit is the parent of all processes.\n\n"
                          "This version of init is designed to be run only by the kernel\n");
        }
-       /* Fix up argv[0] to be certain we claim to be init */
-       strncpy(argv[0], "init", strlen(argv[0]));
-
        /* Set up sig handlers  -- be sure to
         * clear all of these in run() */
        signal(SIGUSR1, halt_signal);
@@ -838,6 +876,10 @@ extern int init_main(int argc, char **argv)
                 * of "askfirst" shells */
                parse_inittab();
        }
+       
+       /* Fix up argv[0] to be certain we claim to be init */
+       strncpy(argv[0], "init", strlen(argv[0])+1);
+       strncpy(argv[1], "\0", strlen(argv[1])+1);
 
        /* Now run everything that needs to be run */
 
index 899dca4..2f2203b 100644 (file)
  *
  */
 
+/* Turn this on to disable all the dangerous 
+   rebooting stuff when debugging.
+#define DEBUG_INIT
+*/
+
 #include "internal.h"
 #include <stdio.h>
 #include <string.h>
@@ -78,7 +83,8 @@ typedef enum {
        RESPAWN,
        ASKFIRST,
        WAIT,
-       ONCE
+       ONCE,
+       CTRLALTDEL
 } initActionEnum;
 
 /* And now a list of the actions we support in the version of init */
@@ -93,6 +99,7 @@ static const struct initActionType actions[] = {
        {"askfirst", ASKFIRST},
        {"wait", WAIT},
        {"once", ONCE},
+       {"ctrlaltdel", CTRLALTDEL},
        {0}
 };
 
@@ -113,6 +120,7 @@ static char *log = VT_LOG;
 static int kernelVersion = 0;
 static char termType[32] = "TERM=ansi";
 static char console[32] = _PATH_CONSOLE;
+static void delete_initAction(initAction * action);
 
 
 /* print a message to the specified device:
@@ -131,8 +139,8 @@ void message(int device, char *fmt, ...)
                va_start(arguments, fmt);
                vsnprintf(msg, sizeof(msg), fmt, arguments);
                va_end(arguments);
-               openlog("init", 0, LOG_DAEMON);
-               syslog(LOG_DAEMON | LOG_NOTICE, msg);
+               openlog("init", 0, LOG_USER);
+               syslog(LOG_USER|LOG_INFO, msg);
                closelog();
        }
 #else
@@ -146,11 +154,12 @@ void message(int device, char *fmt, ...)
                        log_fd = -2;
                        /* log to main console instead */
                        device = CONSOLE;
-               } else if ((log_fd = device_open(log, O_RDWR | O_NDELAY)) < 0) {
-                       log_fd = -1;
+               } else if ((log_fd = device_open(log, O_RDWR|O_NDELAY)) < 0) {
+                       log_fd = -2;
                        fprintf(stderr, "Bummer, can't write to log on %s!\r\n", log);
                        fflush(stderr);
-                       return;
+                       log = NULL;
+                       device = CONSOLE;
                }
        }
        if ((device & LOG) && (log_fd >= 0)) {
@@ -303,10 +312,10 @@ static void console_init()
                /* check for serial console and disable logging to tty3 & running a
                   * shell to tty2 */
                if (ioctl(0, TIOCGSERIAL, &sr) == 0) {
-                       message(LOG | CONSOLE,
-                                       "serial console detected.  Disabling virtual terminals.\r\n");
                        log = NULL;
                        secondConsole = NULL;
+                       message(LOG | CONSOLE,
+                                       "serial console detected.  Disabling virtual terminals.\r\n");
                }
                close(fd);
        }
@@ -319,6 +328,7 @@ static pid_t run(char *command, char *terminal, int get_enter)
        pid_t pid;
        char *tmpCmd;
        char *cmd[255];
+       char buf[255];
        static const char press_enter[] =
 
                "\nPlease press Enter to activate this console. ";
@@ -333,7 +343,9 @@ static pid_t run(char *command, char *terminal, int get_enter)
 
 
        if ((pid = fork()) == 0) {
+#ifdef DEBUG_INIT
                pid_t shell_pgid = getpid();
+#endif
 
                /* Clean up */
                close(0);
@@ -369,30 +381,40 @@ static pid_t run(char *command, char *terminal, int get_enter)
                         */
                        char c;
 
+#ifdef DEBUG_INIT
                        message(LOG, "Waiting for enter to start '%s' (pid %d, console %s)\r\n",
                                        command, shell_pgid, terminal);
+#endif
                        write(fileno(stdout), press_enter, sizeof(press_enter) - 1);
                        read(fileno(stdin), &c, 1);
                }
 
+#ifdef DEBUG_INIT
                /* Log the process name and args */
-               message(LOG, "Starting pid %d, console %s: '",
+               message(LOG, "Starting pid %d, console %s: '%s'\r\n",
                                shell_pgid, terminal, command);
-
-               /* Convert command (char*) into cmd (char**, one word per string) */
-               for (tmpCmd = command, i = 0;
-                        (tmpCmd = strsep(&command, " \t")) != NULL;) {
-                       if (*tmpCmd != '\0') {
-                               cmd[i] = tmpCmd;
-#ifdef DEBUG_INIT
-                               message(LOG, "%s ", tmpCmd);
 #endif
-                               tmpCmd++;
-                               i++;
+
+               /* See if any special /bin/sh requiring characters are present */
+               if (strpbrk(command, "~`!$^&*()=|\\{}[];\"'<>?") != NULL) {
+                       cmd[0] = SHELL;
+                       cmd[1] = "-c";
+                       strcpy(buf, "exec ");
+                       strncat(buf, command, sizeof(buf) - strlen(buf) - 1);
+                       cmd[2] = buf;
+                       cmd[3] = NULL;
+               } else {
+                       /* Convert command (char*) into cmd (char**, one word per string) */
+                       for (tmpCmd = command, i = 0;
+                                (tmpCmd = strsep(&command, " \t")) != NULL;) {
+                               if (*tmpCmd != '\0') {
+                                       cmd[i] = tmpCmd;
+                                       tmpCmd++;
+                                       i++;
+                               }
                        }
+                       cmd[i] = NULL;
                }
-               cmd[i] = NULL;
-               message(LOG, "'\r\n");
 
                /* Now run it.  The new program will take over this PID, 
                 * so nothing further in init.c should be run. */
@@ -413,9 +435,8 @@ static int waitfor(char *command, char *terminal, int get_enter)
 
        while (1) {
                wpid = wait(&status);
-               if (wpid > 0) {
-                       message(LOG, "Process '%s' (pid %d) exited.\n", command, wpid);
-                       break;
+               if (wpid > 0 && wpid != pid) {
+                       continue;
                }
                if (wpid == pid)
                        break;
@@ -424,7 +445,7 @@ static int waitfor(char *command, char *terminal, int get_enter)
 }
 
 /* Make sure there is enough memory to do something useful. *
- * Calls swapon if needed so be sure /proc is mounted. */
+ * Calls "swapon -a" if needed so be sure /etc/fstab is present... */
 static void check_memory()
 {
        struct stat statBuf;
@@ -434,7 +455,7 @@ static void check_memory()
 
        if (stat("/etc/fstab", &statBuf) == 0) {
                /* Try to turn on swap */
-               waitfor("/bin/swapon swapon -a", log, FALSE);
+               system("/sbin/swapon swapon -a");
                if (mem_total() < 3500)
                        goto goodnight;
        } else
@@ -448,31 +469,45 @@ static void check_memory()
                sleep(1);
 }
 
+/* Run all commands to be run right before halt/reboot */
+static void run_lastAction(void)
+{
+       initAction *a;
+       for (a = initActionList; a; a = a->nextPtr) {
+               if (a->action == CTRLALTDEL) {
+                       waitfor(a->process, a->console, FALSE);
+                       delete_initAction(a);
+               }
+       }
+}
+
+
 #ifndef DEBUG_INIT
 static void shutdown_system(void)
 {
+
        /* first disable our SIGHUP signal */
        signal(SIGHUP, SIG_DFL);
 
        /* Allow Ctrl-Alt-Del to reboot system. */
        reboot(RB_ENABLE_CAD);
-       message(CONSOLE, "\r\nThe system is going down NOW !!\r\n");
+
+       message(CONSOLE|LOG, "\r\nThe system is going down NOW !!\r\n");
        sync();
 
        /* Send signals to every process _except_ pid 1 */
-       message(CONSOLE, "Sending SIGTERM to all processes.\r\n");
+       message(CONSOLE|LOG, "Sending SIGTERM to all processes.\r\n");
        kill(-1, SIGTERM);
-       sleep(5);
+       sleep(1);
        sync();
 
-       message(CONSOLE, "Sending SIGKILL to all processes.\r\n");
+       message(CONSOLE|LOG, "Sending SIGKILL to all processes.\r\n");
        kill(-1, SIGKILL);
-       sleep(5);
+       sleep(1);
+
+       /* run everything to be run at "ctrlaltdel" */
+       run_lastAction();
 
-       message(CONSOLE, "Disabling swap.\r\n");
-       waitfor("swapoff -a", console, FALSE);
-       message(CONSOLE, "Unmounting filesystems.\r\n");
-       waitfor("umount -a -r", console, FALSE);
        sync();
        if (kernelVersion > 0 && kernelVersion <= 2 * 65536 + 2 * 256 + 11) {
                /* bdflush, kupdate not needed for kernels >2.2.11 */
@@ -484,14 +519,14 @@ static void shutdown_system(void)
 static void halt_signal(int sig)
 {
        shutdown_system();
-       message(CONSOLE,
+       message(CONSOLE|LOG,
                        "The system is halted. Press %s or turn off power\r\n",
                        (secondConsole == NULL) /* serial console */
                        ? "Reset" : "CTRL-ALT-DEL");
        sync();
 
        /* allow time for last message to reach serial console */
-       sleep(5);
+       sleep(2);
 
 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,2,0)
        if (sig == SIGUSR2)
@@ -505,7 +540,7 @@ static void halt_signal(int sig)
 static void reboot_signal(int sig)
 {
        shutdown_system();
-       message(CONSOLE, "Please stand by while rebooting the system.\r\n");
+       message(CONSOLE|LOG, "Please stand by while rebooting the system.\r\n");
        sync();
 
        /* allow time for last message to reach serial console */
@@ -631,7 +666,7 @@ void new_initAction(initActionEnum action, char *process, char *cons)
 //      newAction->process, newAction->action, newAction->console);
 }
 
-void delete_initAction(initAction * action)
+static void delete_initAction(initAction * action)
 {
        initAction *a, *b = NULL;
 
@@ -669,6 +704,10 @@ void parse_inittab(void)
        if (file == NULL) {
                /* No inittab file -- set up some default behavior */
 #endif
+               /* Swapoff on halt/reboot */
+               new_initAction(CTRLALTDEL, "/bin/umount -a -r > /dev/null 2>&1", console);
+               /* Umount all filesystems on halt/reboot */
+               new_initAction(CTRLALTDEL, "/bin/umount -a -r > /dev/null 2>&1", console);
                /* Askfirst shell on tty1 */
                new_initAction(ASKFIRST, SHELL, console);
                /* Askfirst shell on tty2 */
@@ -756,6 +795,8 @@ void parse_inittab(void)
 #endif
 }
 
+
+
 extern int init_main(int argc, char **argv)
 {
        initAction *a;
@@ -768,9 +809,6 @@ extern int init_main(int argc, char **argv)
                usage("init\n\nInit is the parent of all processes.\n\n"
                          "This version of init is designed to be run only by the kernel\n");
        }
-       /* Fix up argv[0] to be certain we claim to be init */
-       strncpy(argv[0], "init", strlen(argv[0]));
-
        /* Set up sig handlers  -- be sure to
         * clear all of these in run() */
        signal(SIGUSR1, halt_signal);
@@ -838,6 +876,10 @@ extern int init_main(int argc, char **argv)
                 * of "askfirst" shells */
                parse_inittab();
        }
+       
+       /* Fix up argv[0] to be certain we claim to be init */
+       strncpy(argv[0], "init", strlen(argv[0])+1);
+       strncpy(argv[1], "\0", strlen(argv[1])+1);
 
        /* Now run everything that needs to be run */
 
index 22f4f2f..090fcc8 100644 (file)
@@ -31,6 +31,7 @@
 #include <string.h>
 #include <unistd.h>
 #include <sys/stat.h>
+//#include <sys/param.h>
 #include <mntent.h>
 
 
@@ -186,6 +187,7 @@ extern pid_t findInitPid();
 #if defined BB_INIT || defined BB_SYSLOGD
 extern int device_open(char *device, int mode);
 #endif
+extern void whine_if_fstab_is_missing();
 
 #if defined BB_FEATURE_MOUNT_LOOP
 extern int del_loop(const char *device);
diff --git a/mount.c b/mount.c
index c3e3bbd..37f789d 100644 (file)
--- a/mount.c
+++ b/mount.c
@@ -53,7 +53,7 @@
 #include <linux/loop.h>
 
 
-static int use_loop = 0;
+static int use_loop = FALSE;
 #endif
 
 extern const char mtab_file[]; /* Defined in utility.c */
@@ -114,13 +114,14 @@ do_mount(char *specialfile, char *dir, char *filesystemtype,
                 char *mtab_opts)
 {
        int status = 0;
+       char *lofile = NULL;
 
 #if defined BB_MTAB
        if (fakeIt == FALSE)
 #endif
        {
 #if defined BB_FEATURE_MOUNT_LOOP
-               if (use_loop) {
+               if (use_loop==TRUE) {
                        int loro = flags & MS_RDONLY;
                        char *lofile = specialfile;
 
@@ -137,6 +138,7 @@ do_mount(char *specialfile, char *dir, char *filesystemtype,
                                fprintf(stderr, "WARNING: loop device is read-only\n");
                                flags &= ~MS_RDONLY;
                        }
+                       use_loop = FALSE;
                }
 #endif
                status =
@@ -157,7 +159,7 @@ do_mount(char *specialfile, char *dir, char *filesystemtype,
 
        /* Bummer.  mount failed.  Clean up */
 #if defined BB_FEATURE_MOUNT_LOOP
-       if (specialfile != NULL) {
+       if (lofile != NULL) {
                del_loop(specialfile);
        }
 #endif
@@ -166,20 +168,6 @@ do_mount(char *specialfile, char *dir, char *filesystemtype,
 
 
 
-#if defined BB_MTAB
-#define whine_if_fstab_is_missing() {}
-#else
-extern void whine_if_fstab_is_missing()
-{
-       struct stat statBuf;
-
-       if (stat("/etc/fstab", &statBuf) < 0)
-               fprintf(stderr,
-                               "/etc/fstab file missing -- install one to name /dev/root.\n\n");
-}
-#endif
-
-
 /* Seperate standard mount options from the nonstandard string options */
 static void
 parse_mount_options(char *options, unsigned long *flags, char *strflags)
@@ -204,7 +192,7 @@ parse_mount_options(char *options, unsigned long *flags, char *strflags)
                }
 #if defined BB_FEATURE_MOUNT_LOOP
                if (gotone == FALSE && !strcasecmp("loop", options)) {  /* loop device support */
-                       use_loop = 1;
+                       use_loop = TRUE;
                        gotone = TRUE;
                }
 #endif
@@ -229,7 +217,7 @@ 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, int useMtab, int fakeIt,
-                 char *mtab_opts)
+                 char *mtab_opts, int whineOnErrors)
 {
        int status = 0;
 
@@ -270,9 +258,11 @@ mount_one(char *blockDevice, char *directory, char *filesystemType,
                                                  fakeIt, mtab_opts);
        }
 
-       if (status == FALSE) {
-               fprintf(stderr, "Mounting %s on %s failed: %s\n",
-                               blockDevice, directory, strerror(errno));
+       if (status == FALSE && whineOnErrors == TRUE) {
+               if (whineOnErrors == TRUE) {
+                       fprintf(stderr, "Mounting %s on %s failed: %s\n",
+                                       blockDevice, directory, strerror(errno));
+               }
                return (FALSE);
        }
        return (TRUE);
@@ -387,18 +377,28 @@ 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 /, 
+                       // If the file system isn't noauto, 
                        // 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,
+                               /* If the directory is /, try to remount
+                                * with the options specified in fstab */
+                               if (m->mnt_dir[0] == '/' && m->mnt_dir[1] == '\0') {
+                                       flags |= MS_REMOUNT;
+                               }
+                               if (mount_one(m->mnt_fsname, m->mnt_dir, m->mnt_type,
                                                  flags, string_flags, useMtab, fakeIt,
-                                                 extra_opts);
+                                                 extra_opts, FALSE)) 
+                               {
+                                       /* Try again, but this time try a remount */
+                                       mount_one(m->mnt_fsname, m->mnt_dir, m->mnt_type,
+                                                         flags|MS_REMOUNT, string_flags, useMtab, fakeIt,
+                                                         extra_opts, TRUE);
+                               }
                        }
                }
                endmntent(f);
@@ -414,7 +414,7 @@ extern int mount_main(int argc, char **argv)
 #endif
                        exit(mount_one(device, directory, filesystemType,
                                                   flags, string_flags, useMtab, fakeIt,
-                                                  extra_opts));
+                                                  extra_opts, TRUE));
                } else {
                        goto goodbye;
                }
index 6bda222..bc096ea 100644 (file)
@@ -36,13 +36,16 @@ static int whichApp;
 static const char *appName;
 
 static const char swapoff_usage[] =
+       "swapoff [OPTION] [device]\n\n"
+       "Stop swapping virtual memory pages on the given device.\n\n"
+       "Options:\n"
+       "\t-a\tStop swapping on all swap devices\n";
 
-       "swapoff device\n"
-       "\nStop swapping virtual memory pages on the given device.\n";
 static const char swapon_usage[] =
-
-       "swapon device\n"
-       "\nStart swapping virtual memory pages on the given device.\n";
+       "swapon [OPTION] [device]\n\n"
+       "Start swapping virtual memory pages on the given device.\n\n"
+       "Options:\n"
+       "\t-a\tStart swapping on all swap devices\n";
 
 
 #define SWAPON_APP   1
@@ -85,12 +88,6 @@ static void do_em_all()
 
 extern int swap_on_off_main(int argc, char **argv)
 {
-       struct stat statBuf;
-
-       if (stat("/etc/fstab", &statBuf) < 0)
-               fprintf(stderr,
-                               "/etc/fstab file missing -- Please install one.\n\n");
-
        if (strcmp(*argv, "swapon") == 0) {
                appName = *argv;
                whichApp = SWAPON_APP;
@@ -100,8 +97,9 @@ extern int swap_on_off_main(int argc, char **argv)
                whichApp = SWAPOFF_APP;
        }
 
-       if (argc < 2)
+       if (argc != 2) {
                goto usage_and_exit;
+       }
        argc--;
        argv++;
 
@@ -110,6 +108,7 @@ extern int swap_on_off_main(int argc, char **argv)
                while (*++(*argv))
                        switch (**argv) {
                        case 'a':
+                               whine_if_fstab_is_missing();
                                do_em_all();
                                break;
                        default:
index a2ca8c7..b58b1a0 100644 (file)
--- a/umount.c
+++ b/umount.c
@@ -29,6 +29,7 @@
 #include <fstab.h>
 #include <errno.h>
 
+
 static const char umount_usage[] =
        "umount [flags] filesystem|directory\n\n"
        "Flags:\n" "\t-a:\tUnmount all file systems"
@@ -57,7 +58,99 @@ static int umountAll = FALSE;
 static int doRemount = FALSE;
 extern const char mtab_file[]; /* Defined in utility.c */
 
-#define MIN(x,y) (x > y ? x : y)
+
+/* These functions are here because the getmntent functions do not appear
+ * to be re-entrant, which leads to all sorts of problems when we try to
+ * use them recursively - randolph
+ */
+void mtab_read(void)
+{
+       struct _mtab_entry_t *entry = NULL;
+       struct mntent *e;
+       FILE *fp;
+
+       if (mtab_cache != NULL)
+               return;
+
+       if ((fp = setmntent(mtab_file, "r")) == NULL) {
+               fprintf(stderr, "Cannot open %s\n", mtab_file);
+               return;
+       }
+       while ((e = getmntent(fp))) {
+               entry = malloc(sizeof(struct _mtab_entry_t));
+
+               entry->device = strdup(e->mnt_fsname);
+               entry->mountpt = strdup(e->mnt_dir);
+               entry->next = mtab_cache;
+               mtab_cache = entry;
+       }
+       endmntent(fp);
+}
+
+char *mtab_getinfo(const char *match, const char which)
+{
+       struct _mtab_entry_t *cur = mtab_cache;
+
+       while (cur) {
+               if (strcmp(cur->mountpt, match) == 0 ||
+                       strcmp(cur->device, match) == 0) {
+                       if (which == MTAB_GETMOUNTPT) {
+                               return cur->mountpt;
+                       } else {
+#if !defined BB_MTAB
+                               if (strcmp(cur->device, "/dev/root") == 0) {
+                                       struct fstab *fstabItem;
+
+                                       fstabItem = getfsfile("/");
+                                       if (fstabItem != NULL)
+                                               return fstabItem->fs_spec;
+                               }
+#endif
+                               return cur->device;
+                       }
+               }
+               cur = cur->next;
+       }
+       return NULL;
+}
+
+char *mtab_first(void **iter)
+{
+       struct _mtab_entry_t *mtab_iter;
+
+       if (!iter)
+               return NULL;
+       mtab_iter = mtab_cache;
+       *iter = (void *) mtab_iter;
+       return mtab_next(iter);
+}
+
+char *mtab_next(void **iter)
+{
+       char *mp;
+
+       if (iter == NULL || *iter == NULL)
+               return NULL;
+       mp = ((struct _mtab_entry_t *) (*iter))->mountpt;
+       *iter = (void *) ((struct _mtab_entry_t *) (*iter))->next;
+       return mp;
+}
+
+void mtab_free(void)
+{
+       struct _mtab_entry_t *this, *next;
+
+       this = mtab_cache;
+       while (this) {
+               next = this->next;
+               if (this->device)
+                       free(this->device);
+               if (this->mountpt)
+                       free(this->mountpt);
+               free(this);
+               this = next;
+       }
+}
 
 static int do_umount(const char *name, int useMtab)
 {
@@ -105,6 +198,9 @@ static int umount_all(int useMtab)
        void *iter;
 
        for (mountpt = mtab_first(&iter); mountpt; mountpt = mtab_next(&iter)) {
+               /* Never umount /proc on a umount -a */
+               if (strstr(mountpt, "proc")!= NULL)
+                       continue;
                status = do_umount(mountpt, useMtab);
                if (status != 0) {
                        /* Don't bother retrying the umount on busy devices */
@@ -163,97 +259,3 @@ extern int umount_main(int argc, char **argv)
        }
 }
 
-
-
-/* These functions are here because the getmntent functions do not appear
- * to be re-entrant, which leads to all sorts of problems when we try to
- * use them recursively - randolph
- */
-void mtab_read(void)
-{
-       struct _mtab_entry_t *entry = NULL;
-       struct mntent *e;
-       FILE *fp;
-
-       if (mtab_cache != NULL)
-               return;
-
-       if ((fp = setmntent(mtab_file, "r")) == NULL) {
-               fprintf(stderr, "Cannot open %s\n", mtab_file);
-               return;
-       }
-       while ((e = getmntent(fp))) {
-               entry = malloc(sizeof(struct _mtab_entry_t));
-
-               entry->device = strdup(e->mnt_fsname);
-               entry->mountpt = strdup(e->mnt_dir);
-               entry->next = mtab_cache;
-               mtab_cache = entry;
-       }
-       endmntent(fp);
-}
-
-char *mtab_getinfo(const char *match, const char which)
-{
-       struct _mtab_entry_t *cur = mtab_cache;
-
-       while (cur) {
-               if (strcmp(cur->mountpt, match) == 0 ||
-                       strcmp(cur->device, match) == 0) {
-                       if (which == MTAB_GETMOUNTPT) {
-                               return cur->mountpt;
-                       } else {
-#if !defined BB_MTAB
-                               if (strcmp(cur->device, "/dev/root") == 0) {
-                                       struct fstab *fstabItem;
-
-                                       fstabItem = getfsfile("/");
-                                       if (fstabItem != NULL)
-                                               return fstabItem->fs_spec;
-                               }
-#endif
-                               return cur->device;
-                       }
-               }
-               cur = cur->next;
-       }
-       return NULL;
-}
-
-char *mtab_first(void **iter)
-{
-       struct _mtab_entry_t *mtab_iter;
-
-       if (!iter)
-               return NULL;
-       mtab_iter = mtab_cache;
-       *iter = (void *) mtab_iter;
-       return mtab_next(iter);
-}
-
-char *mtab_next(void **iter)
-{
-       char *mp;
-
-       if (iter == NULL || *iter == NULL)
-               return NULL;
-       mp = ((struct _mtab_entry_t *) (*iter))->mountpt;
-       *iter = (void *) ((struct _mtab_entry_t *) (*iter))->next;
-       return mp;
-}
-
-void mtab_free(void)
-{
-       struct _mtab_entry_t *this, *next;
-
-       this = mtab_cache;
-       while (this) {
-               next = this->next;
-               if (this->device)
-                       free(this->device);
-               if (this->mountpt)
-                       free(this->mountpt);
-               free(this);
-               this = next;
-       }
-}
index c3e3bbd..37f789d 100644 (file)
@@ -53,7 +53,7 @@
 #include <linux/loop.h>
 
 
-static int use_loop = 0;
+static int use_loop = FALSE;
 #endif
 
 extern const char mtab_file[]; /* Defined in utility.c */
@@ -114,13 +114,14 @@ do_mount(char *specialfile, char *dir, char *filesystemtype,
                 char *mtab_opts)
 {
        int status = 0;
+       char *lofile = NULL;
 
 #if defined BB_MTAB
        if (fakeIt == FALSE)
 #endif
        {
 #if defined BB_FEATURE_MOUNT_LOOP
-               if (use_loop) {
+               if (use_loop==TRUE) {
                        int loro = flags & MS_RDONLY;
                        char *lofile = specialfile;
 
@@ -137,6 +138,7 @@ do_mount(char *specialfile, char *dir, char *filesystemtype,
                                fprintf(stderr, "WARNING: loop device is read-only\n");
                                flags &= ~MS_RDONLY;
                        }
+                       use_loop = FALSE;
                }
 #endif
                status =
@@ -157,7 +159,7 @@ do_mount(char *specialfile, char *dir, char *filesystemtype,
 
        /* Bummer.  mount failed.  Clean up */
 #if defined BB_FEATURE_MOUNT_LOOP
-       if (specialfile != NULL) {
+       if (lofile != NULL) {
                del_loop(specialfile);
        }
 #endif
@@ -166,20 +168,6 @@ do_mount(char *specialfile, char *dir, char *filesystemtype,
 
 
 
-#if defined BB_MTAB
-#define whine_if_fstab_is_missing() {}
-#else
-extern void whine_if_fstab_is_missing()
-{
-       struct stat statBuf;
-
-       if (stat("/etc/fstab", &statBuf) < 0)
-               fprintf(stderr,
-                               "/etc/fstab file missing -- install one to name /dev/root.\n\n");
-}
-#endif
-
-
 /* Seperate standard mount options from the nonstandard string options */
 static void
 parse_mount_options(char *options, unsigned long *flags, char *strflags)
@@ -204,7 +192,7 @@ parse_mount_options(char *options, unsigned long *flags, char *strflags)
                }
 #if defined BB_FEATURE_MOUNT_LOOP
                if (gotone == FALSE && !strcasecmp("loop", options)) {  /* loop device support */
-                       use_loop = 1;
+                       use_loop = TRUE;
                        gotone = TRUE;
                }
 #endif
@@ -229,7 +217,7 @@ 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, int useMtab, int fakeIt,
-                 char *mtab_opts)
+                 char *mtab_opts, int whineOnErrors)
 {
        int status = 0;
 
@@ -270,9 +258,11 @@ mount_one(char *blockDevice, char *directory, char *filesystemType,
                                                  fakeIt, mtab_opts);
        }
 
-       if (status == FALSE) {
-               fprintf(stderr, "Mounting %s on %s failed: %s\n",
-                               blockDevice, directory, strerror(errno));
+       if (status == FALSE && whineOnErrors == TRUE) {
+               if (whineOnErrors == TRUE) {
+                       fprintf(stderr, "Mounting %s on %s failed: %s\n",
+                                       blockDevice, directory, strerror(errno));
+               }
                return (FALSE);
        }
        return (TRUE);
@@ -387,18 +377,28 @@ 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 /, 
+                       // If the file system isn't noauto, 
                        // 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,
+                               /* If the directory is /, try to remount
+                                * with the options specified in fstab */
+                               if (m->mnt_dir[0] == '/' && m->mnt_dir[1] == '\0') {
+                                       flags |= MS_REMOUNT;
+                               }
+                               if (mount_one(m->mnt_fsname, m->mnt_dir, m->mnt_type,
                                                  flags, string_flags, useMtab, fakeIt,
-                                                 extra_opts);
+                                                 extra_opts, FALSE)) 
+                               {
+                                       /* Try again, but this time try a remount */
+                                       mount_one(m->mnt_fsname, m->mnt_dir, m->mnt_type,
+                                                         flags|MS_REMOUNT, string_flags, useMtab, fakeIt,
+                                                         extra_opts, TRUE);
+                               }
                        }
                }
                endmntent(f);
@@ -414,7 +414,7 @@ extern int mount_main(int argc, char **argv)
 #endif
                        exit(mount_one(device, directory, filesystemType,
                                                   flags, string_flags, useMtab, fakeIt,
-                                                  extra_opts));
+                                                  extra_opts, TRUE));
                } else {
                        goto goodbye;
                }
index 6bda222..bc096ea 100644 (file)
@@ -36,13 +36,16 @@ static int whichApp;
 static const char *appName;
 
 static const char swapoff_usage[] =
+       "swapoff [OPTION] [device]\n\n"
+       "Stop swapping virtual memory pages on the given device.\n\n"
+       "Options:\n"
+       "\t-a\tStop swapping on all swap devices\n";
 
-       "swapoff device\n"
-       "\nStop swapping virtual memory pages on the given device.\n";
 static const char swapon_usage[] =
-
-       "swapon device\n"
-       "\nStart swapping virtual memory pages on the given device.\n";
+       "swapon [OPTION] [device]\n\n"
+       "Start swapping virtual memory pages on the given device.\n\n"
+       "Options:\n"
+       "\t-a\tStart swapping on all swap devices\n";
 
 
 #define SWAPON_APP   1
@@ -85,12 +88,6 @@ static void do_em_all()
 
 extern int swap_on_off_main(int argc, char **argv)
 {
-       struct stat statBuf;
-
-       if (stat("/etc/fstab", &statBuf) < 0)
-               fprintf(stderr,
-                               "/etc/fstab file missing -- Please install one.\n\n");
-
        if (strcmp(*argv, "swapon") == 0) {
                appName = *argv;
                whichApp = SWAPON_APP;
@@ -100,8 +97,9 @@ extern int swap_on_off_main(int argc, char **argv)
                whichApp = SWAPOFF_APP;
        }
 
-       if (argc < 2)
+       if (argc != 2) {
                goto usage_and_exit;
+       }
        argc--;
        argv++;
 
@@ -110,6 +108,7 @@ extern int swap_on_off_main(int argc, char **argv)
                while (*++(*argv))
                        switch (**argv) {
                        case 'a':
+                               whine_if_fstab_is_missing();
                                do_em_all();
                                break;
                        default:
index a2ca8c7..b58b1a0 100644 (file)
@@ -29,6 +29,7 @@
 #include <fstab.h>
 #include <errno.h>
 
+
 static const char umount_usage[] =
        "umount [flags] filesystem|directory\n\n"
        "Flags:\n" "\t-a:\tUnmount all file systems"
@@ -57,7 +58,99 @@ static int umountAll = FALSE;
 static int doRemount = FALSE;
 extern const char mtab_file[]; /* Defined in utility.c */
 
-#define MIN(x,y) (x > y ? x : y)
+
+/* These functions are here because the getmntent functions do not appear
+ * to be re-entrant, which leads to all sorts of problems when we try to
+ * use them recursively - randolph
+ */
+void mtab_read(void)
+{
+       struct _mtab_entry_t *entry = NULL;
+       struct mntent *e;
+       FILE *fp;
+
+       if (mtab_cache != NULL)
+               return;
+
+       if ((fp = setmntent(mtab_file, "r")) == NULL) {
+               fprintf(stderr, "Cannot open %s\n", mtab_file);
+               return;
+       }
+       while ((e = getmntent(fp))) {
+               entry = malloc(sizeof(struct _mtab_entry_t));
+
+               entry->device = strdup(e->mnt_fsname);
+               entry->mountpt = strdup(e->mnt_dir);
+               entry->next = mtab_cache;
+               mtab_cache = entry;
+       }
+       endmntent(fp);
+}
+
+char *mtab_getinfo(const char *match, const char which)
+{
+       struct _mtab_entry_t *cur = mtab_cache;
+
+       while (cur) {
+               if (strcmp(cur->mountpt, match) == 0 ||
+                       strcmp(cur->device, match) == 0) {
+                       if (which == MTAB_GETMOUNTPT) {
+                               return cur->mountpt;
+                       } else {
+#if !defined BB_MTAB
+                               if (strcmp(cur->device, "/dev/root") == 0) {
+                                       struct fstab *fstabItem;
+
+                                       fstabItem = getfsfile("/");
+                                       if (fstabItem != NULL)
+                                               return fstabItem->fs_spec;
+                               }
+#endif
+                               return cur->device;
+                       }
+               }
+               cur = cur->next;
+       }
+       return NULL;
+}
+
+char *mtab_first(void **iter)
+{
+       struct _mtab_entry_t *mtab_iter;
+
+       if (!iter)
+               return NULL;
+       mtab_iter = mtab_cache;
+       *iter = (void *) mtab_iter;
+       return mtab_next(iter);
+}
+
+char *mtab_next(void **iter)
+{
+       char *mp;
+
+       if (iter == NULL || *iter == NULL)
+               return NULL;
+       mp = ((struct _mtab_entry_t *) (*iter))->mountpt;
+       *iter = (void *) ((struct _mtab_entry_t *) (*iter))->next;
+       return mp;
+}
+
+void mtab_free(void)
+{
+       struct _mtab_entry_t *this, *next;
+
+       this = mtab_cache;
+       while (this) {
+               next = this->next;
+               if (this->device)
+                       free(this->device);
+               if (this->mountpt)
+                       free(this->mountpt);
+               free(this);
+               this = next;
+       }
+}
 
 static int do_umount(const char *name, int useMtab)
 {
@@ -105,6 +198,9 @@ static int umount_all(int useMtab)
        void *iter;
 
        for (mountpt = mtab_first(&iter); mountpt; mountpt = mtab_next(&iter)) {
+               /* Never umount /proc on a umount -a */
+               if (strstr(mountpt, "proc")!= NULL)
+                       continue;
                status = do_umount(mountpt, useMtab);
                if (status != 0) {
                        /* Don't bother retrying the umount on busy devices */
@@ -163,97 +259,3 @@ extern int umount_main(int argc, char **argv)
        }
 }
 
-
-
-/* These functions are here because the getmntent functions do not appear
- * to be re-entrant, which leads to all sorts of problems when we try to
- * use them recursively - randolph
- */
-void mtab_read(void)
-{
-       struct _mtab_entry_t *entry = NULL;
-       struct mntent *e;
-       FILE *fp;
-
-       if (mtab_cache != NULL)
-               return;
-
-       if ((fp = setmntent(mtab_file, "r")) == NULL) {
-               fprintf(stderr, "Cannot open %s\n", mtab_file);
-               return;
-       }
-       while ((e = getmntent(fp))) {
-               entry = malloc(sizeof(struct _mtab_entry_t));
-
-               entry->device = strdup(e->mnt_fsname);
-               entry->mountpt = strdup(e->mnt_dir);
-               entry->next = mtab_cache;
-               mtab_cache = entry;
-       }
-       endmntent(fp);
-}
-
-char *mtab_getinfo(const char *match, const char which)
-{
-       struct _mtab_entry_t *cur = mtab_cache;
-
-       while (cur) {
-               if (strcmp(cur->mountpt, match) == 0 ||
-                       strcmp(cur->device, match) == 0) {
-                       if (which == MTAB_GETMOUNTPT) {
-                               return cur->mountpt;
-                       } else {
-#if !defined BB_MTAB
-                               if (strcmp(cur->device, "/dev/root") == 0) {
-                                       struct fstab *fstabItem;
-
-                                       fstabItem = getfsfile("/");
-                                       if (fstabItem != NULL)
-                                               return fstabItem->fs_spec;
-                               }
-#endif
-                               return cur->device;
-                       }
-               }
-               cur = cur->next;
-       }
-       return NULL;
-}
-
-char *mtab_first(void **iter)
-{
-       struct _mtab_entry_t *mtab_iter;
-
-       if (!iter)
-               return NULL;
-       mtab_iter = mtab_cache;
-       *iter = (void *) mtab_iter;
-       return mtab_next(iter);
-}
-
-char *mtab_next(void **iter)
-{
-       char *mp;
-
-       if (iter == NULL || *iter == NULL)
-               return NULL;
-       mp = ((struct _mtab_entry_t *) (*iter))->mountpt;
-       *iter = (void *) ((struct _mtab_entry_t *) (*iter))->next;
-       return mp;
-}
-
-void mtab_free(void)
-{
-       struct _mtab_entry_t *this, *next;
-
-       this = mtab_cache;
-       while (this) {
-               next = this->next;
-               if (this->device)
-                       free(this->device);
-               if (this->mountpt)
-                       free(this->mountpt);
-               free(this);
-               this = next;
-       }
-}
index 7f46f9b..00a1c69 100644 (file)
--- a/utility.c
+++ b/utility.c
@@ -1298,5 +1298,19 @@ extern char *find_unused_loop_device(void)
 }
 #endif                                                 /* BB_FEATURE_MOUNT_LOOP */
 
+#if defined BB_MTAB
+#define whine_if_fstab_is_missing() {}
+#else
+extern void whine_if_fstab_is_missing()
+{
+       struct stat statBuf;
+
+       if (stat("/etc/fstab", &statBuf) < 0)
+               fprintf(stderr,
+                               "/etc/fstab file missing -- install one to name /dev/root.\n\n");
+}
+#endif
+
+
 
 /* END CODE */