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