fbset: fix buglet where we were using wrong pointer
[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                                 close_on_exec_on(log_fd);
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                 pid = fork();
373                 if (pid) {
374                         message(L_LOG | L_CONSOLE, "Can't fork");
375                         _exit(1);
376                 }
377
378                 if (pid > 0) {
379
380                         /* We are the parent -- wait till the child is done */
381                         signal(SIGINT, SIG_IGN);
382                         signal(SIGTSTP, SIG_IGN);
383                         signal(SIGQUIT, SIG_IGN);
384                         signal(SIGCHLD, SIG_DFL);
385
386                         waitfor(NULL, pid);
387                         /* See if stealing the controlling tty back is necessary */
388                         if (tcgetpgrp(0) != getpid())
389                                 _exit(0);
390
391                         /* Use a temporary process to steal the controlling tty. */
392                         pid = fork();
393                         if (pid < 0) {
394                                 message(L_LOG | L_CONSOLE, "Can't fork");
395                                 _exit(1);
396                         }
397                         if (pid == 0) {
398                                 setsid();
399                                 ioctl(0, TIOCSCTTY, 1);
400                                 _exit(0);
401                         }
402                         waitfor(NULL, pid);
403                         _exit(0);
404                 }
405
406                 /* Now fall though to actually execute things */
407         }
408
409         /* See if any special /bin/sh requiring characters are present */
410         if (strpbrk(a->command, "~`!$^&*()=|\\{}[];\"'<>?") != NULL) {
411                 cmd[0] = (char*)DEFAULT_SHELL;
412                 cmd[1] = (char*)"-c";
413                 cmd[2] = strcat(strcpy(buf, "exec "), a->command);
414                 cmd[3] = NULL;
415         } else {
416                 /* Convert command (char*) into cmd (char**, one word per string) */
417                 strcpy(buf, a->command);
418                 s = buf;
419                 for (tmpCmd = buf, i = 0; (tmpCmd = strsep(&s, " \t")) != NULL;) {
420                         if (*tmpCmd != '\0') {
421                                 cmd[i] = tmpCmd;
422                                 i++;
423                         }
424                 }
425                 cmd[i] = NULL;
426         }
427
428         cmdpath = cmd[0];
429
430         /*
431          * Interactive shells want to see a dash in argv[0].  This
432          * typically is handled by login, argv will be setup this
433          * way if a dash appears at the front of the command path
434          * (like "-/bin/sh").
435          */
436         if (*cmdpath == '-') {
437                 /* skip over the dash */
438                 ++cmdpath;
439
440                 /* find the last component in the command pathname */
441                 s = bb_get_last_path_component_nostrip(cmdpath);
442
443                 /* make a new argv[0] */
444                 cmd[0] = malloc(strlen(s) + 2);
445                 if (cmd[0] == NULL) {
446                         message(L_LOG | L_CONSOLE, bb_msg_memory_exhausted);
447                         cmd[0] = cmdpath;
448                 } else {
449                         cmd[0][0] = '-';
450                         strcpy(cmd[0] + 1, s);
451                 }
452 #if ENABLE_FEATURE_INIT_SCTTY
453                 /* Establish this process as session leader and
454                  * (attempt) to make the tty (if any) a controlling tty.
455                  */
456                 setsid();
457                 ioctl(0, TIOCSCTTY, 0 /*don't steal it*/);
458 #endif
459         }
460
461 #if !defined(__UCLIBC__) || defined(__ARCH_HAS_MMU__)
462         if (a->action & ASKFIRST) {
463                 static const char press_enter[] ALIGN1 =
464 #ifdef CUSTOMIZED_BANNER
465 #include CUSTOMIZED_BANNER
466 #endif
467                         "\nPlease press Enter to activate this console. ";
468                 char c;
469                 /*
470                  * Save memory by not exec-ing anything large (like a shell)
471                  * before the user wants it. This is critical if swap is not
472                  * enabled and the system has low memory. Generally this will
473                  * be run on the second virtual console, and the first will
474                  * be allowed to start a shell or whatever an init script
475                  * specifies.
476                  */
477                 messageD(L_LOG, "waiting for enter to start '%s'"
478                                         "(pid %d, tty '%s')\n",
479                                   cmdpath, getpid(), a->terminal);
480                 full_write(1, press_enter, sizeof(press_enter) - 1);
481                 while (read(0, &c, 1) == 1 && c != '\n')
482                         ;
483         }
484 #endif
485         /* Log the process name and args */
486         message(L_LOG, "starting pid %d, tty '%s': '%s'",
487                           getpid(), a->terminal, cmdpath);
488
489 #if ENABLE_FEATURE_INIT_COREDUMPS
490         {
491                 struct stat sb;
492                 if (stat(CORE_ENABLE_FLAG_FILE, &sb) == 0) {
493                         struct rlimit limit;
494
495                         limit.rlim_cur = RLIM_INFINITY;
496                         limit.rlim_max = RLIM_INFINITY;
497                         setrlimit(RLIMIT_CORE, &limit);
498                 }
499         }
500 #endif
501         /* Now run it.  The new program will take over this PID,
502          * so nothing further in init.c should be run. */
503         BB_EXECVP(cmdpath, cmd);
504
505         /* We're still here?  Some error happened. */
506         message(L_LOG | L_CONSOLE, "Cannot run '%s': %s",
507                         cmdpath, strerror(errno));
508         _exit(-1);
509 }
510
511 static int waitfor(const struct init_action *a, pid_t pid)
512 {
513         int runpid;
514         int status, wpid;
515
516         runpid = (NULL == a)? pid : run(a);
517         while (1) {
518                 wpid = waitpid(runpid, &status, 0);
519                 if (wpid == runpid)
520                         break;
521                 if (wpid == -1 && errno == ECHILD) {
522                         /* we missed its termination */
523                         break;
524                 }
525                 /* FIXME other errors should maybe trigger an error, but allow
526                  * the program to continue */
527         }
528         return wpid;
529 }
530
531 /* Run all commands of a particular type */
532 static void run_actions(int action)
533 {
534         struct init_action *a, *tmp;
535
536         for (a = init_action_list; a; a = tmp) {
537                 tmp = a->next;
538                 if (a->action == action) {
539                         /* a->terminal of "" means "init's console" */
540                         if (a->terminal[0] && access(a->terminal, R_OK | W_OK)) {
541                                 delete_init_action(a);
542                         } else if (a->action & (SYSINIT | WAIT | CTRLALTDEL | SHUTDOWN | RESTART)) {
543                                 waitfor(a, 0);
544                                 delete_init_action(a);
545                         } else if (a->action & ONCE) {
546                                 run(a);
547                                 delete_init_action(a);
548                         } else if (a->action & (RESPAWN | ASKFIRST)) {
549                                 /* Only run stuff with pid==0.  If they have
550                                  * a pid, that means it is still running */
551                                 if (a->pid == 0) {
552                                         a->pid = run(a);
553                                 }
554                         }
555                 }
556         }
557 }
558
559 #if !ENABLE_DEBUG_INIT
560 static void init_reboot(unsigned long magic)
561 {
562         pid_t pid;
563         /* We have to fork here, since the kernel calls do_exit(0) in
564          * linux/kernel/sys.c, which can cause the machine to panic when
565          * the init process is killed.... */
566         pid = vfork();
567         if (pid == 0) { /* child */
568                 reboot(magic);
569                 _exit(0);
570         }
571         waitpid(pid, NULL, 0);
572 }
573
574 static void shutdown_system(void)
575 {
576         sigset_t block_signals;
577
578         /* run everything to be run at "shutdown".  This is done _prior_
579          * to killing everything, in case people wish to use scripts to
580          * shut things down gracefully... */
581         run_actions(SHUTDOWN);
582
583         /* first disable all our signals */
584         sigemptyset(&block_signals);
585         sigaddset(&block_signals, SIGHUP);
586         sigaddset(&block_signals, SIGQUIT);
587         sigaddset(&block_signals, SIGCHLD);
588         sigaddset(&block_signals, SIGUSR1);
589         sigaddset(&block_signals, SIGUSR2);
590         sigaddset(&block_signals, SIGINT);
591         sigaddset(&block_signals, SIGTERM);
592         sigaddset(&block_signals, SIGCONT);
593         sigaddset(&block_signals, SIGSTOP);
594         sigaddset(&block_signals, SIGTSTP);
595         sigprocmask(SIG_BLOCK, &block_signals, NULL);
596
597         message(L_CONSOLE | L_LOG, "The system is going down NOW!");
598
599         /* Allow Ctrl-Alt-Del to reboot system. */
600         init_reboot(RB_ENABLE_CAD);
601
602         /* Send signals to every process _except_ pid 1 */
603         message(L_CONSOLE | L_LOG, "Sending SIG%s to all processes", "TERM");
604         kill(-1, SIGTERM);
605         sync();
606         sleep(1);
607
608         message(L_CONSOLE | L_LOG, "Sending SIG%s to all processes", "KILL");
609         kill(-1, SIGKILL);
610         sync();
611         sleep(1);
612 }
613
614 static void exec_signal(int sig ATTRIBUTE_UNUSED)
615 {
616         struct init_action *a, *tmp;
617         sigset_t unblock_signals;
618
619         for (a = init_action_list; a; a = tmp) {
620                 tmp = a->next;
621                 if (a->action & RESTART) {
622                         shutdown_system();
623
624                         /* unblock all signals, blocked in shutdown_system() */
625                         sigemptyset(&unblock_signals);
626                         sigaddset(&unblock_signals, SIGHUP);
627                         sigaddset(&unblock_signals, SIGQUIT);
628                         sigaddset(&unblock_signals, SIGCHLD);
629                         sigaddset(&unblock_signals, SIGUSR1);
630                         sigaddset(&unblock_signals, SIGUSR2);
631                         sigaddset(&unblock_signals, SIGINT);
632                         sigaddset(&unblock_signals, SIGTERM);
633                         sigaddset(&unblock_signals, SIGCONT);
634                         sigaddset(&unblock_signals, SIGSTOP);
635                         sigaddset(&unblock_signals, SIGTSTP);
636                         sigprocmask(SIG_UNBLOCK, &unblock_signals, NULL);
637
638                         /* Open the new terminal device */
639                         open_stdio_to_tty(a->terminal, 0);
640
641                         messageD(L_CONSOLE | L_LOG, "Trying to re-exec %s", a->command);
642                         BB_EXECLP(a->command, a->command, NULL);
643
644                         message(L_CONSOLE | L_LOG, "Cannot run '%s': %s",
645                                         a->command, strerror(errno));
646                         sleep(2);
647                         init_reboot(RB_HALT_SYSTEM);
648                         loop_forever();
649                 }
650         }
651 }
652
653 static void shutdown_signal(int sig)
654 {
655         const char *m;
656         int rb;
657
658         shutdown_system();
659
660         m = "halt";
661         rb = RB_HALT_SYSTEM;
662         if (sig == SIGTERM) {
663                 m = "reboot";
664                 rb = RB_AUTOBOOT;
665         } else if (sig == SIGUSR2) {
666                 m = "poweroff";
667                 rb = RB_POWER_OFF;
668         }
669         message(L_CONSOLE | L_LOG, "Requesting system %s", m);
670         /* allow time for last message to reach serial console */
671         sleep(2);
672         init_reboot(rb);
673         loop_forever();
674 }
675
676 static void ctrlaltdel_signal(int sig ATTRIBUTE_UNUSED)
677 {
678         run_actions(CTRLALTDEL);
679 }
680
681 /* The SIGSTOP & SIGTSTP handler */
682 static void stop_handler(int sig ATTRIBUTE_UNUSED)
683 {
684         int saved_errno = errno;
685
686         got_cont = 0;
687         while (!got_cont)
688                 pause();
689         got_cont = 0;
690         errno = saved_errno;
691 }
692
693 /* The SIGCONT handler */
694 static void cont_handler(int sig ATTRIBUTE_UNUSED)
695 {
696         got_cont = 1;
697 }
698
699 #endif  /* !ENABLE_DEBUG_INIT */
700
701 static void new_init_action(int action, const char *command, const char *cons)
702 {
703         struct init_action *new_action, *a, *last;
704
705         if (strcmp(cons, bb_dev_null) == 0 && (action & ASKFIRST))
706                 return;
707
708         /* Append to the end of the list */
709         for (a = last = init_action_list; a; a = a->next) {
710                 /* don't enter action if it's already in the list,
711                  * but do overwrite existing actions */
712                 if ((strcmp(a->command, command) == 0)
713                  && (strcmp(a->terminal, cons) == 0)
714                 ) {
715                         a->action = action;
716                         return;
717                 }
718                 last = a;
719         }
720
721         new_action = xzalloc(sizeof(struct init_action));
722         if (last) {
723                 last->next = new_action;
724         } else {
725                 init_action_list = new_action;
726         }
727         strcpy(new_action->command, command);
728         new_action->action = action;
729         strcpy(new_action->terminal, cons);
730         messageD(L_LOG | L_CONSOLE, "command='%s' action=%d tty='%s'\n",
731                 new_action->command, new_action->action, new_action->terminal);
732 }
733
734 static void delete_init_action(struct init_action *action)
735 {
736         struct init_action *a, *b = NULL;
737
738         for (a = init_action_list; a; b = a, a = a->next) {
739                 if (a == action) {
740                         if (b == NULL) {
741                                 init_action_list = a->next;
742                         } else {
743                                 b->next = a->next;
744                         }
745                         free(a);
746                         break;
747                 }
748         }
749 }
750
751 /* NOTE that if CONFIG_FEATURE_USE_INITTAB is NOT defined,
752  * then parse_inittab() simply adds in some default
753  * actions(i.e., runs INIT_SCRIPT and then starts a pair
754  * of "askfirst" shells).  If CONFIG_FEATURE_USE_INITTAB
755  * _is_ defined, but /etc/inittab is missing, this
756  * results in the same set of default behaviors.
757  */
758 static void parse_inittab(void)
759 {
760 #if ENABLE_FEATURE_USE_INITTAB
761         FILE *file;
762         char buf[INIT_BUFFS_SIZE], lineAsRead[INIT_BUFFS_SIZE];
763         char tmpConsole[CONSOLE_NAME_SIZE];
764         char *id, *runlev, *action, *command, *eol;
765         const struct init_action_type *a = actions;
766
767         file = fopen(INITTAB, "r");
768         if (file == NULL) {
769                 /* No inittab file -- set up some default behavior */
770 #endif
771                 /* Reboot on Ctrl-Alt-Del */
772                 new_init_action(CTRLALTDEL, "reboot", "");
773                 /* Umount all filesystems on halt/reboot */
774                 new_init_action(SHUTDOWN, "umount -a -r", "");
775                 /* Swapoff on halt/reboot */
776                 if (ENABLE_SWAPONOFF) new_init_action(SHUTDOWN, "swapoff -a", "");
777                 /* Prepare to restart init when a HUP is received */
778                 new_init_action(RESTART, "init", "");
779                 /* Askfirst shell on tty1-4 */
780                 new_init_action(ASKFIRST, bb_default_login_shell, "");
781                 new_init_action(ASKFIRST, bb_default_login_shell, VC_2);
782                 new_init_action(ASKFIRST, bb_default_login_shell, VC_3);
783                 new_init_action(ASKFIRST, bb_default_login_shell, VC_4);
784                 /* sysinit */
785                 new_init_action(SYSINIT, INIT_SCRIPT, "");
786
787                 return;
788 #if ENABLE_FEATURE_USE_INITTAB
789         }
790
791         while (fgets(buf, INIT_BUFFS_SIZE, file) != NULL) {
792                 /* Skip leading spaces */
793                 for (id = buf; *id == ' ' || *id == '\t'; id++);
794
795                 /* Skip the line if it's a comment */
796                 if (*id == '#' || *id == '\n')
797                         continue;
798
799                 /* Trim the trailing \n */
800                 //XXX: chomp() ?
801                 eol = strrchr(id, '\n');
802                 if (eol != NULL)
803                         *eol = '\0';
804
805                 /* Keep a copy around for posterity's sake (and error msgs) */
806                 strcpy(lineAsRead, buf);
807
808                 /* Separate the ID field from the runlevels */
809                 runlev = strchr(id, ':');
810                 if (runlev == NULL || *(runlev + 1) == '\0') {
811                         message(L_LOG | L_CONSOLE, "Bad inittab entry: %s", lineAsRead);
812                         continue;
813                 } else {
814                         *runlev = '\0';
815                         ++runlev;
816                 }
817
818                 /* Separate the runlevels from the action */
819                 action = strchr(runlev, ':');
820                 if (action == NULL || *(action + 1) == '\0') {
821                         message(L_LOG | L_CONSOLE, "Bad inittab entry: %s", lineAsRead);
822                         continue;
823                 } else {
824                         *action = '\0';
825                         ++action;
826                 }
827
828                 /* Separate the action from the command */
829                 command = strchr(action, ':');
830                 if (command == NULL || *(command + 1) == '\0') {
831                         message(L_LOG | L_CONSOLE, "Bad inittab entry: %s", lineAsRead);
832                         continue;
833                 } else {
834                         *command = '\0';
835                         ++command;
836                 }
837
838                 /* Ok, now process it */
839                 for (a = actions; a->name != 0; a++) {
840                         if (strcmp(a->name, action) == 0) {
841                                 if (*id != '\0') {
842                                         if (strncmp(id, "/dev/", 5) == 0)
843                                                 id += 5;
844                                         strcpy(tmpConsole, "/dev/");
845                                         safe_strncpy(tmpConsole + 5, id,
846                                                 sizeof(tmpConsole) - 5);
847                                         id = tmpConsole;
848                                 }
849                                 new_init_action(a->action, command, id);
850                                 break;
851                         }
852                 }
853                 if (a->name == 0) {
854                         /* Choke on an unknown action */
855                         message(L_LOG | L_CONSOLE, "Bad inittab entry: %s", lineAsRead);
856                 }
857         }
858         fclose(file);
859 #endif /* FEATURE_USE_INITTAB */
860 }
861
862 #if ENABLE_FEATURE_USE_INITTAB
863 static void reload_signal(int sig ATTRIBUTE_UNUSED)
864 {
865         struct init_action *a, *tmp;
866
867         message(L_LOG, "reloading /etc/inittab");
868
869         /* disable old entrys */
870         for (a = init_action_list; a; a = a->next ) {
871                 a->action = ONCE;
872         }
873
874         parse_inittab();
875
876         /* remove unused entrys */
877         for (a = init_action_list; a; a = tmp) {
878                 tmp = a->next;
879                 if ((a->action & (ONCE | SYSINIT | WAIT)) && a->pid == 0) {
880                         delete_init_action(a);
881                 }
882         }
883         run_actions(RESPAWN);
884 }
885 #endif  /* FEATURE_USE_INITTAB */
886
887 int init_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
888 int init_main(int argc, char **argv)
889 {
890         struct init_action *a;
891         pid_t wpid;
892
893         die_sleep = 30 * 24*60*60; /* if xmalloc will ever die... */
894
895         if (argc > 1 && !strcmp(argv[1], "-q")) {
896                 return kill(1, SIGHUP);
897         }
898 #if !ENABLE_DEBUG_INIT
899         /* Expect to be invoked as init with PID=1 or be invoked as linuxrc */
900         if (getpid() != 1
901          && (!ENABLE_FEATURE_INITRD || !strstr(applet_name, "linuxrc"))
902         ) {
903                 bb_show_usage();
904         }
905         /* Set up sig handlers  -- be sure to
906          * clear all of these in run() */
907         signal(SIGHUP, exec_signal);
908         signal(SIGQUIT, exec_signal);
909         signal(SIGUSR1, shutdown_signal);
910         signal(SIGUSR2, shutdown_signal);
911         signal(SIGINT, ctrlaltdel_signal);
912         signal(SIGTERM, shutdown_signal);
913         signal(SIGCONT, cont_handler);
914         signal(SIGSTOP, stop_handler);
915         signal(SIGTSTP, stop_handler);
916
917         /* Turn off rebooting via CTL-ALT-DEL -- we get a
918          * SIGINT on CAD so we can shut things down gracefully... */
919         init_reboot(RB_DISABLE_CAD);
920 #endif
921
922
923         /* Figure out where the default console should be */
924         console_init();
925         set_sane_term();
926         chdir("/");
927         setsid();
928         {
929                 const char *const *e;
930                 /* Make sure environs is set to something sane */
931                 for (e = environment; *e; e++)
932                         putenv((char *) *e);
933         }
934
935         if (argc > 1) setenv("RUNLEVEL", argv[1], 1);
936
937         /* Hello world */
938         message(MAYBE_CONSOLE | L_LOG, "init started: %s", bb_banner);
939
940         /* Make sure there is enough memory to do something useful. */
941         if (ENABLE_SWAPONOFF) {
942                 struct sysinfo info;
943
944                 if (!sysinfo(&info) &&
945                         (info.mem_unit ? : 1) * (long long)info.totalram < 1024*1024)
946                 {
947                         message(L_CONSOLE, "Low memory, forcing swapon");
948                         /* swapon -a requires /proc typically */
949                         new_init_action(SYSINIT, "mount -t proc proc /proc", "");
950                         /* Try to turn on swap */
951                         new_init_action(SYSINIT, "swapon -a", "");
952                         run_actions(SYSINIT);   /* wait and removing */
953                 }
954         }
955
956         /* Check if we are supposed to be in single user mode */
957         if (argc > 1
958          && (!strcmp(argv[1], "single") || !strcmp(argv[1], "-s") || LONE_CHAR(argv[1], '1'))
959         ) {
960                 /* Start a shell on console */
961                 new_init_action(RESPAWN, bb_default_login_shell, "");
962         } else {
963                 /* Not in single user mode -- see what inittab says */
964
965                 /* NOTE that if CONFIG_FEATURE_USE_INITTAB is NOT defined,
966                  * then parse_inittab() simply adds in some default
967                  * actions(i.e., runs INIT_SCRIPT and then starts a pair
968                  * of "askfirst" shells */
969                 parse_inittab();
970         }
971
972 #if ENABLE_SELINUX
973         if (getenv("SELINUX_INIT") == NULL) {
974                 int enforce = 0;
975
976                 putenv((char*)"SELINUX_INIT=YES");
977                 if (selinux_init_load_policy(&enforce) == 0) {
978                         BB_EXECVP(argv[0], argv);
979                 } else if (enforce > 0) {
980                         /* SELinux in enforcing mode but load_policy failed */
981                         /* At this point, we probably can't open /dev/console, so log() won't work */
982                         message(L_CONSOLE, "Cannot load SELinux Policy. "
983                                 "Machine is in enforcing mode. Halting now.");
984                         exit(1);
985                 }
986         }
987 #endif /* CONFIG_SELINUX */
988
989         /* Make the command line just say "init"  -- thats all, nothing else */
990         fixup_argv(argv);
991
992         /* Now run everything that needs to be run */
993
994         /* First run the sysinit command */
995         run_actions(SYSINIT);
996
997         /* Next run anything that wants to block */
998         run_actions(WAIT);
999
1000         /* Next run anything to be run only once */
1001         run_actions(ONCE);
1002
1003 #if ENABLE_FEATURE_USE_INITTAB
1004         /* Redefine SIGHUP to reread /etc/inittab */
1005         signal(SIGHUP, reload_signal);
1006 #else
1007         signal(SIGHUP, SIG_IGN);
1008 #endif /* FEATURE_USE_INITTAB */
1009
1010         /* Now run the looping stuff for the rest of forever */
1011         while (1) {
1012                 /* run the respawn stuff */
1013                 run_actions(RESPAWN);
1014
1015                 /* run the askfirst stuff */
1016                 run_actions(ASKFIRST);
1017
1018                 /* Don't consume all CPU time -- sleep a bit */
1019                 sleep(1);
1020
1021                 /* Wait for a child process to exit */
1022                 wpid = wait(NULL);
1023                 while (wpid > 0) {
1024                         /* Find out who died and clean up their corpse */
1025                         for (a = init_action_list; a; a = a->next) {
1026                                 if (a->pid == wpid) {
1027                                         /* Set the pid to 0 so that the process gets
1028                                          * restarted by run_actions() */
1029                                         a->pid = 0;
1030                                         message(L_LOG, "process '%s' (pid %d) exited. "
1031                                                         "Scheduling it for restart.",
1032                                                         a->command, wpid);
1033                                 }
1034                         }
1035                         /* see if anyone else is waiting to be reaped */
1036                         wpid = waitpid(-1, NULL, WNOHANG);
1037                 }
1038         }
1039 }