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