Fix some formatting
[oweals/busybox.git] / init.c
diff --git a/init.c b/init.c
index f38d154b7657f843fa5b4ab538b40e916e898d8a..5d0d924adbd894ee00ac8a8b688f6a97d36651a8 100644 (file)
--- a/init.c
+++ b/init.c
@@ -27,7 +27,7 @@
 #define DEBUG_INIT
 */
 
-#include "internal.h"
+#include "busybox.h"
 #include <stdio.h>
 #include <stdlib.h>
 #include <errno.h>
@@ -37,6 +37,7 @@
 #include <string.h>
 #include <termios.h>
 #include <unistd.h>
+#include <limits.h>
 #include <sys/fcntl.h>
 #include <sys/ioctl.h>
 #include <sys/mount.h>
 # include <sys/syslog.h>
 #endif
 
+#define bb_need_full_version
+#define BB_DECLARE_EXTERN
+#include "messages.c"
+
 /* From <linux/vt.h> */
 struct vt_stat {
        unsigned short v_active;        /* active vt */
        unsigned short v_signal;        /* signal to send */
        unsigned short v_state;         /* vt bitmask */
 };
-#define VT_GETSTATE     0x5603  /* get global vt state info */
+static const int VT_GETSTATE = 0x5603;  /* get global vt state info */
 
 /* From <linux/serial.h> */
 struct serial_struct {
@@ -75,12 +80,12 @@ struct serial_struct {
 
 
 #ifndef RB_HALT_SYSTEM
-#define RB_HALT_SYSTEM  0xcdef0123
-#define RB_ENABLE_CAD   0x89abcdef
-#define RB_DISABLE_CAD  0
+static const int RB_HALT_SYSTEM = 0xcdef0123;
+static const int RB_ENABLE_CAD = 0x89abcdef;
+static const int RB_DISABLE_CAD = 0;
 #define RB_POWER_OFF    0x4321fedc
-#define RB_AUTOBOOT     0x01234567
-#if defined(__GLIBC__)
+static const int RB_AUTOBOOT = 0x01234567;
+#if defined(__GLIBC__) || defined (__UCLIBC__)
 #include <sys/reboot.h>
   #define init_reboot(magic) reboot(magic)
 #else
@@ -110,23 +115,27 @@ struct serial_struct {
 #if defined(__GLIBC__)
 #include <sys/kdaemon.h>
 #else
+#include <sys/syscall.h>
+#include <linux/unistd.h>
 static _syscall2(int, bdflush, int, func, int, data);
 #endif                                                 /* __GLIBC__ */
 
 
 #define VT_PRIMARY   "/dev/tty1"     /* Primary virtual console */
 #define VT_SECONDARY "/dev/tty2"     /* Virtual console */
-#define VT_LOG       "/dev/tty3"     /* Virtual console */
+#define VT_THIRD     "/dev/tty3"     /* Virtual console */
+#define VT_FOURTH    "/dev/tty4"     /* Virtual console */
+#define VT_LOG       "/dev/tty5"     /* Virtual console */
 #define SERIAL_CON0  "/dev/ttyS0"    /* Primary serial console */
 #define SERIAL_CON1  "/dev/ttyS1"    /* Serial console */
-#define SHELL        "/bin/sh"      /* Default shell */
+#define SHELL        "-/bin/sh"             /* Default shell */
 #define INITTAB      "/etc/inittab"  /* inittab file location */
 #ifndef INIT_SCRIPT
 #define INIT_SCRIPT  "/etc/init.d/rcS"   /* Default sysinit script. */
 #endif
 
-#define LOG     0x1
-#define CONSOLE 0x2
+static const int LOG = 0x1;
+static const int CONSOLE = 0x2;
 
 /* Allowed init action types */
 typedef enum {
@@ -151,7 +160,7 @@ static const struct initActionType actions[] = {
        {"wait", WAIT},
        {"once", ONCE},
        {"ctrlaltdel", CTRLALTDEL},
-       {0}
+       {0, 0}
 };
 
 /* Set up a linked list of initActions, to be read from inittab */
@@ -167,6 +176,8 @@ initAction *initActionList = NULL;
 
 
 static char *secondConsole = VT_SECONDARY;
+static char *thirdConsole  = VT_THIRD;
+static char *fourthConsole = VT_FOURTH;
 static char *log           = VT_LOG;
 static int  kernelVersion  = 0;
 static char termType[32]   = "TERM=linux";
@@ -280,33 +291,27 @@ void set_term(int fd)
        tcsetattr(fd, TCSANOW, &tty);
 }
 
-/* How much memory does this machine have? */
+/* How much memory does this machine have?
+   Units are kBytes to avoid overflow on 4GB machines */
 static int check_free_memory()
 {
        struct sysinfo info;
+       unsigned int result, u, s=10;
 
-       /* Pre initialize mem_unit in case this kernel is something prior to
-        * the linux 2.4 kernel (which will actually fill in mem_unit... */
-       sysinfo(&info);
        if (sysinfo(&info) != 0) {
-               printf("Error checking free memory: %s\n", strerror(errno));
+               perror_msg("Error checking free memory: ");
                return -1;
        }
-       if (info.mem_unit==0) {
-               /* Looks like we have a kernel prior to Linux 2.4.x */
-               info.mem_unit=1024;
-               info.totalram/=info.mem_unit;
-               info.totalswap/=info.mem_unit;
-       } else {
-               /* Bah. Linux 2.4.x completely changed sysinfo. This can in theory
-               overflow a 32 bit unsigned long, but who puts more then 4GiB ram+swap
-               on an embedded system? */
-               info.mem_unit/=1024;
-               info.totalram*=info.mem_unit;
-               info.totalswap*=info.mem_unit;
-       }
 
-       return(info.totalram+info.totalswap);
+       /* Kernels 2.0.x and 2.2.x return info.mem_unit==0 with values in bytes.
+        * Kernels 2.4.0 return info.mem_unit in bytes. */
+       u = info.mem_unit;
+       if (u==0) u=1;
+       while ( (u&1) == 0 && s > 0 ) { u>>=1; s--; }
+       result = (info.totalram>>s) + (info.totalswap>>s);
+       result = result*u;
+       if (result < 0) result = INT_MAX;
+       return result;
 }
 
 static void console_init()
@@ -370,11 +375,13 @@ static void console_init()
                /* Perhaps we should panic here? */
                snprintf(console, sizeof(console) - 1, "/dev/null");
        } else {
-               /* check for serial console and disable logging to tty3 & running a
-                  * shell to tty2 */
+               /* check for serial console and disable logging to tty5 & running a
+                  * shell to tty2-4 */
                if (ioctl(0, TIOCGSERIAL, &sr) == 0) {
                        log = NULL;
                        secondConsole = NULL;
+                       thirdConsole = NULL;
+                       fourthConsole = NULL;
                        /* Force the TERM setting to vt102 for serial console --
                         * iff TERM is set to linux (the default) */
                        if (strcmp( termType, "TERM=linux" ) == 0)
@@ -392,10 +399,14 @@ static pid_t run(char *command, char *terminal, int get_enter)
        int i, fd;
        pid_t pid;
        char *tmpCmd;
-       char *cmd[255];
+        char *cmd[255], *cmdpath;
        char buf[255];
        static const char press_enter[] =
 
+#ifdef CUSTOMIZED_BANNER
+#include CUSTOMIZED_BANNER
+#endif
+
                "\nPlease press Enter to activate this console. ";
        char *environment[] = {
                "HOME=/",
@@ -406,9 +417,9 @@ static pid_t run(char *command, char *terminal, int get_enter)
                0
        };
 
-
        if ((pid = fork()) == 0) {
                /* Clean up */
+               ioctl(0, TIOCNOTTY, 0);
                close(0);
                close(1);
                close(2);
@@ -428,7 +439,7 @@ static pid_t run(char *command, char *terminal, int get_enter)
                dup2(fd, 0);
                dup2(fd, 1);
                dup2(fd, 2);
-               ioctl(0, TIOCSCTTY, 0);
+               ioctl(0, TIOCSCTTY, 1);
                tcsetpgrp(0, getpgrp());
                set_term(0);
 
@@ -441,14 +452,13 @@ static pid_t run(char *command, char *terminal, int get_enter)
                         * be allowed to start a shell or whatever an init script 
                         * specifies.
                         */
-                       char c;
 #ifdef DEBUG_INIT
                        pid_t shell_pgid = getpid();
                        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);
+                       getc(stdin);
                }
 
 #ifdef DEBUG_INIT
@@ -478,6 +488,34 @@ static pid_t run(char *command, char *terminal, int get_enter)
                        cmd[i] = NULL;
                }
 
+               cmdpath = cmd[0];
+
+               /*
+                   Interactive shells want to see a dash in argv[0].  This
+                   typically is handled by login, argv will be setup this 
+                   way if a dash appears at the front of the command path 
+                  (like "-/bin/sh").
+               */
+
+               if (*cmdpath == '-') {
+                       char *s;
+
+                       /* skip over the dash */
+                         ++cmdpath;
+
+                       /* find the last component in the command pathname */
+                                                s = get_last_path_component(cmdpath);
+
+                       /* make a new argv[0] */
+                       if ((cmd[0] = malloc(strlen(s)+2)) == NULL) {
+                               message(LOG | CONSOLE, "malloc failed");
+                               cmd[0] = cmdpath;
+                       } else {
+                               cmd[0][0] = '-';
+                               strcpy(cmd[0]+1, s);
+                       }
+               }
+
 #if defined BB_FEATURE_INIT_COREDUMPS
                {
                        struct stat sb;
@@ -492,11 +530,11 @@ static pid_t run(char *command, char *terminal, int get_enter)
 
                /* Now run it.  The new program will take over this PID, 
                 * so nothing further in init.c should be run. */
-               execve(cmd[0], cmd, environment);
+                execve(cmdpath, cmd, environment);
 
-               /* We're still here?  Some error happened. */
-               message(LOG | CONSOLE, "Bummer, could not run '%s': %s\n", cmd[0],
-                               strerror(errno));
+                /* We're still here?  Some error happened. */
+                message(LOG | CONSOLE, "Bummer, could not run '%s': %s\n", cmdpath,
+                                strerror(errno));
                exit(-1);
        }
        return pid;
@@ -626,6 +664,10 @@ static void reboot_signal(int sig)
 
 #if defined BB_FEATURE_INIT_CHROOT
 
+#warning BB_FEATURE_INIT_CHROOT is out of date and should be rewritten to us
+#warning pivot root instead.  Do not even bother till this work is done...
+#warning You have been warned.
+
 #if ! defined BB_FEATURE_USE_PROCFS
 #error Sorry, I depend on the /proc filesystem right now.
 #endif
@@ -784,14 +826,20 @@ void parse_inittab(void)
                /* No inittab file -- set up some default behavior */
 #endif
                /* Swapoff on halt/reboot */
-               new_initAction(CTRLALTDEL, "/sbin/swapoff -a > /dev/null 2>&1", console);
+               new_initAction(CTRLALTDEL, "/sbin/swapoff -a", console);
                /* Umount all filesystems on halt/reboot */
-               new_initAction(CTRLALTDEL, "/bin/umount -a -r > /dev/null 2>&1", console);
+               new_initAction(CTRLALTDEL, "/bin/umount -a -r", console);
                /* Askfirst shell on tty1 */
                new_initAction(ASKFIRST, SHELL, console);
                /* Askfirst shell on tty2 */
                if (secondConsole != NULL)
                        new_initAction(ASKFIRST, SHELL, secondConsole);
+               /* Askfirst shell on tty3 */
+               if (thirdConsole != NULL)
+                       new_initAction(ASKFIRST, SHELL, thirdConsole);
+               /* Askfirst shell on tty4 */
+               if (fourthConsole != NULL)
+                       new_initAction(ASKFIRST, SHELL, fourthConsole);
                /* sysinit */
                new_initAction(SYSINIT, INIT_SCRIPT, console);
 
@@ -938,16 +986,14 @@ extern int init_main(int argc, char **argv)
                        CONSOLE|
 #endif
                        LOG,
-                       "init started:  BusyBox v%s (%s) multi-call binary\r\n",
-                       BB_VER, BB_BT);
+                       "init started:  %s\r\n", full_version);
 #else
        message(
 #if ! defined BB_FEATURE_EXTRA_QUIET
                        CONSOLE|
 #endif
                        LOG,
-                       "init(%d) started:  BusyBox v%s (%s) multi-call binary\r\n",
-                       getpid(), BB_VER, BB_BT);
+                       "init(%d) started:  %s\r\n", getpid(), full_version);
 #endif
 
 
@@ -957,9 +1003,13 @@ extern int init_main(int argc, char **argv)
        /* Check if we are supposed to be in single user mode */
        if (argc > 1 && (!strcmp(argv[1], "single") ||
                                         !strcmp(argv[1], "-s") || !strcmp(argv[1], "1"))) {
-               /* Ask first then start a shell on tty2 */
+               /* Ask first then start a shell on tty2-4 */
                if (secondConsole != NULL)
                        new_initAction(ASKFIRST, SHELL, secondConsole);
+               if (thirdConsole != NULL)
+                       new_initAction(ASKFIRST, SHELL, thirdConsole);
+               if (fourthConsole != NULL)
+                       new_initAction(ASKFIRST, SHELL, fourthConsole);
                /* Start a shell on tty1 */
                new_initAction(RESPAWN, SHELL, console);
        } else {
@@ -973,7 +1023,8 @@ extern int init_main(int argc, char **argv)
        }
 
        /* Fix up argv[0] to be certain we claim to be init */
-       strncpy(argv[0], "init", strlen(argv[0])+1);
+       argv[0]="init";
+
        if (argc > 1)
                strncpy(argv[1], "\0", strlen(argv[1])+1);