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