#include <sys/types.h>
#include <sys/wait.h>
#include "busybox.h"
-#define bb_need_full_version
-#define BB_DECLARE_EXTERN
-#include "messages.c"
#ifdef BB_SYSLOGD
# include <sys/syslog.h>
#endif
static const int RB_DISABLE_CAD = 0;
#define RB_POWER_OFF 0x4321fedc
static const int RB_AUTOBOOT = 0x01234567;
-#if defined(__GLIBC__) || defined (__UCLIBC__)
-#include <sys/reboot.h>
+#endif
+
+#if __GNU_LIBRARY__ > 5
+ #include <sys/reboot.h>
#define init_reboot(magic) reboot(magic)
#else
#define init_reboot(magic) reboot(0xfee1dead, 672274793, magic)
#endif
-#endif
#ifndef _PATH_STDPATH
#define _PATH_STDPATH "/usr/bin:/bin:/usr/sbin:/sbin"
#define KERNEL_VERSION(a,b,c) (((a) << 16) + ((b) << 8) + (c))
-#if defined(__GLIBC__)
-#include <sys/kdaemon.h>
+#if __GNU_LIBRARY__ > 5
+ #include <sys/kdaemon.h>
#else
-#include <sys/syscall.h>
-#include <linux/unistd.h>
-static _syscall2(int, bdflush, int, func, int, data);
-#endif /* __GLIBC__ */
+ extern int bdflush (int func, long int data);
+#endif
#define VT_PRIMARY "/dev/tty1" /* Primary 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 LOGIN_SHELL "-" SHELL /* Default login shell */
#define INITTAB "/etc/inittab" /* inittab file location */
#ifndef INIT_SCRIPT
#define INIT_SCRIPT "/etc/init.d/rcS" /* Default sysinit script. */
ASKFIRST,
WAIT,
ONCE,
- CTRLALTDEL
+ CTRLALTDEL,
+ SHUTDOWN
} initActionEnum;
/* A mapping between "inittab" action name strings and action type codes. */
{"wait", WAIT},
{"once", ONCE},
{"ctrlaltdel", CTRLALTDEL},
+ {"shutdown", SHUTDOWN},
{0, 0}
};
static void delete_initAction(initAction * action);
-
+static void loop_forever()
+{
+ while (1)
+ sleep (1);
+}
/* Print a message to the specified device.
* Device may be bitwise-or'd from LOG | CONSOLE */
/* Make it be sane */
tty.c_cflag &= CBAUD|CBAUDEX|CSIZE|CSTOPB|PARENB|PARODD;
- tty.c_cflag |= HUPCL|CLOCAL;
+ tty.c_cflag |= CREAD|HUPCL|CLOCAL;
+
/* input modes */
tty.c_iflag = ICRNL | IXON | IXOFF;
}
if ((s = getenv("CONSOLE")) != NULL) {
- snprintf(console, sizeof(console) - 1, "%s", s);
+ safe_strncpy(console, s, sizeof(console));
}
#if #cpu(sparc)
/* sparc kernel supports console=tty[ab] parameter which is also
else if ((s = getenv("console")) != NULL) {
/* remap tty[ab] to /dev/ttyS[01] */
if (strcmp(s, "ttya") == 0)
- snprintf(console, sizeof(console) - 1, "%s", SERIAL_CON0);
+ safe_strncpy(console, SERIAL_CON0, sizeof(console));
else if (strcmp(s, "ttyb") == 0)
- snprintf(console, sizeof(console) - 1, "%s", SERIAL_CON1);
+ safe_strncpy(console, SERIAL_CON1, sizeof(console));
}
#endif
else {
snprintf(console, sizeof(console) - 1, "/dev/tty%d",
vt.v_active);
} else {
- snprintf(console, sizeof(console) - 1, "%s", _PATH_CONSOLE);
+ safe_strncpy(console, _PATH_CONSOLE, sizeof(console));
tried_devcons++;
}
}
/* Can't open selected console -- try /dev/console */
if (!tried_devcons) {
tried_devcons++;
- snprintf(console, sizeof(console) - 1, "%s", _PATH_CONSOLE);
+ safe_strncpy(console, _PATH_CONSOLE, sizeof(console));
continue;
}
/* Can't open selected console -- try vt1 */
if (!tried_vtprimary) {
tried_vtprimary++;
- snprintf(console, sizeof(console) - 1, "%s", VT_PRIMARY);
+ safe_strncpy(console, VT_PRIMARY, sizeof(console));
continue;
}
break;
}
if (fd < 0) {
/* Perhaps we should panic here? */
- snprintf(console, sizeof(console) - 1, "/dev/null");
+ safe_strncpy(console, "/dev/null", sizeof(console));
} else {
/* check for serial console and disable logging to tty5 & running a
* shell to tty2-4 */
/* Force the TERM setting to vt102 for serial console --
* iff TERM is set to linux (the default) */
if (strcmp( termType, "TERM=linux" ) == 0)
- snprintf(termType, sizeof(termType) - 1, "TERM=vt102");
+ safe_strncpy(termType, "TERM=vt102", sizeof(termType));
message(LOG | CONSOLE,
"serial console detected. Disabling virtual terminals.\r\n");
}
termType,
"HOME=/",
"PATH=/usr/bin:/bin:/usr/sbin:/sbin",
- "SHELL=/bin/sh",
+ "SHELL=" SHELL,
"USER=root",
NULL
};
*/
if (*cmdpath == '-') {
- char *s;
/* skip over the dash */
++cmdpath;
goodnight:
message(CONSOLE,
"Sorry, your computer does not have enough memory.\r\n");
- while (1)
- sleep(1);
+ loop_forever();
}
/* Run all commands to be run right before halt/reboot */
-static void run_lastAction(void)
+static void run_actions(initActionEnum action)
{
initAction *a, *tmp;
for (a = initActionList; a; a = tmp) {
tmp = a->nextPtr;
- if (a->action == CTRLALTDEL) {
+ if (a->action == action) {
waitfor(a->process, a->console, FALSE);
delete_initAction(a);
}
kill(-1, SIGKILL);
sleep(1);
- /* run everything to be run at "ctrlaltdel" */
- run_lastAction();
+ /* run everything to be run at "shutdown" */
+ run_actions(SHUTDOWN);
sync();
if (kernelVersion > 0 && kernelVersion <= KERNEL_VERSION(2,2,11)) {
init_reboot(RB_POWER_OFF);
else
init_reboot(RB_HALT_SYSTEM);
- exit(0);
+
+ loop_forever();
}
static void reboot_signal(int sig)
sleep(2);
init_reboot(RB_AUTOBOOT);
- exit(0);
+
+ loop_forever();
+}
+
+static void ctrlaltdel_signal(int sig)
+{
+ run_actions(CTRLALTDEL);
}
#endif /* ! DEBUG_INIT */
newAction = calloc((size_t) (1), sizeof(initAction));
if (!newAction) {
message(LOG | CONSOLE, "Memory allocation failure\n");
- while (1)
- sleep(1);
+ loop_forever();
}
newAction->nextPtr = initActionList;
initActionList = newAction;
/* NOTE that if BB_FEATURE_USE_INITTAB is NOT defined,
* then parse_inittab() simply adds in some default
- * actions(i.e runs INIT_SCRIPT and then starts a pair
+ * actions(i.e., runs INIT_SCRIPT and then starts a pair
* of "askfirst" shells). If BB_FEATURE_USE_INITTAB
* _is_ defined, but /etc/inittab is missing, this
* results in the same set of default behaviors.
if (file == NULL) {
/* No inittab file -- set up some default behavior */
#endif
+ /* Reboot on Ctrl-Alt-Del */
+ new_initAction(CTRLALTDEL, "/sbin/reboot", console);
/* Swapoff on halt/reboot */
- new_initAction(CTRLALTDEL, "/sbin/swapoff -a", console);
+ new_initAction(SHUTDOWN, "/sbin/swapoff -a", console);
/* Umount all filesystems on halt/reboot */
- new_initAction(CTRLALTDEL, "/bin/umount -a -r", console);
+ new_initAction(SHUTDOWN, "/bin/umount -a -r", console);
/* Askfirst shell on tty1 */
- new_initAction(ASKFIRST, SHELL, console);
+ new_initAction(ASKFIRST, LOGIN_SHELL, console);
/* Askfirst shell on tty2 */
if (secondConsole != NULL)
- new_initAction(ASKFIRST, SHELL, secondConsole);
+ new_initAction(ASKFIRST, LOGIN_SHELL, secondConsole);
/* Askfirst shell on tty3 */
if (thirdConsole != NULL)
- new_initAction(ASKFIRST, SHELL, thirdConsole);
+ new_initAction(ASKFIRST, LOGIN_SHELL, thirdConsole);
/* Askfirst shell on tty4 */
if (fourthConsole != NULL)
- new_initAction(ASKFIRST, SHELL, fourthConsole);
+ new_initAction(ASKFIRST, LOGIN_SHELL, fourthConsole);
/* sysinit */
new_initAction(SYSINIT, INIT_SCRIPT, console);
* clear all of these in run() */
signal(SIGUSR1, halt_signal);
signal(SIGUSR2, halt_signal);
- signal(SIGINT, reboot_signal);
+ signal(SIGINT, ctrlaltdel_signal);
signal(SIGTERM, reboot_signal);
/* Turn off rebooting via CTL-ALT-DEL -- we get a
!strcmp(argv[1], "-s") || !strcmp(argv[1], "1"))) {
/* Ask first then start a shell on tty2-4 */
if (secondConsole != NULL)
- new_initAction(ASKFIRST, SHELL, secondConsole);
+ new_initAction(ASKFIRST, LOGIN_SHELL, secondConsole);
if (thirdConsole != NULL)
- new_initAction(ASKFIRST, SHELL, thirdConsole);
+ new_initAction(ASKFIRST, LOGIN_SHELL, thirdConsole);
if (fourthConsole != NULL)
- new_initAction(ASKFIRST, SHELL, fourthConsole);
+ new_initAction(ASKFIRST, LOGIN_SHELL, fourthConsole);
/* Start a shell on tty1 */
- new_initAction(RESPAWN, SHELL, console);
+ new_initAction(RESPAWN, LOGIN_SHELL, console);
} else {
/* Not in single user mode -- see what inittab says */
/* NOTE that if BB_FEATURE_USE_INITTAB is NOT defined,
* then parse_inittab() simply adds in some default
- * actions(i.e runs INIT_SCRIPT and then starts a pair
+ * actions(i.e., runs INIT_SCRIPT and then starts a pair
* of "askfirst" shells */
parse_inittab();
}
if (initActionList == NULL) {
message(LOG | CONSOLE,
"No more tasks for init -- sleeping forever.\n");
- while (1)
- sleep(1);
+ loop_forever();
}
/* Now run the looping stuff for the rest of forever */