7694b4448d1eac502010d34f4d4b3c9986a4f9f4
[oweals/busybox.git] / init / init.c
1 /* vi: set sw=4 ts=4: */
2 /*
3  * Mini init implementation for busybox
4  *
5  * Copyright (C) 1995, 1996 by Bruce Perens <bruce@pixar.com>.
6  * Copyright (C) 1999-2004 by Erik Andersen <andersen@codepoet.org>
7  * Adjusted by so many folks, it's impossible to keep track.
8  *
9  * Licensed under GPLv2 or later, see file LICENSE in this tarball for details.
10  */
11
12 #include "busybox.h"
13 #include <errno.h>
14 #include <paths.h>
15 #include <signal.h>
16 #include <sys/ioctl.h>
17 #include <sys/wait.h>
18 #include <sys/reboot.h>
19
20 #include "init_shared.h"
21
22 #if ENABLE_SYSLOGD
23 # include <sys/syslog.h>
24 #endif
25
26 #define INIT_BUFFS_SIZE 256
27
28 /* From <linux/vt.h> */
29 struct vt_stat {
30         unsigned short v_active;        /* active vt */
31         unsigned short v_signal;        /* signal to send */
32         unsigned short v_state; /* vt bitmask */
33 };
34 enum { VT_GETSTATE = 0x5603 };  /* get global vt state info */
35
36 /* From <linux/serial.h> */
37 struct serial_struct {
38         int     type;
39         int     line;
40         unsigned int    port;
41         int     irq;
42         int     flags;
43         int     xmit_fifo_size;
44         int     custom_divisor;
45         int     baud_base;
46         unsigned short  close_delay;
47         char    io_type;
48         char    reserved_char[1];
49         int     hub6;
50         unsigned short  closing_wait; /* time to wait before closing */
51         unsigned short  closing_wait2; /* no longer used... */
52         unsigned char   *iomem_base;
53         unsigned short  iomem_reg_shift;
54         unsigned int    port_high;
55         unsigned long   iomap_base;     /* cookie passed into ioremap */
56         int     reserved[1];
57 };
58
59 #ifndef _PATH_STDPATH
60 #define _PATH_STDPATH   "/usr/bin:/bin:/usr/sbin:/sbin"
61 #endif
62
63 #if ENABLE_FEATURE_INIT_COREDUMPS
64 /*
65  * When a file named CORE_ENABLE_FLAG_FILE exists, setrlimit is called
66  * before processes are spawned to set core file size as unlimited.
67  * This is for debugging only.  Don't use this is production, unless
68  * you want core dumps lying about....
69  */
70 #define CORE_ENABLE_FLAG_FILE "/.init_enable_core"
71 #include <sys/resource.h>
72 #endif
73
74 #define INITTAB      "/etc/inittab"     /* inittab file location */
75 #ifndef INIT_SCRIPT
76 #define INIT_SCRIPT  "/etc/init.d/rcS"  /* Default sysinit script. */
77 #endif
78
79 #define MAXENV  16              /* Number of env. vars */
80
81 #define CONSOLE_BUFF_SIZE 32
82
83 /* Allowed init action types */
84 #define SYSINIT     0x001
85 #define RESPAWN     0x002
86 #define ASKFIRST    0x004
87 #define WAIT        0x008
88 #define ONCE        0x010
89 #define CTRLALTDEL  0x020
90 #define SHUTDOWN    0x040
91 #define RESTART     0x080
92
93 /* A mapping between "inittab" action name strings and action type codes. */
94 struct init_action_type {
95         const char *name;
96         int action;
97 };
98
99 static const struct init_action_type actions[] = {
100         {"sysinit", SYSINIT},
101         {"respawn", RESPAWN},
102         {"askfirst", ASKFIRST},
103         {"wait", WAIT},
104         {"once", ONCE},
105         {"ctrlaltdel", CTRLALTDEL},
106         {"shutdown", SHUTDOWN},
107         {"restart", RESTART},
108         {0, 0}
109 };
110
111 /* Set up a linked list of init_actions, to be read from inittab */
112 struct init_action {
113         pid_t pid;
114         char command[INIT_BUFFS_SIZE];
115         char terminal[CONSOLE_BUFF_SIZE];
116         struct init_action *next;
117         int action;
118 };
119
120 /* Static variables */
121 static struct init_action *init_action_list = NULL;
122 static char console[CONSOLE_BUFF_SIZE] = CONSOLE_DEV;
123
124 #if !ENABLE_SYSLOGD
125 static char *log_console = VC_5;
126 #endif
127 #if !ENABLE_DEBUG_INIT
128 static sig_atomic_t got_cont = 0;
129 #endif
130
131 enum {
132         LOG = 0x1,
133         CONSOLE = 0x2,
134
135 #if ENABLE_FEATURE_EXTRA_QUIET
136         MAYBE_CONSOLE = 0x0,
137 #else
138         MAYBE_CONSOLE = CONSOLE,
139 #endif
140
141 #ifndef RB_HALT_SYSTEM
142         RB_HALT_SYSTEM = 0xcdef0123, /* FIXME: this overflows enum */
143         RB_ENABLE_CAD = 0x89abcdef,
144         RB_DISABLE_CAD = 0,
145         RB_POWER_OFF = 0x4321fedc,
146         RB_AUTOBOOT = 0x01234567,
147 #endif
148 };
149
150 static const char * const environment[] = {
151         "HOME=/",
152         "PATH=" _PATH_STDPATH,
153         "SHELL=/bin/sh",
154         "USER=root",
155         NULL
156 };
157
158 /* Function prototypes */
159 static void delete_init_action(struct init_action *a);
160 static int waitfor(const struct init_action *a, pid_t pid);
161 #if !ENABLE_DEBUG_INIT
162 static void shutdown_signal(int sig);
163 #endif
164
165 #if !ENABLE_DEBUG_INIT
166 static void loop_forever(void)
167 {
168         while (1)
169                 sleep(1);
170 }
171 #endif
172
173 /* Print a message to the specified device.
174  * Device may be bitwise-or'd from LOG | CONSOLE */
175 #if ENABLE_DEBUG_INIT
176 #define messageD message
177 #else
178 #define messageD(...)  do {} while (0)
179 #endif
180 static void message(int device, const char *fmt, ...)
181         __attribute__ ((format(printf, 2, 3)));
182 static void message(int device, const char *fmt, ...)
183 {
184         va_list arguments;
185         int l;
186         RESERVE_CONFIG_BUFFER(msg, 1024);
187 #if !ENABLE_SYSLOGD
188         static int log_fd = -1;
189 #endif
190
191         msg[0] = '\r';
192                 va_start(arguments, fmt);
193         l = vsnprintf(msg + 1, 1024 - 2, fmt, arguments) + 1;
194                 va_end(arguments);
195
196 #if ENABLE_SYSLOGD
197         /* Log the message to syslogd */
198         if (device & LOG) {
199                 /* don`t out "\r\n" */
200                 openlog(applet_name, 0, LOG_DAEMON);
201                 syslog(LOG_INFO, "%s", msg + 1);
202                 closelog();
203         }
204
205         msg[l++] = '\n';
206         msg[l] = 0;
207 #else
208
209         msg[l++] = '\n';
210         msg[l] = 0;
211         /* Take full control of the log tty, and never close it.
212          * It's mine, all mine!  Muhahahaha! */
213         if (log_fd < 0) {
214                 if ((log_fd = device_open(log_console, O_RDWR | O_NONBLOCK | O_NOCTTY)) < 0) {
215                         log_fd = -2;
216                         bb_error_msg("bummer, can't write to log on %s!", log_console);
217                         device = CONSOLE;
218                 } else {
219                         fcntl(log_fd, F_SETFD, FD_CLOEXEC);
220                 }
221         }
222         if ((device & LOG) && (log_fd >= 0)) {
223                 full_write(log_fd, msg, l);
224         }
225 #endif
226
227         if (device & CONSOLE) {
228                 int fd = device_open(CONSOLE_DEV,
229                                         O_WRONLY | O_NOCTTY | O_NONBLOCK);
230                 /* Always send console messages to /dev/console so people will see them. */
231                 if (fd >= 0) {
232                         full_write(fd, msg, l);
233                         close(fd);
234 #if ENABLE_DEBUG_INIT
235                 /* all descriptors may be closed */
236                 } else {
237                         bb_error_msg("bummer, can't print: ");
238                         va_start(arguments, fmt);
239                         vfprintf(stderr, fmt, arguments);
240                         va_end(arguments);
241 #endif
242                 }
243         }
244         RELEASE_CONFIG_BUFFER(msg);
245 }
246
247 /* Set terminal settings to reasonable defaults */
248 static void set_term(void)
249 {
250         struct termios tty;
251
252         tcgetattr(STDIN_FILENO, &tty);
253
254         /* set control chars */
255         tty.c_cc[VINTR] = 3;    /* C-c */
256         tty.c_cc[VQUIT] = 28;   /* C-\ */
257         tty.c_cc[VERASE] = 127; /* C-? */
258         tty.c_cc[VKILL] = 21;   /* C-u */
259         tty.c_cc[VEOF] = 4;     /* C-d */
260         tty.c_cc[VSTART] = 17;  /* C-q */
261         tty.c_cc[VSTOP] = 19;   /* C-s */
262         tty.c_cc[VSUSP] = 26;   /* C-z */
263
264         /* use line dicipline 0 */
265         tty.c_line = 0;
266
267         /* Make it be sane */
268         tty.c_cflag &= CBAUD | CBAUDEX | CSIZE | CSTOPB | PARENB | PARODD;
269         tty.c_cflag |= CREAD | HUPCL | CLOCAL;
270
271
272         /* input modes */
273         tty.c_iflag = ICRNL | IXON | IXOFF;
274
275         /* output modes */
276         tty.c_oflag = OPOST | ONLCR;
277
278         /* local modes */
279         tty.c_lflag =
280                 ISIG | ICANON | ECHO | ECHOE | ECHOK | ECHOCTL | ECHOKE | IEXTEN;
281
282         tcsetattr(STDIN_FILENO, TCSANOW, &tty);
283 }
284
285 static void console_init(void)
286 {
287         int fd;
288         int tried = 0;
289         struct vt_stat vt;
290         struct serial_struct sr;
291         char *s;
292
293         if ((s = getenv("CONSOLE")) != NULL || (s = getenv("console")) != NULL) {
294                 safe_strncpy(console, s, sizeof(console));
295         } else {
296                 /* 2.2 kernels: identify the real console backend and try to use it */
297                 if (ioctl(0, TIOCGSERIAL, &sr) == 0) {
298                         /* this is a serial console */
299                         snprintf(console, sizeof(console) - 1, SC_FORMAT, sr.line);
300                 } else if (ioctl(0, VT_GETSTATE, &vt) == 0) {
301                         /* this is linux virtual tty */
302                         snprintf(console, sizeof(console) - 1, VC_FORMAT, vt.v_active);
303                 } else {
304                         safe_strncpy(console, CONSOLE_DEV, sizeof(console));
305                         tried++;
306                 }
307         }
308
309         while ((fd = open(console, O_RDONLY | O_NONBLOCK)) < 0 && tried < 2) {
310                 /* Can't open selected console -- try
311                         logical system console and VT_MASTER */
312                 safe_strncpy(console, (tried == 0 ? CONSOLE_DEV : CURRENT_VC),
313                                                         sizeof(console));
314                 tried++;
315         }
316         if (fd < 0) {
317                 /* Perhaps we should panic here? */
318 #if !ENABLE_SYSLOGD
319                 log_console =
320 #endif
321                 safe_strncpy(console, bb_dev_null, sizeof(console));
322         } else {
323                 s = getenv("TERM");
324                 /* check for serial console */
325                 if (ioctl(fd, TIOCGSERIAL, &sr) == 0) {
326                         /* Force the TERM setting to vt102 for serial console --
327                          * if TERM is set to linux (the default) */
328                         if (s == NULL || strcmp(s, "linux") == 0)
329                                 putenv("TERM=vt102");
330 #if !ENABLE_SYSLOGD
331                         log_console = console;
332 #endif
333                 } else {
334                         if (s == NULL)
335                                 putenv("TERM=linux");
336                 }
337                 close(fd);
338         }
339         messageD(LOG, "console=%s", console);
340 }
341
342 static void fixup_argv(int argc, char **argv, char *new_argv0)
343 {
344         int len;
345
346         /* Fix up argv[0] to be certain we claim to be init */
347         len = strlen(argv[0]);
348         memset(argv[0], 0, len);
349         safe_strncpy(argv[0], new_argv0, len + 1);
350
351         /* Wipe argv[1]-argv[N] so they don't clutter the ps listing */
352         len = 1;
353         while (argc > len) {
354                 memset(argv[len], 0, strlen(argv[len]));
355                 len++;
356         }
357 }
358
359 /* Open the new terminal device */
360 static void open_new_terminal(const char * const device, const int fail) {
361         struct stat sb;
362
363         if ((device_open(device, O_RDWR)) < 0) {
364                 if (stat(device, &sb) != 0) {
365                         message(LOG | CONSOLE, "device '%s' does not exist.", device);
366                 } else {
367                         message(LOG | CONSOLE, "Bummer, can't open %s", device);
368                 }
369                 if (fail)
370                         _exit(1);
371                 /* else */
372 #if !ENABLE_DEBUG_INIT
373                 shutdown_signal(SIGUSR1);
374 #else
375                 _exit(2);
376 #endif
377         }
378 }
379
380 static pid_t run(const struct init_action *a)
381 {
382         int i;
383         pid_t pid;
384         char *s, *tmpCmd, *cmd[INIT_BUFFS_SIZE], *cmdpath;
385         char buf[INIT_BUFFS_SIZE + 6];  /* INIT_BUFFS_SIZE+strlen("exec ")+1 */
386         sigset_t nmask, omask;
387         static const char press_enter[] =
388 #ifdef CUSTOMIZED_BANNER
389 #include CUSTOMIZED_BANNER
390 #endif
391                 "\nPlease press Enter to activate this console. ";
392         char *prog;
393
394         /* Block sigchild while forking.  */
395         sigemptyset(&nmask);
396         sigaddset(&nmask, SIGCHLD);
397         sigprocmask(SIG_BLOCK, &nmask, &omask);
398
399         if ((pid = fork()) == 0) {
400
401                 /* Clean up */
402                 close(0);
403                 close(1);
404                 close(2);
405                 sigprocmask(SIG_SETMASK, &omask, NULL);
406
407                 /* Reset signal handlers that were set by the parent process */
408                 signal(SIGUSR1, SIG_DFL);
409                 signal(SIGUSR2, SIG_DFL);
410                 signal(SIGINT, SIG_DFL);
411                 signal(SIGTERM, SIG_DFL);
412                 signal(SIGHUP, SIG_DFL);
413                 signal(SIGQUIT, SIG_DFL);
414                 signal(SIGCONT, SIG_DFL);
415                 signal(SIGSTOP, SIG_DFL);
416                 signal(SIGTSTP, SIG_DFL);
417
418                 /* Create a new session and make ourself the process
419                  * group leader */
420                 setsid();
421
422                 /* Open the new terminal device */
423                 open_new_terminal(a->terminal, 1);
424
425                 /* Make sure the terminal will act fairly normal for us */
426                 set_term();
427                 /* Setup stdout, stderr for the new process so
428                  * they point to the supplied terminal */
429                 dup(0);
430                 dup(0);
431
432                 /* If the init Action requires us to wait, then force the
433                  * supplied terminal to be the controlling tty. */
434                 if (a->action & (SYSINIT | WAIT | CTRLALTDEL | SHUTDOWN | RESTART)) {
435
436                         /* Now fork off another process to just hang around */
437                         if ((pid = fork()) < 0) {
438                                 message(LOG | CONSOLE, "Can't fork!");
439                                 _exit(1);
440                         }
441
442                         if (pid > 0) {
443
444                                 /* We are the parent -- wait till the child is done */
445                                 signal(SIGINT, SIG_IGN);
446                                 signal(SIGTSTP, SIG_IGN);
447                                 signal(SIGQUIT, SIG_IGN);
448                                 signal(SIGCHLD, SIG_DFL);
449
450                                 waitfor(NULL, pid);
451                                 /* See if stealing the controlling tty back is necessary */
452                                 if (tcgetpgrp(0) != getpid())
453                                         _exit(0);
454
455                                 /* Use a temporary process to steal the controlling tty. */
456                                 if ((pid = fork()) < 0) {
457                                         message(LOG | CONSOLE, "Can't fork!");
458                                         _exit(1);
459                                 }
460                                 if (pid == 0) {
461                                         setsid();
462                                         ioctl(0, TIOCSCTTY, 1);
463                                         _exit(0);
464                                 }
465                                 waitfor(NULL, pid);
466                                 _exit(0);
467                         }
468
469                         /* Now fall though to actually execute things */
470                 }
471
472                 /* See if any special /bin/sh requiring characters are present */
473                 if (strpbrk(a->command, "~`!$^&*()=|\\{}[];\"'<>?") != NULL) {
474                         cmd[0] = (char *)DEFAULT_SHELL;
475                         cmd[1] = "-c";
476                         cmd[2] = strcat(strcpy(buf, "exec "), a->command);
477                         cmd[3] = NULL;
478                 } else {
479                         /* Convert command (char*) into cmd (char**, one word per string) */
480                         strcpy(buf, a->command);
481                         s = buf;
482                         for (tmpCmd = buf, i = 0; (tmpCmd = strsep(&s, " \t")) != NULL;) {
483                                 if (*tmpCmd != '\0') {
484                                         cmd[i] = tmpCmd;
485                                         i++;
486                                 }
487                         }
488                         cmd[i] = NULL;
489                 }
490
491                 cmdpath = cmd[0];
492
493                 /*
494                    Interactive shells want to see a dash in argv[0].  This
495                    typically is handled by login, argv will be setup this
496                    way if a dash appears at the front of the command path
497                    (like "-/bin/sh").
498                  */
499
500                 if (*cmdpath == '-') {
501
502                         /* skip over the dash */
503                         ++cmdpath;
504
505                         /* find the last component in the command pathname */
506                         s = bb_get_last_path_component(cmdpath);
507
508                         /* make a new argv[0] */
509                         if ((cmd[0] = malloc(strlen(s) + 2)) == NULL) {
510                                 message(LOG | CONSOLE, bb_msg_memory_exhausted);
511                                 cmd[0] = cmdpath;
512                         } else {
513                                 cmd[0][0] = '-';
514                                 strcpy(cmd[0] + 1, s);
515                         }
516 #if ENABLE_FEATURE_INIT_SCTTY
517                         /* Establish this process as session leader and
518                          * (attempt) to make the tty (if any) a controlling tty.
519                          */
520                         (void) setsid();
521                         (void) ioctl(0, TIOCSCTTY, 0/*don't steal it*/);
522 #endif
523                 }
524
525 #if !defined(__UCLIBC__) || defined(__ARCH_HAS_MMU__)
526                 if (a->action & ASKFIRST) {
527                         char c;
528                         /*
529                          * Save memory by not exec-ing anything large (like a shell)
530                          * before the user wants it. This is critical if swap is not
531                          * enabled and the system has low memory. Generally this will
532                          * be run on the second virtual console, and the first will
533                          * be allowed to start a shell or whatever an init script
534                          * specifies.
535                          */
536                         messageD(LOG, "Waiting for enter to start '%s'"
537                                                 "(pid %d, terminal %s)\n",
538                                           cmdpath, getpid(), a->terminal);
539                         full_write(1, press_enter, sizeof(press_enter) - 1);
540                         while (read(0, &c, 1) == 1 && c != '\n')
541                                 ;
542                 }
543 #endif
544
545                 /* Log the process name and args */
546                 message(LOG, "Starting pid %d, console %s: '%s'",
547                                   getpid(), a->terminal, cmdpath);
548
549 #if ENABLE_FEATURE_INIT_COREDUMPS
550                 {
551                         struct stat sb;
552                         if (stat(CORE_ENABLE_FLAG_FILE, &sb) == 0) {
553                                 struct rlimit limit;
554
555                                 limit.rlim_cur = RLIM_INFINITY;
556                                 limit.rlim_max = RLIM_INFINITY;
557                                 setrlimit(RLIMIT_CORE, &limit);
558                         }
559                 }
560 #endif
561
562                 /* Now run it.  The new program will take over this PID,
563                  * so nothing further in init.c should be run. */
564                 prog = cmdpath;
565                 if (ENABLE_FEATURE_EXEC_PREFER_APPLETS && find_applet_by_name(prog))
566                         prog = CONFIG_BUSYBOX_EXEC_PATH;
567                 execvp(prog, cmd);
568
569                 /* We're still here?  Some error happened. */
570                 message(LOG | CONSOLE, "Bummer, cannot run '%s': %m", cmdpath);
571                 _exit(-1);
572         }
573         sigprocmask(SIG_SETMASK, &omask, NULL);
574         return pid;
575 }
576
577 static int waitfor(const struct init_action *a, pid_t pid)
578 {
579         int runpid;
580         int status, wpid;
581
582         runpid = (NULL == a)? pid : run(a);
583         while (1) {
584                 wpid = waitpid(runpid,&status,0);
585                 if (wpid == runpid)
586                         break;
587                 if (wpid == -1 && errno == ECHILD) {
588                         /* we missed its termination */
589                         break;
590                 }
591                 /* FIXME other errors should maybe trigger an error, but allow
592                  * the program to continue */
593         }
594         return wpid;
595 }
596
597 /* Run all commands of a particular type */
598 static void run_actions(int action)
599 {
600         struct init_action *a, *tmp;
601
602         for (a = init_action_list; a; a = tmp) {
603                 tmp = a->next;
604                 if (a->action == action) {
605                         if (access(a->terminal, R_OK | W_OK)) {
606                                 delete_init_action(a);
607                         } else if (a->action & (SYSINIT | WAIT | CTRLALTDEL | SHUTDOWN | RESTART)) {
608                                 waitfor(a, 0);
609                                 delete_init_action(a);
610                         } else if (a->action & ONCE) {
611                                 run(a);
612                                 delete_init_action(a);
613                         } else if (a->action & (RESPAWN | ASKFIRST)) {
614                                 /* Only run stuff with pid==0.  If they have
615                                  * a pid, that means it is still running */
616                                 if (a->pid == 0) {
617                                         a->pid = run(a);
618                                 }
619                         }
620                 }
621         }
622 }
623
624 #if !ENABLE_DEBUG_INIT
625 static void init_reboot(unsigned long magic)
626 {
627         pid_t pid;
628         /* We have to fork here, since the kernel calls do_exit(0) in
629          * linux/kernel/sys.c, which can cause the machine to panic when
630          * the init process is killed.... */
631         pid = vfork();
632         if (pid == 0) { /* child */
633                 reboot(magic);
634                 _exit(0);
635         }
636         waitpid(pid, NULL, 0);
637 }
638
639 static void shutdown_system(void)
640 {
641         sigset_t block_signals;
642
643         /* run everything to be run at "shutdown".  This is done _prior_
644          * to killing everything, in case people wish to use scripts to
645          * shut things down gracefully... */
646         run_actions(SHUTDOWN);
647
648         /* first disable all our signals */
649         sigemptyset(&block_signals);
650         sigaddset(&block_signals, SIGHUP);
651         sigaddset(&block_signals, SIGQUIT);
652         sigaddset(&block_signals, SIGCHLD);
653         sigaddset(&block_signals, SIGUSR1);
654         sigaddset(&block_signals, SIGUSR2);
655         sigaddset(&block_signals, SIGINT);
656         sigaddset(&block_signals, SIGTERM);
657         sigaddset(&block_signals, SIGCONT);
658         sigaddset(&block_signals, SIGSTOP);
659         sigaddset(&block_signals, SIGTSTP);
660         sigprocmask(SIG_BLOCK, &block_signals, NULL);
661
662         /* Allow Ctrl-Alt-Del to reboot system. */
663         init_reboot(RB_ENABLE_CAD);
664
665         message(CONSOLE | LOG, "The system is going down NOW !!");
666         sync();
667
668         /* Send signals to every process _except_ pid 1 */
669         message(CONSOLE | LOG, init_sending_format, "TERM");
670         kill(-1, SIGTERM);
671         sleep(1);
672         sync();
673
674         message(CONSOLE | LOG, init_sending_format, "KILL");
675         kill(-1, SIGKILL);
676         sleep(1);
677
678         sync();
679 }
680
681 static void exec_signal(int sig ATTRIBUTE_UNUSED)
682 {
683         struct init_action *a, *tmp;
684         sigset_t unblock_signals;
685         char *prog;
686
687         for (a = init_action_list; a; a = tmp) {
688                 tmp = a->next;
689                 if (a->action & RESTART) {
690                         shutdown_system();
691
692                         /* unblock all signals, blocked in shutdown_system() */
693                         sigemptyset(&unblock_signals);
694                         sigaddset(&unblock_signals, SIGHUP);
695                         sigaddset(&unblock_signals, SIGQUIT);
696                         sigaddset(&unblock_signals, SIGCHLD);
697                         sigaddset(&unblock_signals, SIGUSR1);
698                         sigaddset(&unblock_signals, SIGUSR2);
699                         sigaddset(&unblock_signals, SIGINT);
700                         sigaddset(&unblock_signals, SIGTERM);
701                         sigaddset(&unblock_signals, SIGCONT);
702                         sigaddset(&unblock_signals, SIGSTOP);
703                         sigaddset(&unblock_signals, SIGTSTP);
704                         sigprocmask(SIG_UNBLOCK, &unblock_signals, NULL);
705
706                         /* Close whatever files are open. */
707                         close(0);
708                         close(1);
709                         close(2);
710
711                         /* Open the new terminal device */
712                         open_new_terminal(a->terminal, 0);
713
714                         /* Make sure the terminal will act fairly normal for us */
715                         set_term();
716                         /* Setup stdout, stderr on the supplied terminal */
717                         dup(0);
718                         dup(0);
719
720                         messageD(CONSOLE | LOG, "Trying to re-exec %s", a->command);
721                         prog = a->command;
722                         if (ENABLE_FEATURE_EXEC_PREFER_APPLETS && find_applet_by_name(prog))
723                                 prog = CONFIG_BUSYBOX_EXEC_PATH;
724                         execlp(prog, a->command, NULL);
725
726                         message(CONSOLE | LOG, "exec of '%s' failed: %m",
727                                         a->command);
728                         sync();
729                         sleep(2);
730                         init_reboot(RB_HALT_SYSTEM);
731                         loop_forever();
732                 }
733         }
734 }
735
736 static void shutdown_signal(int sig)
737 {
738         char *m;
739         int rb;
740
741         shutdown_system();
742
743         if (sig == SIGTERM) {
744                 m = "reboot";
745                 rb = RB_AUTOBOOT;
746         } else if (sig == SIGUSR2) {
747                 m = "poweroff";
748                 rb = RB_POWER_OFF;
749         } else {
750                 m = "halt";
751                 rb = RB_HALT_SYSTEM;
752         }
753         message(CONSOLE | LOG, "Requesting system %s.", m);
754         sync();
755
756         /* allow time for last message to reach serial console */
757         sleep(2);
758
759         init_reboot(rb);
760         loop_forever();
761 }
762
763 static void ctrlaltdel_signal(int sig ATTRIBUTE_UNUSED)
764 {
765         run_actions(CTRLALTDEL);
766 }
767
768 /* The SIGSTOP & SIGTSTP handler */
769 static void stop_handler(int sig ATTRIBUTE_UNUSED)
770 {
771         int saved_errno = errno;
772
773         got_cont = 0;
774         while (!got_cont)
775                 pause();
776         got_cont = 0;
777         errno = saved_errno;
778 }
779
780 /* The SIGCONT handler */
781 static void cont_handler(int sig ATTRIBUTE_UNUSED)
782 {
783         got_cont = 1;
784 }
785
786 #endif                                                  /* ! ENABLE_DEBUG_INIT */
787
788 static void new_init_action(int action, const char *command, const char *cons)
789 {
790         struct init_action *new_action, *a, *last;
791
792         if (*cons == '\0')
793                 cons = console;
794
795         if (strcmp(cons, bb_dev_null) == 0 && (action & ASKFIRST))
796                 return;
797
798         new_action = xzalloc(sizeof(struct init_action));
799
800         /* Append to the end of the list */
801         for (a = last = init_action_list; a; a = a->next) {
802                 /* don't enter action if it's already in the list,
803                  * but do overwrite existing actions */
804                 if ((strcmp(a->command, command) == 0) &&
805                     (strcmp(a->terminal, cons) ==0)) {
806                         a->action = action;
807                         free(new_action);
808                         return;
809                 }
810                 last = a;
811         }
812         if (last) {
813                 last->next = new_action;
814         } else {
815                 init_action_list = new_action;
816         }
817         strcpy(new_action->command, command);
818         new_action->action = action;
819         strcpy(new_action->terminal, cons);
820         messageD(LOG|CONSOLE, "command='%s' action='%d' terminal='%s'\n",
821                 new_action->command, new_action->action, new_action->terminal);
822 }
823
824 static void delete_init_action(struct init_action *action)
825 {
826         struct init_action *a, *b = NULL;
827
828         for (a = init_action_list; a; b = a, a = a->next) {
829                 if (a == action) {
830                         if (b == NULL) {
831                                 init_action_list = a->next;
832                         } else {
833                                 b->next = a->next;
834                         }
835                         free(a);
836                         break;
837                 }
838         }
839 }
840
841 /* NOTE that if CONFIG_FEATURE_USE_INITTAB is NOT defined,
842  * then parse_inittab() simply adds in some default
843  * actions(i.e., runs INIT_SCRIPT and then starts a pair
844  * of "askfirst" shells).  If CONFIG_FEATURE_USE_INITTAB
845  * _is_ defined, but /etc/inittab is missing, this
846  * results in the same set of default behaviors.
847  */
848 static void parse_inittab(void)
849 {
850 #if ENABLE_FEATURE_USE_INITTAB
851         FILE *file;
852         char buf[INIT_BUFFS_SIZE], lineAsRead[INIT_BUFFS_SIZE];
853         char tmpConsole[CONSOLE_BUFF_SIZE];
854         char *id, *runlev, *action, *command, *eol;
855         const struct init_action_type *a = actions;
856
857
858         file = fopen(INITTAB, "r");
859         if (file == NULL) {
860                 /* No inittab file -- set up some default behavior */
861 #endif
862                 /* Reboot on Ctrl-Alt-Del */
863                 new_init_action(CTRLALTDEL, "reboot", "");
864                 /* Umount all filesystems on halt/reboot */
865                 new_init_action(SHUTDOWN, "umount -a -r", "");
866                 /* Swapoff on halt/reboot */
867                 if(ENABLE_SWAPONOFF) new_init_action(SHUTDOWN, "swapoff -a", "");
868                 /* Prepare to restart init when a HUP is received */
869                 new_init_action(RESTART, "init", "");
870                 /* Askfirst shell on tty1-4 */
871                 new_init_action(ASKFIRST, bb_default_login_shell, "");
872                 new_init_action(ASKFIRST, bb_default_login_shell, VC_2);
873                 new_init_action(ASKFIRST, bb_default_login_shell, VC_3);
874                 new_init_action(ASKFIRST, bb_default_login_shell, VC_4);
875                 /* sysinit */
876                 new_init_action(SYSINIT, INIT_SCRIPT, "");
877
878                 return;
879 #if ENABLE_FEATURE_USE_INITTAB
880         }
881
882         while (fgets(buf, INIT_BUFFS_SIZE, file) != NULL) {
883                 /* Skip leading spaces */
884                 for (id = buf; *id == ' ' || *id == '\t'; id++);
885
886                 /* Skip the line if it's a comment */
887                 if (*id == '#' || *id == '\n')
888                         continue;
889
890                 /* Trim the trailing \n */
891                 eol = strrchr(id, '\n');
892                 if (eol != NULL)
893                         *eol = '\0';
894
895                 /* Keep a copy around for posterity's sake (and error msgs) */
896                 strcpy(lineAsRead, buf);
897
898                 /* Separate the ID field from the runlevels */
899                 runlev = strchr(id, ':');
900                 if (runlev == NULL || *(runlev + 1) == '\0') {
901                         message(LOG | CONSOLE, "Bad inittab entry: %s", lineAsRead);
902                         continue;
903                 } else {
904                         *runlev = '\0';
905                         ++runlev;
906                 }
907
908                 /* Separate the runlevels from the action */
909                 action = strchr(runlev, ':');
910                 if (action == NULL || *(action + 1) == '\0') {
911                         message(LOG | CONSOLE, "Bad inittab entry: %s", lineAsRead);
912                         continue;
913                 } else {
914                         *action = '\0';
915                         ++action;
916                 }
917
918                 /* Separate the action from the command */
919                 command = strchr(action, ':');
920                 if (command == NULL || *(command + 1) == '\0') {
921                         message(LOG | CONSOLE, "Bad inittab entry: %s", lineAsRead);
922                         continue;
923                 } else {
924                         *command = '\0';
925                         ++command;
926                 }
927
928                 /* Ok, now process it */
929                 for (a = actions; a->name != 0; a++) {
930                         if (strcmp(a->name, action) == 0) {
931                                 if (*id != '\0') {
932                                         if(strncmp(id, "/dev/", 5) == 0)
933                                                 id += 5;
934                                         strcpy(tmpConsole, "/dev/");
935                                         safe_strncpy(tmpConsole + 5, id,
936                                                 CONSOLE_BUFF_SIZE - 5);
937                                         id = tmpConsole;
938                                 }
939                                 new_init_action(a->action, command, id);
940                                 break;
941                         }
942                 }
943                 if (a->name == 0) {
944                         /* Choke on an unknown action */
945                         message(LOG | CONSOLE, "Bad inittab entry: %s", lineAsRead);
946                 }
947         }
948         fclose(file);
949         return;
950 #endif /* FEATURE_USE_INITTAB */
951 }
952
953 #if ENABLE_FEATURE_USE_INITTAB
954 static void reload_signal(int sig ATTRIBUTE_UNUSED)
955 {
956         struct init_action *a, *tmp;
957
958         message(LOG, "Reloading /etc/inittab");
959
960         /* disable old entrys */
961         for (a = init_action_list; a; a = a->next ) {
962                 a->action = ONCE;
963         }
964
965         parse_inittab();
966
967         /* remove unused entrys */
968         for (a = init_action_list; a; a = tmp) {
969                 tmp = a->next;
970                 if (a->action & (ONCE | SYSINIT | WAIT ) &&
971                                 a->pid == 0 ) {
972                         delete_init_action(a);
973                 }
974         }
975         run_actions(RESPAWN);
976         return;
977 }
978 #endif  /* FEATURE_USE_INITTAB */
979
980 int init_main(int argc, char **argv)
981 {
982         struct init_action *a;
983         pid_t wpid;
984
985         die_sleep = 30 * 24*60*60; /* if xmalloc will ever die... */
986
987         if (argc > 1 && !strcmp(argv[1], "-q")) {
988                 return kill(1,SIGHUP);
989         }
990 #if !ENABLE_DEBUG_INIT
991         /* Expect to be invoked as init with PID=1 or be invoked as linuxrc */
992         if (getpid() != 1 &&
993                 (!ENABLE_FEATURE_INITRD || !strstr(applet_name, "linuxrc")))
994         {
995                 bb_show_usage();
996         }
997         /* Set up sig handlers  -- be sure to
998          * clear all of these in run() */
999         signal(SIGHUP, exec_signal);
1000         signal(SIGQUIT, exec_signal);
1001         signal(SIGUSR1, shutdown_signal);
1002         signal(SIGUSR2, shutdown_signal);
1003         signal(SIGINT, ctrlaltdel_signal);
1004         signal(SIGTERM, shutdown_signal);
1005         signal(SIGCONT, cont_handler);
1006         signal(SIGSTOP, stop_handler);
1007         signal(SIGTSTP, stop_handler);
1008
1009         /* Turn off rebooting via CTL-ALT-DEL -- we get a
1010          * SIGINT on CAD so we can shut things down gracefully... */
1011         init_reboot(RB_DISABLE_CAD);
1012 #endif
1013
1014         /* Figure out where the default console should be */
1015         console_init();
1016
1017         /* Close whatever files are open, and reset the console. */
1018         close(0);
1019         close(1);
1020         close(2);
1021
1022         if (device_open(console, O_RDWR | O_NOCTTY) == 0) {
1023                 set_term();
1024                 close(0);
1025         }
1026
1027         chdir("/");
1028         setsid();
1029         {
1030                 const char * const *e;
1031                 /* Make sure environs is set to something sane */
1032                 for (e = environment; *e; e++)
1033                         putenv((char *) *e);
1034         }
1035
1036         if (argc > 1) setenv("RUNLEVEL", argv[1], 1);
1037
1038         /* Hello world */
1039         message(MAYBE_CONSOLE | LOG, "init started:  %s", bb_msg_full_version);
1040
1041         /* Make sure there is enough memory to do something useful. */
1042         if (ENABLE_SWAPONOFF) {
1043                 struct sysinfo info;
1044
1045                 if (!sysinfo(&info) &&
1046                         (info.mem_unit ? : 1) * (long long)info.totalram < 1024*1024)
1047                 {
1048                         message(CONSOLE,"Low memory: forcing swapon.");
1049                         /* swapon -a requires /proc typically */
1050                         new_init_action(SYSINIT, "mount -t proc proc /proc", "");
1051                         /* Try to turn on swap */
1052                         new_init_action(SYSINIT, "swapon -a", "");
1053                         run_actions(SYSINIT);   /* wait and removing */
1054                 }
1055         }
1056
1057         /* Check if we are supposed to be in single user mode */
1058         if (argc > 1
1059          && (!strcmp(argv[1], "single") || !strcmp(argv[1], "-s") || LONE_CHAR(argv[1], '1'))
1060         ) {
1061                 /* Start a shell on console */
1062                 new_init_action(RESPAWN, bb_default_login_shell, "");
1063         } else {
1064                 /* Not in single user mode -- see what inittab says */
1065
1066                 /* NOTE that if CONFIG_FEATURE_USE_INITTAB is NOT defined,
1067                  * then parse_inittab() simply adds in some default
1068                  * actions(i.e., runs INIT_SCRIPT and then starts a pair
1069                  * of "askfirst" shells */
1070                 parse_inittab();
1071         }
1072
1073 #if ENABLE_SELINUX
1074         if (getenv("SELINUX_INIT") == NULL) {
1075                 int enforce = 0;
1076
1077                 putenv("SELINUX_INIT=YES");
1078                 if (selinux_init_load_policy(&enforce) == 0) {
1079                         char *prog = argv[0];
1080                         if (ENABLE_FEATURE_EXEC_PREFER_APPLETS && find_applet_by_name(prog))
1081                                 prog = CONFIG_BUSYBOX_EXEC_PATH;
1082                         execvp(prog, argv);
1083                 } else if (enforce > 0) {
1084                         /* SELinux in enforcing mode but load_policy failed */
1085                         /* At this point, we probably can't open /dev/console, so log() won't work */
1086                         message(CONSOLE,"Unable to load SELinux Policy. Machine is in enforcing mode. Halting now.");
1087                         exit(1);
1088                 }
1089         }
1090 #endif /* CONFIG_SELINUX */
1091
1092         /* Make the command line just say "init"  -- thats all, nothing else */
1093         fixup_argv(argc, argv, "init");
1094
1095         /* Now run everything that needs to be run */
1096
1097         /* First run the sysinit command */
1098         run_actions(SYSINIT);
1099
1100         /* Next run anything that wants to block */
1101         run_actions(WAIT);
1102
1103         /* Next run anything to be run only once */
1104         run_actions(ONCE);
1105
1106 #if ENABLE_FEATURE_USE_INITTAB
1107         /* Redefine SIGHUP to reread /etc/inittab */
1108         signal(SIGHUP, reload_signal);
1109 #else
1110         signal(SIGHUP, SIG_IGN);
1111 #endif /* FEATURE_USE_INITTAB */
1112
1113
1114         /* Now run the looping stuff for the rest of forever */
1115         while (1) {
1116                 /* run the respawn stuff */
1117                 run_actions(RESPAWN);
1118
1119                 /* run the askfirst stuff */
1120                 run_actions(ASKFIRST);
1121
1122                 /* Don't consume all CPU time -- sleep a bit */
1123                 sleep(1);
1124
1125                 /* Wait for a child process to exit */
1126                 wpid = wait(NULL);
1127                 while (wpid > 0) {
1128                         /* Find out who died and clean up their corpse */
1129                         for (a = init_action_list; a; a = a->next) {
1130                                 if (a->pid == wpid) {
1131                                         /* Set the pid to 0 so that the process gets
1132                                          * restarted by run_actions() */
1133                                         a->pid = 0;
1134                                         message(LOG, "Process '%s' (pid %d) exited.  "
1135                                                         "Scheduling it for restart.",
1136                                                         a->command, wpid);
1137                                 }
1138                         }
1139                         /* see if anyone else is waiting to be reaped */
1140                         wpid = waitpid(-1, NULL, WNOHANG);
1141                 }
1142         }
1143 }