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