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