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