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