#include <string.h>
#include <termios.h>
#include <unistd.h>
-#include <asm/types.h>
-#include <linux/serial.h> /* for serial_struct */
-#include <linux/version.h>
-#include <linux/reboot.h>
-#include <linux/unistd.h>
-#include <sys/sysinfo.h> /* For check_free_memory() */
#include <sys/fcntl.h>
#include <sys/ioctl.h>
#include <sys/mount.h>
-//#include <sys/sysmacros.h>
#include <sys/types.h>
-#include <sys/vt.h> /* for vt_stat */
#include <sys/wait.h>
#ifdef BB_SYSLOGD
# 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 */
+
+/* From <linux/serial.h> */
+struct serial_struct {
+ int type;
+ int line;
+ int port;
+ int irq;
+ int flags;
+ int xmit_fifo_size;
+ int custom_divisor;
+ int baud_base;
+ unsigned short close_delay;
+ char reserved_char[2];
+ int hub6;
+ unsigned short closing_wait; /* time to wait before closing */
+ unsigned short closing_wait2; /* no longer used... */
+ int reserved[4];
+};
+
+
#ifndef RB_HALT_SYSTEM
#define RB_HALT_SYSTEM 0xcdef0123
#include <sys/time.h>
#endif
-#ifndef KERNEL_VERSION
#define KERNEL_VERSION(a,b,c) (((a) << 16) + ((b) << 8) + (c))
-#endif
#if defined(__GLIBC__)
#include <sys/kdaemon.h>
#else
-_syscall2(int, bdflush, int, func, int, data);
+static _syscall2(int, bdflush, int, func, int, data);
#endif /* __GLIBC__ */
{"wait", WAIT},
{"once", ONCE},
{"ctrlaltdel", CTRLALTDEL},
- {0}
+ {0, 0}
};
/* Set up a linked list of initActions, to be read from inittab */
}
}
-#define CTRLCHAR(ch) ((ch)&0x1f)
-
/* Set terminal settings to reasonable defaults */
void set_term(int fd)
{
tcgetattr(fd, &tty);
/* set control chars */
- tty.c_cc[VINTR] = CTRLCHAR('C'); /* Ctrl-C */
- tty.c_cc[VQUIT] = CTRLCHAR('\\'); /* Ctrl-\ */
- tty.c_cc[VERASE] = CTRLCHAR('?'); /* Ctrl-? */
- tty.c_cc[VKILL] = CTRLCHAR('U'); /* Ctrl-U */
- tty.c_cc[VEOF] = CTRLCHAR('D'); /* Ctrl-D */
- tty.c_cc[VSTOP] = CTRLCHAR('S'); /* Ctrl-S */
- tty.c_cc[VSTART] = CTRLCHAR('Q'); /* Ctrl-Q */
- tty.c_cc[VSUSP] = CTRLCHAR('Z'); /* Ctrl-Z */
+ tty.c_cc[VINTR] = 3; /* C-c */
+ tty.c_cc[VQUIT] = 28; /* C-\ */
+ tty.c_cc[VERASE] = 127; /* C-? */
+ tty.c_cc[VKILL] = 21; /* C-u */
+ tty.c_cc[VEOF] = 4; /* C-d */
+ tty.c_cc[VSTART] = 17; /* C-q */
+ tty.c_cc[VSTOP] = 19; /* C-s */
+ tty.c_cc[VSUSP] = 26; /* C-z */
/* use line dicipline 0 */
tty.c_line = 0;
{
struct sysinfo info;
+ /* 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) {
- message(LOG, "Error checking free memory: %s\n", strerror(errno));
+ printf("Error checking free memory: %s\n", strerror(errno));
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)/1024);
+ return(info.totalram+info.totalswap);
}
static void console_init()
dup2(fd, 0);
dup2(fd, 1);
dup2(fd, 2);
+ ioctl(0, TIOCSCTTY, 0);
tcsetpgrp(0, getpgrp());
set_term(0);
run_lastAction();
sync();
- if (kernelVersion > 0 && kernelVersion <= 2 * 65536 + 2 * 256 + 11) {
+ if (kernelVersion > 0 && kernelVersion <= KERNEL_VERSION(2,2,11)) {
/* bdflush, kupdate not needed for kernels >2.2.11 */
bdflush(1, 0);
sync();
/* allow time for last message to reach serial console */
sleep(2);
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,2,0)
- if (sig == SIGUSR2)
+ if (sig == SIGUSR2 && kernelVersion >= KERNEL_VERSION(2,2,0))
init_reboot(RB_POWER_OFF);
else
-#endif
init_reboot(RB_HALT_SYSTEM);
exit(0);
}
#ifdef BB_FEATURE_USE_INITTAB
FILE *file;
char buf[256], lineAsRead[256], tmpConsole[256];
- char *p, *q, *r, *s;
+ char *id, *runlev, *action, *process, *eol;
const struct initActionType *a = actions;
int foundIt;
while (fgets(buf, 255, file) != NULL) {
foundIt = FALSE;
- for (p = buf; *p == ' ' || *p == '\t'; p++);
- if (*p == '#' || *p == '\n')
+ /* Skip leading spaces */
+ for (id = buf; *id == ' ' || *id == '\t'; id++);
+
+ /* Skip the line if it's a comment */
+ if (*id == '#' || *id == '\n')
continue;
/* Trim the trailing \n */
- q = strrchr(p, '\n');
- if (q != NULL)
- *q = '\0';
+ eol = strrchr(id, '\n');
+ if (eol != NULL)
+ *eol = '\0';
/* Keep a copy around for posterity's sake (and error msgs) */
strcpy(lineAsRead, buf);
- /* Grab the ID field */
- s = p;
- p = strchr(p, ':');
- if (p != NULL || *(p + 1) != '\0') {
- *p = '\0';
- ++p;
+ /* Separate the ID field from the runlevels */
+ runlev = strchr(id, ':');
+ if (runlev == NULL || *(runlev + 1) == '\0') {
+ message(LOG | CONSOLE, "Bad inittab entry: %s\n", lineAsRead);
+ continue;
+ } else {
+ *runlev = '\0';
+ ++runlev;
}
- /* Now peel off the process field from the end
- * of the string */
- q = strrchr(p, ':');
- if (q == NULL || *(q + 1) == '\0') {
+ /* Separate the runlevels from the action */
+ action = strchr(runlev, ':');
+ if (action == NULL || *(action + 1) == '\0') {
message(LOG | CONSOLE, "Bad inittab entry: %s\n", lineAsRead);
continue;
} else {
- *q = '\0';
- ++q;
+ *action = '\0';
+ ++action;
}
- /* Now peel off the action field */
- r = strrchr(p, ':');
- if (r == NULL || *(r + 1) == '\0') {
+ /* Separate the action from the process */
+ process = strchr(action, ':');
+ if (process == NULL || *(process + 1) == '\0') {
message(LOG | CONSOLE, "Bad inittab entry: %s\n", lineAsRead);
continue;
} else {
- ++r;
+ *process = '\0';
+ ++process;
}
/* Ok, now process it */
a = actions;
while (a->name != 0) {
- if (strcmp(a->name, r) == 0) {
- if (*s != '\0') {
+ if (strcmp(a->name, action) == 0) {
+ if (*id != '\0') {
struct stat statBuf;
strcpy(tmpConsole, "/dev/");
- strncat(tmpConsole, s, 200);
+ strncat(tmpConsole, id, 200);
if (stat(tmpConsole, &statBuf) != 0) {
message(LOG | CONSOLE,
"device '%s' does not exist. Did you read the directions?\n",
tmpConsole);
break;
}
- s = tmpConsole;
+ id = tmpConsole;
}
- new_initAction(a->action, q, s);
+ new_initAction(a->action, process, id);
foundIt = TRUE;
}
a++;
/* Expect to be invoked as init with PID=1 or be invoked as linuxrc */
if (getpid() != 1
#ifdef BB_FEATURE_LINUXRC
- && strstr(argv[0], "linuxrc") == NULL
+ && strstr(applet_name, "linuxrc") == NULL
#endif
)
{
/* Set up sig handlers -- be sure to
* clear all of these in run() */
signal(SIGUSR1, halt_signal);
- signal(SIGUSR2, reboot_signal);
+ signal(SIGUSR2, halt_signal);
signal(SIGINT, reboot_signal);
signal(SIGTERM, reboot_signal);
#if defined BB_FEATURE_INIT_CHROOT
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