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