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