Make sure FILE pointer returned by hdopen() is not leaked even if the
[sysvinit.git] / src / init.c
CommitLineData
a74aeac6
PR
1/*
2 * Init A System-V Init Clone.
3 *
4 * Usage: /sbin/init
5 * init [0123456SsQqAaBbCc]
6 * telinit [0123456SsQqAaBbCc]
7 *
8 * Version: @(#)init.c 2.86 30-Jul-2004 miquels@cistron.nl
9 */
c6fb5841 10#define VERSION "2.89"
23d97522 11#define DATE "26-Mar-2010"
a74aeac6
PR
12/*
13 * This file is part of the sysvinit suite,
14 * Copyright (C) 1991-2004 Miquel van Smoorenburg.
15 *
16 * This program is free software; you can redistribute it and/or modify
17 * it under the terms of the GNU General Public License as published by
18 * the Free Software Foundation; either version 2 of the License, or
19 * (at your option) any later version.
20 *
21 * This program is distributed in the hope that it will be useful,
22 * but WITHOUT ANY WARRANTY; without even the implied warranty of
23 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
24 * GNU General Public License for more details.
25 *
26 * You should have received a copy of the GNU General Public License
27 * along with this program; if not, write to the Free Software
28 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
29 *
30 */
31
32#include <sys/types.h>
33#include <sys/stat.h>
34#include <sys/ioctl.h>
35#include <sys/wait.h>
36#ifdef __linux__
37#include <sys/kd.h>
38#endif
39#include <sys/resource.h>
40#include <stdlib.h>
41#include <unistd.h>
42#include <errno.h>
43#include <stdio.h>
44#include <time.h>
45#include <fcntl.h>
46#include <string.h>
47#include <signal.h>
48#include <termios.h>
49#include <utmp.h>
50#include <ctype.h>
51#include <stdarg.h>
52#include <sys/syslog.h>
53#include <sys/time.h>
54
55#ifdef WITH_SELINUX
55f242bf 56# include <selinux/selinux.h>
a74aeac6
PR
57#endif
58
a74aeac6 59#ifdef __i386__
5f959b29 60# ifdef __GLIBC__
a74aeac6
PR
61 /* GNU libc 2.x */
62# define STACK_DEBUG 1
63# if (__GLIBC__ == 2 && __GLIBC_MINOR__ == 0)
64 /* Only glibc 2.0 needs this */
65# include <sigcontext.h>
5f959b29
DWF
66# elif ( __GLIBC__ > 2) && ((__GLIBC__ == 2) && (__GLIBC_MINOR__ >= 1))
67# include <bits/sigcontext.h>
a74aeac6
PR
68# endif
69# endif
70#endif
71
72#include "init.h"
73#include "initreq.h"
74#include "paths.h"
75#include "reboot.h"
76#include "set.h"
77
78#ifndef SIGPWR
79# define SIGPWR SIGUSR2
80#endif
81
82#ifndef CBAUD
83# define CBAUD 0
84#endif
85#ifndef CBAUDEX
86# define CBAUDEX 0
87#endif
88
89/* Set a signal handler. */
90#define SETSIG(sa, sig, fun, flags) \
91 do { \
c5ae561e 92 memset(&sa, 0, sizeof(sa)); \
a74aeac6
PR
93 sa.sa_handler = fun; \
94 sa.sa_flags = flags; \
95 sigemptyset(&sa.sa_mask); \
96 sigaction(sig, &sa, NULL); \
97 } while(0)
98
99/* Version information */
100char *Version = "@(#) init " VERSION " " DATE " miquels@cistron.nl";
101char *bootmsg = "version " VERSION " %s";
102#define E_VERSION "INIT_VERSION=sysvinit-" VERSION
103
104CHILD *family = NULL; /* The linked list of all entries */
105CHILD *newFamily = NULL; /* The list after inittab re-read */
106
107CHILD ch_emerg = { /* Emergency shell */
108 WAITING, 0, 0, 0, 0,
109 "~~",
110 "S",
111 3,
112 "/sbin/sulogin",
113 NULL,
114 NULL
115};
116
117char runlevel = 'S'; /* The current run level */
118char thislevel = 'S'; /* The current runlevel */
119char prevlevel = 'N'; /* Previous runlevel */
120int dfl_level = 0; /* Default runlevel */
121sig_atomic_t got_cont = 0; /* Set if we received the SIGCONT signal */
122sig_atomic_t got_signals; /* Set if we received a signal. */
123int emerg_shell = 0; /* Start emergency shell? */
124int wrote_wtmp_reboot = 1; /* Set when we wrote the reboot record */
125int wrote_utmp_reboot = 1; /* Set when we wrote the reboot record */
63a2c981
DWF
126int wrote_wtmp_rlevel = 1; /* Set when we wrote the runlevel record */
127int wrote_utmp_rlevel = 1; /* Set when we wrote the runlevel record */
a74aeac6
PR
128int sltime = 5; /* Sleep time between TERM and KILL */
129char *argv0; /* First arguments; show up in ps listing */
130int maxproclen; /* Maximal length of argv[0] with \0 */
131struct utmp utproto; /* Only used for sizeof(utproto.ut_id) */
a74aeac6
PR
132char *console_dev; /* Console device. */
133int pipe_fd = -1; /* /dev/initctl */
134int did_boot = 0; /* Did we already do BOOT* stuff? */
135int main(int, char **);
136
137/* Used by re-exec part */
138int reload = 0; /* Should we do initialization stuff? */
139char *myname="/sbin/init"; /* What should we exec */
140int oops_error; /* Used by some of the re-exec code. */
141const char *Signature = "12567362"; /* Signature for re-exec fd */
142
143/* Macro to see if this is a special action */
144#define ISPOWER(i) ((i) == POWERWAIT || (i) == POWERFAIL || \
145 (i) == POWEROKWAIT || (i) == POWERFAILNOW || \
146 (i) == CTRLALTDEL)
147
148/* ascii values for the `action' field. */
149struct actions {
150 char *name;
151 int act;
152} actions[] = {
153 { "respawn", RESPAWN },
154 { "wait", WAIT },
155 { "once", ONCE },
156 { "boot", BOOT },
157 { "bootwait", BOOTWAIT },
158 { "powerfail", POWERFAIL },
159 { "powerfailnow",POWERFAILNOW },
160 { "powerwait", POWERWAIT },
161 { "powerokwait", POWEROKWAIT },
162 { "ctrlaltdel", CTRLALTDEL },
163 { "off", OFF },
164 { "ondemand", ONDEMAND },
165 { "initdefault", INITDEFAULT },
166 { "sysinit", SYSINIT },
167 { "kbrequest", KBREQUEST },
168 { NULL, 0 },
169};
170
171/*
172 * State parser token table (see receive_state)
173 */
174struct {
175 char name[4];
176 int cmd;
177} cmds[] = {
178 { "VER", C_VER },
179 { "END", C_END },
180 { "REC", C_REC },
181 { "EOR", C_EOR },
182 { "LEV", C_LEV },
183 { "FL ", C_FLAG },
184 { "AC ", C_ACTION },
185 { "CMD", C_PROCESS },
186 { "PID", C_PID },
187 { "EXS", C_EXS },
188 { "-RL", D_RUNLEVEL },
189 { "-TL", D_THISLEVEL },
190 { "-PL", D_PREVLEVEL },
191 { "-SI", D_GOTSIGN },
192 { "-WR", D_WROTE_WTMP_REBOOT},
193 { "-WU", D_WROTE_UTMP_REBOOT},
194 { "-ST", D_SLTIME },
195 { "-DB", D_DIDBOOT },
63a2c981
DWF
196 { "-LW", D_WROTE_WTMP_RLEVEL},
197 { "-LU", D_WROTE_UTMP_RLEVEL},
a74aeac6
PR
198 { "", 0 }
199};
200struct {
201 char *name;
202 int mask;
203} flags[]={
204 {"RU",RUNNING},
205 {"DE",DEMAND},
206 {"XD",XECUTED},
207 {"WT",WAITING},
208 {NULL,0}
209};
210
211#define NR_EXTRA_ENV 16
212char *extra_env[NR_EXTRA_ENV];
213
214
215/*
216 * Sleep a number of seconds.
217 *
218 * This only works correctly because the linux select updates
219 * the elapsed time in the struct timeval passed to select!
220 */
5f959b29 221static
a74aeac6
PR
222void do_sleep(int sec)
223{
224 struct timeval tv;
225
226 tv.tv_sec = sec;
227 tv.tv_usec = 0;
228
229 while(select(0, NULL, NULL, NULL, &tv) < 0 && errno == EINTR)
230 ;
231}
232
233
234/*
235 * Non-failing allocation routines (init cannot fail).
236 */
5f959b29 237static
a74aeac6
PR
238void *imalloc(size_t size)
239{
240 void *m;
241
242 while ((m = malloc(size)) == NULL) {
243 initlog(L_VB, "out of memory");
244 do_sleep(5);
245 }
246 memset(m, 0, size);
247 return m;
248}
249
5f959b29 250static
23de6d4a 251char *istrdup(const char *s)
a74aeac6
PR
252{
253 char *m;
254 int l;
255
256 l = strlen(s) + 1;
257 m = imalloc(l);
258 memcpy(m, s, l);
259 return m;
260}
261
262
263/*
264 * Send the state info of the previous running init to
265 * the new one, in a version-independant way.
266 */
5f959b29 267static
a74aeac6
PR
268void send_state(int fd)
269{
270 FILE *fp;
271 CHILD *p;
272 int i,val;
273
274 fp = fdopen(fd,"w");
275
276 fprintf(fp, "VER%s\n", Version);
277 fprintf(fp, "-RL%c\n", runlevel);
278 fprintf(fp, "-TL%c\n", thislevel);
279 fprintf(fp, "-PL%c\n", prevlevel);
280 fprintf(fp, "-SI%u\n", got_signals);
281 fprintf(fp, "-WR%d\n", wrote_wtmp_reboot);
282 fprintf(fp, "-WU%d\n", wrote_utmp_reboot);
283 fprintf(fp, "-ST%d\n", sltime);
284 fprintf(fp, "-DB%d\n", did_boot);
285
286 for (p = family; p; p = p->next) {
287 fprintf(fp, "REC%s\n", p->id);
288 fprintf(fp, "LEV%s\n", p->rlevel);
289 for (i = 0, val = p->flags; flags[i].mask; i++)
290 if (val & flags[i].mask) {
291 val &= ~flags[i].mask;
292 fprintf(fp, "FL %s\n",flags[i].name);
293 }
294 fprintf(fp, "PID%d\n",p->pid);
295 fprintf(fp, "EXS%u\n",p->exstat);
296 for(i = 0; actions[i].act; i++)
297 if (actions[i].act == p->action) {
298 fprintf(fp, "AC %s\n", actions[i].name);
299 break;
300 }
301 fprintf(fp, "CMD%s\n", p->process);
302 fprintf(fp, "EOR\n");
303 }
304 fprintf(fp, "END\n");
305 fclose(fp);
306}
307
308/*
309 * Read a string from a file descriptor.
310 * FIXME: why not use fgets() ?
311 */
312static int get_string(char *p, int size, FILE *f)
313{
314 int c;
315
316 while ((c = getc(f)) != EOF && c != '\n') {
317 if (--size > 0)
318 *p++ = c;
319 }
320 *p = '\0';
321 return (c != EOF) && (size > 0);
322}
323
324/*
325 * Read trailing data from the state pipe until we see a newline.
326 */
327static int get_void(FILE *f)
328{
329 int c;
330
331 while ((c = getc(f)) != EOF && c != '\n')
332 ;
333
334 return (c != EOF);
335}
336
337/*
338 * Read the next "command" from the state pipe.
339 */
340static int get_cmd(FILE *f)
341{
342 char cmd[4] = " ";
343 int i;
344
345 if (fread(cmd, 1, sizeof(cmd) - 1, f) != sizeof(cmd) - 1)
346 return C_EOF;
347
348 for(i = 0; cmds[i].cmd && strcmp(cmds[i].name, cmd) != 0; i++)
349 ;
350 return cmds[i].cmd;
351}
352
353/*
354 * Read a CHILD * from the state pipe.
355 */
356static CHILD *get_record(FILE *f)
357{
358 int cmd;
359 char s[32];
360 int i;
361 CHILD *p;
362
363 do {
364 switch (cmd = get_cmd(f)) {
365 case C_END:
366 get_void(f);
367 return NULL;
368 case 0:
369 get_void(f);
370 break;
371 case C_REC:
372 break;
373 case D_RUNLEVEL:
374 fscanf(f, "%c\n", &runlevel);
375 break;
376 case D_THISLEVEL:
377 fscanf(f, "%c\n", &thislevel);
378 break;
379 case D_PREVLEVEL:
380 fscanf(f, "%c\n", &prevlevel);
381 break;
382 case D_GOTSIGN:
383 fscanf(f, "%u\n", &got_signals);
384 break;
385 case D_WROTE_WTMP_REBOOT:
386 fscanf(f, "%d\n", &wrote_wtmp_reboot);
387 break;
388 case D_WROTE_UTMP_REBOOT:
389 fscanf(f, "%d\n", &wrote_utmp_reboot);
390 break;
391 case D_SLTIME:
392 fscanf(f, "%d\n", &sltime);
393 break;
394 case D_DIDBOOT:
395 fscanf(f, "%d\n", &did_boot);
396 break;
63a2c981
DWF
397 case D_WROTE_WTMP_RLEVEL:
398 fscanf(f, "%d\n", &wrote_wtmp_rlevel);
399 break;
400 case D_WROTE_UTMP_RLEVEL:
401 fscanf(f, "%d\n", &wrote_utmp_rlevel);
402 break;
a74aeac6
PR
403 default:
404 if (cmd > 0 || cmd == C_EOF) {
405 oops_error = -1;
406 return NULL;
407 }
408 }
409 } while (cmd != C_REC);
410
411 p = imalloc(sizeof(CHILD));
412 get_string(p->id, sizeof(p->id), f);
413
414 do switch(cmd = get_cmd(f)) {
415 case 0:
416 case C_EOR:
417 get_void(f);
418 break;
419 case C_PID:
420 fscanf(f, "%d\n", &(p->pid));
421 break;
422 case C_EXS:
423 fscanf(f, "%u\n", &(p->exstat));
424 break;
425 case C_LEV:
426 get_string(p->rlevel, sizeof(p->rlevel), f);
427 break;
428 case C_PROCESS:
429 get_string(p->process, sizeof(p->process), f);
430 break;
431 case C_FLAG:
432 get_string(s, sizeof(s), f);
433 for(i = 0; flags[i].name; i++) {
434 if (strcmp(flags[i].name,s) == 0)
435 break;
436 }
437 p->flags |= flags[i].mask;
438 break;
439 case C_ACTION:
440 get_string(s, sizeof(s), f);
441 for(i = 0; actions[i].name; i++) {
442 if (strcmp(actions[i].name, s) == 0)
443 break;
444 }
445 p->action = actions[i].act ? actions[i].act : OFF;
446 break;
447 default:
448 free(p);
449 oops_error = -1;
450 return NULL;
451 } while( cmd != C_EOR);
452
453 return p;
454}
455
456/*
457 * Read the complete state info from the state pipe.
458 * Returns 0 on success
459 */
5f959b29 460static
a74aeac6
PR
461int receive_state(int fd)
462{
463 FILE *f;
464 char old_version[256];
465 CHILD **pp;
466
467 f = fdopen(fd, "r");
468
85725a06
PR
469 if (get_cmd(f) != C_VER) {
470 fclose(f);
a74aeac6 471 return -1;
85725a06 472 }
a74aeac6
PR
473 get_string(old_version, sizeof(old_version), f);
474 oops_error = 0;
475 for (pp = &family; (*pp = get_record(f)) != NULL; pp = &((*pp)->next))
476 ;
477 fclose(f);
478 return oops_error;
479}
480
481/*
482 * Set the process title.
483 */
484#ifdef __GNUC__
485__attribute__ ((format (printf, 1, 2)))
486#endif
487static int setproctitle(char *fmt, ...)
488{
489 va_list ap;
490 int len;
491 char buf[256];
492
493 buf[0] = 0;
494
495 va_start(ap, fmt);
496 len = vsnprintf(buf, sizeof(buf), fmt, ap);
497 va_end(ap);
498
499 if (maxproclen > 1) {
500 memset(argv0, 0, maxproclen);
501 strncpy(argv0, buf, maxproclen - 1);
502 }
503
504 return len;
505}
506
507/*
508 * Set console_dev to a working console.
509 */
5f959b29 510static
a74aeac6
PR
511void console_init(void)
512{
513 int fd;
514 int tried_devcons = 0;
515 int tried_vtmaster = 0;
516 char *s;
517
a33820c3 518 if ((s = getenv("CONSOLE")) != NULL)
a74aeac6
PR
519 console_dev = s;
520 else {
521 console_dev = CONSOLE;
522 tried_devcons++;
523 }
524
525 while ((fd = open(console_dev, O_RDONLY|O_NONBLOCK)) < 0) {
526 if (!tried_devcons) {
527 tried_devcons++;
528 console_dev = CONSOLE;
529 continue;
530 }
531 if (!tried_vtmaster) {
532 tried_vtmaster++;
533 console_dev = VT_MASTER;
534 continue;
535 }
536 break;
537 }
538 if (fd < 0)
539 console_dev = "/dev/null";
540 else
541 close(fd);
542}
543
544
545/*
546 * Open the console with retries.
547 */
5f959b29 548static
a74aeac6
PR
549int console_open(int mode)
550{
551 int f, fd = -1;
552 int m;
553
554 /*
555 * Open device in nonblocking mode.
556 */
557 m = mode | O_NONBLOCK;
558
559 /*
560 * Retry the open five times.
561 */
562 for(f = 0; f < 5; f++) {
563 if ((fd = open(console_dev, m)) >= 0) break;
23d97522 564 usleep(10000);
a74aeac6
PR
565 }
566
567 if (fd < 0) return fd;
568
569 /*
570 * Set original flags.
571 */
572 if (m != mode)
573 fcntl(fd, F_SETFL, mode);
574 return fd;
575}
576
577/*
578 * We got a signal (HUP PWR WINCH ALRM INT)
579 */
5f959b29 580static
a74aeac6
PR
581void signal_handler(int sig)
582{
583 ADDSET(got_signals, sig);
584}
585
586/*
587 * SIGCHLD: one of our children has died.
588 */
5f959b29
DWF
589static
590# ifdef __GNUC__
591void chld_handler(int sig __attribute__((unused)))
592# else
593void chld_handler(int sig)
594# endif
a74aeac6
PR
595{
596 CHILD *ch;
597 int pid, st;
598 int saved_errno = errno;
599
600 /*
601 * Find out which process(es) this was (were)
602 */
603 while((pid = waitpid(-1, &st, WNOHANG)) != 0) {
604 if (errno == ECHILD) break;
605 for( ch = family; ch; ch = ch->next )
606 if ( ch->pid == pid && (ch->flags & RUNNING) ) {
607 INITDBG(L_VB,
608 "chld_handler: marked %d as zombie",
609 ch->pid);
610 ADDSET(got_signals, SIGCHLD);
611 ch->exstat = st;
612 ch->flags |= ZOMBIE;
613 if (ch->new) {
614 ch->new->exstat = st;
615 ch->new->flags |= ZOMBIE;
616 }
617 break;
618 }
619 if (ch == NULL) {
620 INITDBG(L_VB, "chld_handler: unknown child %d exited.",
621 pid);
622 }
623 }
624 errno = saved_errno;
625}
626
627/*
628 * Linux ignores all signals sent to init when the
629 * SIG_DFL handler is installed. Therefore we must catch SIGTSTP
630 * and SIGCONT, or else they won't work....
631 *
632 * The SIGCONT handler
633 */
5f959b29
DWF
634static
635# ifdef __GNUC__
636void cont_handler(int sig __attribute__((unused)))
637# else
638void cont_handler(int sig)
639# endif
a74aeac6
PR
640{
641 got_cont = 1;
642}
643
644/*
645 * Fork and dump core in /.
646 */
5f959b29 647static
a74aeac6
PR
648void coredump(void)
649{
650 static int dumped = 0;
651 struct rlimit rlim;
652 sigset_t mask;
653
654 if (dumped) return;
655 dumped = 1;
656
657 if (fork() != 0) return;
658
659 sigfillset(&mask);
660 sigprocmask(SIG_SETMASK, &mask, NULL);
661
662 rlim.rlim_cur = RLIM_INFINITY;
663 rlim.rlim_max = RLIM_INFINITY;
664 setrlimit(RLIMIT_CORE, &rlim);
665 chdir("/");
666
667 signal(SIGSEGV, SIG_DFL);
668 raise(SIGSEGV);
669 sigdelset(&mask, SIGSEGV);
670 sigprocmask(SIG_SETMASK, &mask, NULL);
671
672 do_sleep(5);
673 exit(0);
674}
675
676/*
677 * OOPS: segmentation violation!
678 * If we have the info, print where it occured.
679 * Then sleep 30 seconds and try to continue.
680 */
5f959b29 681static
a74aeac6 682#if defined(STACK_DEBUG) && defined(__linux__)
5f959b29
DWF
683# ifdef __GNUC__
684void segv_handler(int sig __attribute__((unused)), struct sigcontext ctx)
685# else
a74aeac6 686void segv_handler(int sig, struct sigcontext ctx)
5f959b29 687# endif
a74aeac6
PR
688{
689 char *p = "";
690 int saved_errno = errno;
691
692 if ((void *)ctx.eip >= (void *)do_sleep &&
693 (void *)ctx.eip < (void *)main)
694 p = " (code)";
695 initlog(L_VB, "PANIC: segmentation violation at %p%s! "
696 "sleeping for 30 seconds.", (void *)ctx.eip, p);
697 coredump();
698 do_sleep(30);
699 errno = saved_errno;
700}
701#else
5f959b29
DWF
702# ifdef __GNUC__
703void segv_handler(int sig __attribute__((unused)))
704# else
705void segv_handler(int sig)
706# endif
a74aeac6
PR
707{
708 int saved_errno = errno;
709
710 initlog(L_VB,
711 "PANIC: segmentation violation! sleeping for 30 seconds.");
712 coredump();
713 do_sleep(30);
714 errno = saved_errno;
715}
716#endif
717
718/*
719 * The SIGSTOP & SIGTSTP handler
720 */
5f959b29
DWF
721static
722# ifdef __GNUC__
723void stop_handler(int sig __attribute__((unused)))
724# else
725void stop_handler(int sig)
726# endif
a74aeac6
PR
727{
728 int saved_errno = errno;
729
730 got_cont = 0;
731 while(!got_cont) pause();
732 got_cont = 0;
733 errno = saved_errno;
734}
735
736/*
737 * Set terminal settings to reasonable defaults
738 */
5f959b29 739static
a74aeac6
PR
740void console_stty(void)
741{
742 struct termios tty;
743 int fd;
744
745 if ((fd = console_open(O_RDWR|O_NOCTTY)) < 0) {
746 initlog(L_VB, "can't open %s", console_dev);
747 return;
748 }
749
55f242bf
DWF
750#ifdef __FreeBSD_kernel__
751 /*
752 * The kernel of FreeBSD expects userland to set TERM. Usually, we want
753 * "cons25". Later, gettys might disagree on this (i.e. we're not using
754 * syscons) but some boot scripts, like /etc/init.d/xserver-xorg, still
755 * need a non-dumb terminal.
756 */
757 putenv ("TERM=cons25");
758#endif
759
a74aeac6
PR
760 (void) tcgetattr(fd, &tty);
761
762 tty.c_cflag &= CBAUD|CBAUDEX|CSIZE|CSTOPB|PARENB|PARODD;
763 tty.c_cflag |= HUPCL|CLOCAL|CREAD;
764
5f959b29
DWF
765 tty.c_cc[VINTR] = CINTR;
766 tty.c_cc[VQUIT] = CQUIT;
767 tty.c_cc[VERASE] = CERASE; /* ASCII DEL (0177) */
768 tty.c_cc[VKILL] = CKILL;
769 tty.c_cc[VEOF] = CEOF;
770 tty.c_cc[VTIME] = 0;
771 tty.c_cc[VMIN] = 1;
fc3def35 772#ifdef VSWTC /* not defined on FreeBSD */
5f959b29 773 tty.c_cc[VSWTC] = _POSIX_VDISABLE;
fc3def35 774#endif /* VSWTC */
5f959b29
DWF
775 tty.c_cc[VSTART] = CSTART;
776 tty.c_cc[VSTOP] = CSTOP;
777 tty.c_cc[VSUSP] = CSUSP;
778 tty.c_cc[VEOL] = _POSIX_VDISABLE;
779 tty.c_cc[VREPRINT] = CREPRINT;
780 tty.c_cc[VDISCARD] = CDISCARD;
781 tty.c_cc[VWERASE] = CWERASE;
782 tty.c_cc[VLNEXT] = CLNEXT;
783 tty.c_cc[VEOL2] = _POSIX_VDISABLE;
a74aeac6
PR
784
785 /*
786 * Set pre and post processing
787 */
33dca826
DWF
788 tty.c_iflag = IGNPAR|ICRNL|IXON|IXANY
789#ifdef IUTF8 /* Not defined on FreeBSD */
790 | (tty.c_iflag & IUTF8)
334256b0 791#endif /* IUTF8 */
33dca826 792 ;
a74aeac6
PR
793 tty.c_oflag = OPOST|ONLCR;
794 tty.c_lflag = ISIG|ICANON|ECHO|ECHOCTL|ECHOPRT|ECHOKE;
795
5f959b29
DWF
796#if defined(SANE_TIO) && (SANE_TIO == 1)
797 /*
798 * Disable flow control (-ixon), ignore break (ignbrk),
799 * and make nl/cr more usable (sane).
800 */
801 tty.c_iflag |= IGNBRK;
802 tty.c_iflag &= ~(BRKINT|INLCR|IGNCR|IXON);
803 tty.c_oflag &= ~(OCRNL|ONLRET);
804#endif
a74aeac6
PR
805 /*
806 * Now set the terminal line.
807 * We don't care about non-transmitted output data
808 * and non-read input data.
809 */
810 (void) tcsetattr(fd, TCSANOW, &tty);
811 (void) tcflush(fd, TCIOFLUSH);
812 (void) close(fd);
813}
814
c5ae561e
DWF
815static ssize_t
816safe_write(int fd, const char *buffer, size_t count)
817{
818 ssize_t offset = 0;
819
820 while (count > 0) {
821 ssize_t block = write(fd, &buffer[offset], count);
822
823 if (block < 0 && errno == EINTR)
824 continue;
825 if (block <= 0)
826 return offset ? offset : block;
827 offset += block;
828 count -= block;
829 }
830 return offset;
831}
832
a74aeac6
PR
833/*
834 * Print to the system console
835 */
836void print(char *s)
837{
838 int fd;
839
840 if ((fd = console_open(O_WRONLY|O_NOCTTY|O_NDELAY)) >= 0) {
c5ae561e 841 safe_write(fd, s, strlen(s));
a74aeac6
PR
842 close(fd);
843 }
844}
845
846/*
847 * Log something to a logfile and the console.
848 */
849#ifdef __GNUC__
850__attribute__ ((format (printf, 2, 3)))
851#endif
852void initlog(int loglevel, char *s, ...)
853{
854 va_list va_alist;
855 char buf[256];
856 sigset_t nmask, omask;
857
858 va_start(va_alist, s);
859 vsnprintf(buf, sizeof(buf), s, va_alist);
860 va_end(va_alist);
861
862 if (loglevel & L_SY) {
863 /*
864 * Re-establish connection with syslogd every time.
865 * Block signals while talking to syslog.
866 */
867 sigfillset(&nmask);
868 sigprocmask(SIG_BLOCK, &nmask, &omask);
869 openlog("init", 0, LOG_DAEMON);
870 syslog(LOG_INFO, "%s", buf);
871 closelog();
872 sigprocmask(SIG_SETMASK, &omask, NULL);
873 }
874
875 /*
876 * And log to the console.
877 */
878 if (loglevel & L_CO) {
879 print("\rINIT: ");
880 print(buf);
881 print("\r\n");
882 }
883}
884
23de6d4a
DWF
885/*
886 * Add or replace specific environment value
887 */
888int addnewenv(const char *new, char **curr, int n)
889{
890 size_t nlen = strcspn(new, "=");
891 int i;
892 for (i = 0; i < n; i++) {
893 if (nlen != strcspn(curr[i], "="))
894 continue;
895 if (strncmp (new, curr[i], nlen) == 0)
896 break;
897 }
898 if (i >= n)
899 curr[n++] = istrdup(new);
900 else {
901 free(curr[i]);
902 curr[i] = istrdup(new);
903 }
904 return n;
905}
a74aeac6
PR
906
907/*
908 * Build a new environment for execve().
909 */
910char **init_buildenv(int child)
911{
912 char i_lvl[] = "RUNLEVEL=x";
913 char i_prev[] = "PREVLEVEL=x";
23de6d4a 914 char i_cons[128];
5f959b29 915 char i_shell[] = "SHELL=" SHELL;
a74aeac6
PR
916 char **e;
917 int n, i;
918
919 for (n = 0; environ[n]; n++)
920 ;
fcda5be1 921 n += NR_EXTRA_ENV + 1; /* Also room for last NULL */
fd6f5c50 922 if (child)
23d97522 923 n += 8;
23de6d4a
DWF
924
925 while ((e = (char**)calloc(n, sizeof(char *))) == NULL) {
926 initlog(L_VB, "out of memory");
927 do_sleep(5);
928 }
a74aeac6
PR
929
930 for (n = 0; environ[n]; n++)
931 e[n] = istrdup(environ[n]);
932
23d97522 933 for (i = 0; i < NR_EXTRA_ENV; i++) {
23de6d4a
DWF
934 if (extra_env[i] == NULL || *extra_env[i] == '\0')
935 continue;
936 n = addnewenv(extra_env[i], e, n);
23d97522 937 }
a74aeac6
PR
938
939 if (child) {
940 snprintf(i_cons, sizeof(i_cons), "CONSOLE=%s", console_dev);
941 i_lvl[9] = thislevel;
942 i_prev[10] = prevlevel;
23de6d4a
DWF
943 n = addnewenv(i_shell, e, n);
944 n = addnewenv(i_lvl, e, n);
945 n = addnewenv(i_prev, e, n);
946 n = addnewenv(i_cons, e, n);
947 n = addnewenv(E_VERSION, e, n);
a74aeac6
PR
948 }
949
950 e[n++] = NULL;
951
952 return e;
953}
954
955
956void init_freeenv(char **e)
957{
958 int n;
959
960 for (n = 0; e[n]; n++)
961 free(e[n]);
962 free(e);
963}
964
965
966/*
967 * Fork and execute.
968 *
969 * This function is too long and indents too deep.
970 *
971 */
5f959b29 972static
23d97522 973pid_t spawn(CHILD *ch, int *res)
a74aeac6
PR
974{
975 char *args[16]; /* Argv array */
976 char buf[136]; /* Line buffer */
23d97522 977 int f, st; /* Scratch variables */
a74aeac6
PR
978 char *ptr; /* Ditto */
979 time_t t; /* System time */
980 int oldAlarm; /* Previous alarm value */
981 char *proc = ch->process; /* Command line */
982 pid_t pid, pgrp; /* child, console process group. */
983 sigset_t nmask, omask; /* For blocking SIGCHLD */
984 struct sigaction sa;
985
986 *res = -1;
987 buf[sizeof(buf) - 1] = 0;
988
989 /* Skip '+' if it's there */
990 if (proc[0] == '+') proc++;
991
992 ch->flags |= XECUTED;
993
994 if (ch->action == RESPAWN || ch->action == ONDEMAND) {
995 /* Is the date stamp from less than 2 minutes ago? */
996 time(&t);
997 if (ch->tm + TESTTIME > t) {
998 ch->count++;
999 } else {
1000 ch->count = 0;
1001 ch->tm = t;
1002 }
1003
1004 /* Do we try to respawn too fast? */
1005 if (ch->count >= MAXSPAWN) {
1006
1007 initlog(L_VB,
1008 "Id \"%s\" respawning too fast: disabled for %d minutes",
1009 ch->id, SLEEPTIME / 60);
1010 ch->flags &= ~RUNNING;
1011 ch->flags |= FAILING;
1012
1013 /* Remember the time we stopped */
1014 ch->tm = t;
1015
1016 /* Try again in 5 minutes */
1017 oldAlarm = alarm(0);
1018 if (oldAlarm > SLEEPTIME || oldAlarm <= 0) oldAlarm = SLEEPTIME;
1019 alarm(oldAlarm);
1020 return(-1);
1021 }
1022 }
1023
1024 /* See if there is an "initscript" (except in single user mode). */
1025 if (access(INITSCRIPT, R_OK) == 0 && runlevel != 'S') {
1026 /* Build command line using "initscript" */
1027 args[1] = SHELL;
1028 args[2] = INITSCRIPT;
1029 args[3] = ch->id;
1030 args[4] = ch->rlevel;
1031 args[5] = "unknown";
1032 for(f = 0; actions[f].name; f++) {
1033 if (ch->action == actions[f].act) {
1034 args[5] = actions[f].name;
1035 break;
1036 }
1037 }
1038 args[6] = proc;
1039 args[7] = NULL;
1040 } else if (strpbrk(proc, "~`!$^&*()=|\\{}[];\"'<>?")) {
1041 /* See if we need to fire off a shell for this command */
1042 /* Give command line to shell */
1043 args[1] = SHELL;
1044 args[2] = "-c";
1045 strcpy(buf, "exec ");
1046 strncat(buf, proc, sizeof(buf) - strlen(buf) - 1);
1047 args[3] = buf;
1048 args[4] = NULL;
1049 } else {
1050 /* Split up command line arguments */
1051 buf[0] = 0;
1052 strncat(buf, proc, sizeof(buf) - 1);
1053 ptr = buf;
1054 for(f = 1; f < 15; f++) {
1055 /* Skip white space */
1056 while(*ptr == ' ' || *ptr == '\t') ptr++;
1057 args[f] = ptr;
1058
1059 /* May be trailing space.. */
1060 if (*ptr == 0) break;
1061
1062 /* Skip this `word' */
1063 while(*ptr && *ptr != ' ' && *ptr != '\t' && *ptr != '#')
1064 ptr++;
1065
1066 /* If end-of-line, break */
1067 if (*ptr == '#' || *ptr == 0) {
1068 f++;
1069 *ptr = 0;
1070 break;
1071 }
1072 /* End word with \0 and continue */
1073 *ptr++ = 0;
1074 }
1075 args[f] = NULL;
1076 }
1077 args[0] = args[1];
1078 while(1) {
1079 /*
1080 * Block sigchild while forking.
1081 */
1082 sigemptyset(&nmask);
1083 sigaddset(&nmask, SIGCHLD);
1084 sigprocmask(SIG_BLOCK, &nmask, &omask);
1085
1086 if ((pid = fork()) == 0) {
fd6f5c50 1087
a74aeac6
PR
1088 close(0);
1089 close(1);
1090 close(2);
1091 if (pipe_fd >= 0) close(pipe_fd);
1092
1093 sigprocmask(SIG_SETMASK, &omask, NULL);
1094
1095 /*
1096 * In sysinit, boot, bootwait or single user mode:
1097 * for any wait-type subprocess we _force_ the console
1098 * to be its controlling tty.
1099 */
1100 if (strchr("*#sS", runlevel) && ch->flags & WAITING) {
1101 /*
1102 * We fork once extra. This is so that we can
1103 * wait and change the process group and session
1104 * of the console after exit of the leader.
1105 */
1106 setsid();
1107 if ((f = console_open(O_RDWR|O_NOCTTY)) >= 0) {
1108 /* Take over controlling tty by force */
1109 (void)ioctl(f, TIOCSCTTY, 1);
1110 dup(f);
1111 dup(f);
1112 }
63a2c981
DWF
1113
1114 /*
1115 * 4 Sep 2001, Andrea Arcangeli:
1116 * Fix a race in spawn() that is used to deadlock init in a
1117 * waitpid() loop: must set the childhandler as default before forking
1118 * off the child or the chld_handler could run before the waitpid loop
1119 * has a chance to find its zombie-child.
1120 */
a74aeac6
PR
1121 SETSIG(sa, SIGCHLD, SIG_DFL, SA_RESTART);
1122 if ((pid = fork()) < 0) {
1123 initlog(L_VB, "cannot fork: %s",
1124 strerror(errno));
1125 exit(1);
1126 }
1127 if (pid > 0) {
23d97522 1128 pid_t rc;
a74aeac6
PR
1129 /*
1130 * Ignore keyboard signals etc.
1131 * Then wait for child to exit.
1132 */
1133 SETSIG(sa, SIGINT, SIG_IGN, SA_RESTART);
1134 SETSIG(sa, SIGTSTP, SIG_IGN, SA_RESTART);
1135 SETSIG(sa, SIGQUIT, SIG_IGN, SA_RESTART);
1136
1137 while ((rc = waitpid(pid, &st, 0)) != pid)
1138 if (rc < 0 && errno == ECHILD)
1139 break;
1140
1141 /*
1142 * Small optimization. See if stealing
1143 * controlling tty back is needed.
1144 */
1145 pgrp = tcgetpgrp(f);
1146 if (pgrp != getpid())
1147 exit(0);
1148
1149 /*
1150 * Steal controlling tty away. We do
1151 * this with a temporary process.
1152 */
1153 if ((pid = fork()) < 0) {
1154 initlog(L_VB, "cannot fork: %s",
1155 strerror(errno));
1156 exit(1);
1157 }
1158 if (pid == 0) {
1159 setsid();
1160 (void)ioctl(f, TIOCSCTTY, 1);
1161 exit(0);
1162 }
1163 while((rc = waitpid(pid, &st, 0)) != pid)
1164 if (rc < 0 && errno == ECHILD)
1165 break;
1166 exit(0);
1167 }
1168
1169 /* Set ioctl settings to default ones */
1170 console_stty();
1171
1172 } else {
1173 setsid();
1174 if ((f = console_open(O_RDWR|O_NOCTTY)) < 0) {
1175 initlog(L_VB, "open(%s): %s", console_dev,
1176 strerror(errno));
1177 f = open("/dev/null", O_RDWR);
1178 }
1179 dup(f);
1180 dup(f);
1181 }
1182
23d97522
DWF
1183 /*
1184 * Update utmp/wtmp file prior to starting
1185 * any child. This MUST be done right here in
1186 * the child process in order to prevent a race
1187 * condition that occurs when the child
1188 * process' time slice executes before the
1189 * parent (can and does happen in a uniprocessor
1190 * environment). If the child is a getty and
1191 * the race condition happens, then init's utmp
1192 * update will happen AFTER the getty runs
1193 * and expects utmp to be updated already!
1194 *
1195 * Do NOT log if process field starts with '+'
1196 * FIXME: that's for compatibility with *very*
1197 * old getties - probably it can be taken out.
1198 */
1199 if (ch->process[0] != '+')
1200 write_utmp_wtmp("", ch->id, getpid(), INIT_PROCESS, "");
1201
a74aeac6
PR
1202 /* Reset all the signals, set up environment */
1203 for(f = 1; f < NSIG; f++) SETSIG(sa, f, SIG_DFL, SA_RESTART);
1204 environ = init_buildenv(1);
1205
1206 /*
1207 * Execute prog. In case of ENOEXEC try again
1208 * as a shell script.
1209 */
1210 execvp(args[1], args + 1);
1211 if (errno == ENOEXEC) {
1212 args[1] = SHELL;
1213 args[2] = "-c";
1214 strcpy(buf, "exec ");
1215 strncat(buf, proc, sizeof(buf) - strlen(buf) - 1);
1216 args[3] = buf;
1217 args[4] = NULL;
1218 execvp(args[1], args + 1);
1219 }
1220 initlog(L_VB, "cannot execute \"%s\"", args[1]);
23d97522
DWF
1221
1222 if (ch->process[0] != '+')
1223 write_utmp_wtmp("", ch->id, getpid(), DEAD_PROCESS, NULL);
a74aeac6
PR
1224 exit(1);
1225 }
1226 *res = pid;
1227 sigprocmask(SIG_SETMASK, &omask, NULL);
1228
1229 INITDBG(L_VB, "Started id %s (pid %d)", ch->id, pid);
1230
1231 if (pid == -1) {
1232 initlog(L_VB, "cannot fork, retry..");
1233 do_sleep(5);
1234 continue;
1235 }
1236 return(pid);
1237 }
1238}
1239
1240/*
1241 * Start a child running!
1242 */
5f959b29 1243static
a74aeac6
PR
1244void startup(CHILD *ch)
1245{
1246 /*
1247 * See if it's disabled
1248 */
1249 if (ch->flags & FAILING) return;
1250
1251 switch(ch->action) {
1252
1253 case SYSINIT:
1254 case BOOTWAIT:
1255 case WAIT:
1256 case POWERWAIT:
1257 case POWERFAILNOW:
1258 case POWEROKWAIT:
1259 case CTRLALTDEL:
1260 if (!(ch->flags & XECUTED)) ch->flags |= WAITING;
13c69d3f 1261 /* Fall through */
a74aeac6
PR
1262 case KBREQUEST:
1263 case BOOT:
1264 case POWERFAIL:
1265 case ONCE:
1266 if (ch->flags & XECUTED) break;
1267 case ONDEMAND:
1268 case RESPAWN:
1269 ch->flags |= RUNNING;
90c78fcc 1270 (void)spawn(ch, &(ch->pid));
a74aeac6
PR
1271 break;
1272 }
1273}
1274
1275
1276/*
1277 * Read the inittab file.
1278 */
5f959b29 1279static
a74aeac6
PR
1280void read_inittab(void)
1281{
1282 FILE *fp; /* The INITTAB file */
1283 CHILD *ch, *old, *i; /* Pointers to CHILD structure */
1284 CHILD *head = NULL; /* Head of linked list */
1285#ifdef INITLVL
1286 struct stat st; /* To stat INITLVL */
1287#endif
1288 sigset_t nmask, omask; /* For blocking SIGCHLD. */
1289 char buf[256]; /* Line buffer */
1290 char err[64]; /* Error message. */
1291 char *id, *rlevel,
1292 *action, *process; /* Fields of a line */
1293 char *p;
1294 int lineNo = 0; /* Line number in INITTAB file */
1295 int actionNo; /* Decoded action field */
1296 int f; /* Counter */
1297 int round; /* round 0 for SIGTERM, 1 for SIGKILL */
1298 int foundOne = 0; /* No killing no sleep */
1299 int talk; /* Talk to the user */
1300 int done = 0; /* Ready yet? */
1301
1302#if DEBUG
1303 if (newFamily != NULL) {
1304 INITDBG(L_VB, "PANIC newFamily != NULL");
1305 exit(1);
1306 }
1307 INITDBG(L_VB, "Reading inittab");
1308#endif
1309
1310 /*
b55908a4 1311 * Open INITTAB and read line by line.
a74aeac6
PR
1312 */
1313 if ((fp = fopen(INITTAB, "r")) == NULL)
1314 initlog(L_VB, "No inittab file found");
1315
1316 while(!done) {
1317 /*
1318 * Add single user shell entry at the end.
1319 */
1320 if (fp == NULL || fgets(buf, sizeof(buf), fp) == NULL) {
1321 done = 1;
1322 /*
1323 * See if we have a single user entry.
1324 */
1325 for(old = newFamily; old; old = old->next)
1326 if (strpbrk(old->rlevel, "S")) break;
1327 if (old == NULL)
1328 snprintf(buf, sizeof(buf), "~~:S:wait:%s\n", SULOGIN);
1329 else
1330 continue;
1331 }
1332 lineNo++;
1333 /*
1334 * Skip comments and empty lines
1335 */
1336 for(p = buf; *p == ' ' || *p == '\t'; p++)
1337 ;
1338 if (*p == '#' || *p == '\n') continue;
1339
1340 /*
1341 * Decode the fields
1342 */
1343 id = strsep(&p, ":");
1344 rlevel = strsep(&p, ":");
1345 action = strsep(&p, ":");
1346 process = strsep(&p, "\n");
1347
1348 /*
1349 * Check if syntax is OK. Be very verbose here, to
1350 * avoid newbie postings on comp.os.linux.setup :)
1351 */
1352 err[0] = 0;
1353 if (!id || !*id) strcpy(err, "missing id field");
1354 if (!rlevel) strcpy(err, "missing runlevel field");
1355 if (!process) strcpy(err, "missing process field");
1356 if (!action || !*action)
1357 strcpy(err, "missing action field");
1358 if (id && strlen(id) > sizeof(utproto.ut_id))
1359 sprintf(err, "id field too long (max %d characters)",
1360 (int)sizeof(utproto.ut_id));
1361 if (rlevel && strlen(rlevel) > 11)
1362 strcpy(err, "rlevel field too long (max 11 characters)");
1363 if (process && strlen(process) > 127)
1364 strcpy(err, "process field too long");
1365 if (action && strlen(action) > 32)
1366 strcpy(err, "action field too long");
1367 if (err[0] != 0) {
1368 initlog(L_VB, "%s[%d]: %s", INITTAB, lineNo, err);
1369 INITDBG(L_VB, "%s:%s:%s:%s", id, rlevel, action, process);
1370 continue;
1371 }
1372
1373 /*
1374 * Decode the "action" field
1375 */
1376 actionNo = -1;
1377 for(f = 0; actions[f].name; f++)
1378 if (strcasecmp(action, actions[f].name) == 0) {
1379 actionNo = actions[f].act;
1380 break;
1381 }
1382 if (actionNo == -1) {
1383 initlog(L_VB, "%s[%d]: %s: unknown action field",
1384 INITTAB, lineNo, action);
1385 continue;
1386 }
1387
1388 /*
1389 * See if the id field is unique
1390 */
1391 for(old = newFamily; old; old = old->next) {
1392 if(strcmp(old->id, id) == 0 && strcmp(id, "~~")) {
1393 initlog(L_VB, "%s[%d]: duplicate ID field \"%s\"",
1394 INITTAB, lineNo, id);
1395 break;
1396 }
1397 }
1398 if (old) continue;
1399
1400 /*
1401 * Allocate a CHILD structure
1402 */
1403 ch = imalloc(sizeof(CHILD));
1404
1405 /*
1406 * And fill it in.
1407 */
1408 ch->action = actionNo;
1409 strncpy(ch->id, id, sizeof(utproto.ut_id) + 1); /* Hack for different libs. */
1410 strncpy(ch->process, process, sizeof(ch->process) - 1);
1411 if (rlevel[0]) {
192c4567 1412 for(f = 0; f < (int)sizeof(rlevel) - 1 && rlevel[f]; f++) {
a74aeac6
PR
1413 ch->rlevel[f] = rlevel[f];
1414 if (ch->rlevel[f] == 's') ch->rlevel[f] = 'S';
1415 }
1416 strncpy(ch->rlevel, rlevel, sizeof(ch->rlevel) - 1);
1417 } else {
1418 strcpy(ch->rlevel, "0123456789");
1419 if (ISPOWER(ch->action))
1420 strcpy(ch->rlevel, "S0123456789");
1421 }
1422 /*
1423 * We have the fake runlevel '#' for SYSINIT and
1424 * '*' for BOOT and BOOTWAIT.
1425 */
1426 if (ch->action == SYSINIT) strcpy(ch->rlevel, "#");
1427 if (ch->action == BOOT || ch->action == BOOTWAIT)
1428 strcpy(ch->rlevel, "*");
1429
1430 /*
1431 * Now add it to the linked list. Special for powerfail.
1432 */
1433 if (ISPOWER(ch->action)) {
1434
1435 /*
1436 * Disable by default
1437 */
1438 ch->flags |= XECUTED;
1439
1440 /*
1441 * Tricky: insert at the front of the list..
1442 */
1443 old = NULL;
1444 for(i = newFamily; i; i = i->next) {
1445 if (!ISPOWER(i->action)) break;
1446 old = i;
1447 }
1448 /*
1449 * Now add after entry "old"
1450 */
1451 if (old) {
1452 ch->next = i;
1453 old->next = ch;
1454 if (i == NULL) head = ch;
1455 } else {
1456 ch->next = newFamily;
1457 newFamily = ch;
1458 if (ch->next == NULL) head = ch;
1459 }
1460 } else {
1461 /*
1462 * Just add at end of the list
1463 */
1464 if (ch->action == KBREQUEST) ch->flags |= XECUTED;
1465 ch->next = NULL;
1466 if (head)
1467 head->next = ch;
1468 else
1469 newFamily = ch;
1470 head = ch;
1471 }
1472
1473 /*
1474 * Walk through the old list comparing id fields
1475 */
1476 for(old = family; old; old = old->next)
1477 if (strcmp(old->id, ch->id) == 0) {
1478 old->new = ch;
1479 break;
1480 }
1481 }
1482 /*
1483 * We're done.
1484 */
1485 if (fp) fclose(fp);
1486
1487 /*
1488 * Loop through the list of children, and see if they need to
1489 * be killed.
1490 */
1491
1492 INITDBG(L_VB, "Checking for children to kill");
1493 for(round = 0; round < 2; round++) {
1494 talk = 1;
1495 for(ch = family; ch; ch = ch->next) {
1496 ch->flags &= ~KILLME;
1497
1498 /*
1499 * Is this line deleted?
1500 */
1501 if (ch->new == NULL) ch->flags |= KILLME;
1502
1503 /*
1504 * If the entry has changed, kill it anyway. Note that
1505 * we do not check ch->process, only the "action" field.
1506 * This way, you can turn an entry "off" immediately, but
1507 * changes in the command line will only become effective
1508 * after the running version has exited.
1509 */
1510 if (ch->new && ch->action != ch->new->action) ch->flags |= KILLME;
1511
1512 /*
1513 * Only BOOT processes may live in all levels
1514 */
1515 if (ch->action != BOOT &&
1516 strchr(ch->rlevel, runlevel) == NULL) {
1517 /*
1518 * Ondemand procedures live always,
1519 * except in single user
1520 */
1521 if (runlevel == 'S' || !(ch->flags & DEMAND))
1522 ch->flags |= KILLME;
1523 }
1524
1525 /*
1526 * Now, if this process may live note so in the new list
1527 */
1528 if ((ch->flags & KILLME) == 0) {
1529 ch->new->flags = ch->flags;
1530 ch->new->pid = ch->pid;
1531 ch->new->exstat = ch->exstat;
1532 continue;
1533 }
1534
1535
1536 /*
1537 * Is this process still around?
1538 */
1539 if ((ch->flags & RUNNING) == 0) {
1540 ch->flags &= ~KILLME;
1541 continue;
1542 }
1543 INITDBG(L_VB, "Killing \"%s\"", ch->process);
1544 switch(round) {
1545 case 0: /* Send TERM signal */
1546 if (talk)
1547 initlog(L_CO,
82bb2fc6 1548 "Sending processes configured via /etc/inittab the TERM signal");
a74aeac6
PR
1549 kill(-(ch->pid), SIGTERM);
1550 foundOne = 1;
1551 break;
1552 case 1: /* Send KILL signal and collect status */
1553 if (talk)
1554 initlog(L_CO,
82bb2fc6 1555 "Sending processes configured via /etc/inittab the KILL signal");
a74aeac6
PR
1556 kill(-(ch->pid), SIGKILL);
1557 break;
1558 }
1559 talk = 0;
1560
1561 }
1562 /*
1563 * See if we have to wait 5 seconds
1564 */
1565 if (foundOne && round == 0) {
1566 /*
1567 * Yup, but check every second if we still have children.
1568 */
1569 for(f = 0; f < sltime; f++) {
1570 for(ch = family; ch; ch = ch->next) {
1571 if (!(ch->flags & KILLME)) continue;
1572 if ((ch->flags & RUNNING) && !(ch->flags & ZOMBIE))
1573 break;
1574 }
1575 if (ch == NULL) {
1576 /*
1577 * No running children, skip SIGKILL
1578 */
1579 round = 1;
1580 foundOne = 0; /* Skip the sleep below. */
1581 break;
1582 }
1583 do_sleep(1);
1584 }
1585 }
1586 }
1587
1588 /*
1589 * Now give all processes the chance to die and collect exit statuses.
1590 */
1591 if (foundOne) do_sleep(1);
1592 for(ch = family; ch; ch = ch->next)
1593 if (ch->flags & KILLME) {
1594 if (!(ch->flags & ZOMBIE))
1595 initlog(L_CO, "Pid %d [id %s] seems to hang", ch->pid,
1596 ch->id);
1597 else {
1598 INITDBG(L_VB, "Updating utmp for pid %d [id %s]",
1599 ch->pid, ch->id);
1600 ch->flags &= ~RUNNING;
1601 if (ch->process[0] != '+')
1602 write_utmp_wtmp("", ch->id, ch->pid, DEAD_PROCESS, NULL);
1603 }
1604 }
1605
1606 /*
1607 * Both rounds done; clean up the list.
1608 */
1609 sigemptyset(&nmask);
1610 sigaddset(&nmask, SIGCHLD);
1611 sigprocmask(SIG_BLOCK, &nmask, &omask);
1612 for(ch = family; ch; ch = old) {
1613 old = ch->next;
1614 free(ch);
1615 }
1616 family = newFamily;
1617 for(ch = family; ch; ch = ch->next) ch->new = NULL;
1618 newFamily = NULL;
1619 sigprocmask(SIG_SETMASK, &omask, NULL);
1620
1621#ifdef INITLVL
1622 /*
1623 * Dispose of INITLVL file.
1624 */
1625 if (lstat(INITLVL, &st) >= 0 && S_ISLNK(st.st_mode)) {
1626 /*
1627 * INITLVL is a symbolic link, so just truncate the file.
1628 */
1629 close(open(INITLVL, O_WRONLY|O_TRUNC));
1630 } else {
1631 /*
1632 * Delete INITLVL file.
1633 */
1634 unlink(INITLVL);
1635 }
1636#endif
1637#ifdef INITLVL2
1638 /*
1639 * Dispose of INITLVL2 file.
1640 */
1641 if (lstat(INITLVL2, &st) >= 0 && S_ISLNK(st.st_mode)) {
1642 /*
1643 * INITLVL2 is a symbolic link, so just truncate the file.
1644 */
1645 close(open(INITLVL2, O_WRONLY|O_TRUNC));
1646 } else {
1647 /*
1648 * Delete INITLVL2 file.
1649 */
1650 unlink(INITLVL2);
1651 }
1652#endif
1653}
1654
1655/*
1656 * Walk through the family list and start up children.
1657 * The entries that do not belong here at all are removed
1658 * from the list.
1659 */
5f959b29 1660static
a74aeac6
PR
1661void start_if_needed(void)
1662{
1663 CHILD *ch; /* Pointer to child */
1664 int delete; /* Delete this entry from list? */
1665
1666 INITDBG(L_VB, "Checking for children to start");
1667
1668 for(ch = family; ch; ch = ch->next) {
1669
1670#if DEBUG
1671 if (ch->rlevel[0] == 'C') {
1672 INITDBG(L_VB, "%s: flags %d", ch->process, ch->flags);
1673 }
1674#endif
1675
1676 /* Are we waiting for this process? Then quit here. */
1677 if (ch->flags & WAITING) break;
1678
1679 /* Already running? OK, don't touch it */
1680 if (ch->flags & RUNNING) continue;
1681
1682 /* See if we have to start it up */
1683 delete = 1;
1684 if (strchr(ch->rlevel, runlevel) ||
1685 ((ch->flags & DEMAND) && !strchr("#*Ss", runlevel))) {
1686 startup(ch);
1687 delete = 0;
1688 }
1689
1690 if (delete) {
1691 /* FIXME: is this OK? */
1692 ch->flags &= ~(RUNNING|WAITING);
1693 if (!ISPOWER(ch->action) && ch->action != KBREQUEST)
1694 ch->flags &= ~XECUTED;
1695 ch->pid = 0;
1696 } else
1697 /* Do we have to wait for this process? */
1698 if (ch->flags & WAITING) break;
1699 }
1700 /* Done. */
1701}
1702
1703/*
1704 * Ask the user on the console for a runlevel
1705 */
5f959b29 1706static
a74aeac6
PR
1707int ask_runlevel(void)
1708{
1709 const char prompt[] = "\nEnter runlevel: ";
1710 char buf[8];
1711 int lvl = -1;
1712 int fd;
1713
1714 console_stty();
1715 fd = console_open(O_RDWR|O_NOCTTY);
1716
1717 if (fd < 0) return('S');
1718
1719 while(!strchr("0123456789S", lvl)) {
c5ae561e
DWF
1720 safe_write(fd, prompt, sizeof(prompt) - 1);
1721 if (read(fd, buf, sizeof(buf)) <= 0)
1722 buf[0] = 0;
a74aeac6
PR
1723 if (buf[0] != 0 && (buf[1] == '\r' || buf[1] == '\n'))
1724 lvl = buf[0];
1725 if (islower(lvl)) lvl = toupper(lvl);
1726 }
1727 close(fd);
1728 return lvl;
1729}
1730
1731/*
1732 * Search the INITTAB file for the 'initdefault' field, with the default
1733 * runlevel. If this fails, ask the user to supply a runlevel.
1734 */
5f959b29 1735static
a74aeac6
PR
1736int get_init_default(void)
1737{
1738 CHILD *ch;
1739 int lvl = -1;
1740 char *p;
1741
1742 /*
1743 * Look for initdefault.
1744 */
1745 for(ch = family; ch; ch = ch->next)
1746 if (ch->action == INITDEFAULT) {
1747 p = ch->rlevel;
1748 while(*p) {
1749 if (*p > lvl) lvl = *p;
1750 p++;
1751 }
1752 break;
1753 }
1754 /*
1755 * See if level is valid
1756 */
1757 if (lvl > 0) {
1758 if (islower(lvl)) lvl = toupper(lvl);
1759 if (strchr("0123456789S", lvl) == NULL) {
1760 initlog(L_VB,
1761 "Initdefault level '%c' is invalid", lvl);
1762 lvl = 0;
1763 }
1764 }
1765 /*
1766 * Ask for runlevel on console if needed.
1767 */
1768 if (lvl <= 0) lvl = ask_runlevel();
1769
1770 /*
1771 * Log the fact that we have a runlevel now.
1772 */
1773 return lvl;
1774}
1775
1776
1777/*
1778 * We got signaled.
1779 *
1780 * Do actions for the new level. If we are compatible with
1781 * the "old" INITLVL and arg == 0, try to read the new
1782 * runlevel from that file first.
1783 */
5f959b29 1784static
a74aeac6
PR
1785int read_level(int arg)
1786{
1787 CHILD *ch; /* Walk through list */
1788 unsigned char foo = 'X'; /* Contents of INITLVL */
1789 int ok = 1;
1790#ifdef INITLVL
1791 FILE *fp;
1792 struct stat stt;
1793 int st;
1794#endif
1795
1796 if (arg) foo = arg;
1797
1798#ifdef INITLVL
1799 ok = 0;
1800
1801 if (arg == 0) {
1802 fp = NULL;
1803 if (stat(INITLVL, &stt) != 0 || stt.st_size != 0L)
1804 fp = fopen(INITLVL, "r");
1805#ifdef INITLVL2
1806 if (fp == NULL &&
1807 (stat(INITLVL2, &stt) != 0 || stt.st_size != 0L))
1808 fp = fopen(INITLVL2, "r");
1809#endif
1810 if (fp == NULL) {
1811 /* INITLVL file empty or not there - act as 'init q' */
1812 initlog(L_SY, "Re-reading inittab");
1813 return(runlevel);
1814 }
1815 ok = fscanf(fp, "%c %d", &foo, &st);
1816 fclose(fp);
1817 } else {
1818 /* We go to the new runlevel passed as an argument. */
1819 foo = arg;
1820 ok = 1;
1821 }
1822 if (ok == 2) sltime = st;
1823
1824#endif /* INITLVL */
1825
1826 if (islower(foo)) foo = toupper(foo);
1827 if (ok < 1 || ok > 2 || strchr("QS0123456789ABCU", foo) == NULL) {
1828 initlog(L_VB, "bad runlevel: %c", foo);
1829 return runlevel;
1830 }
1831
1832 /* Log this action */
1833 switch(foo) {
1834 case 'S':
1835 initlog(L_VB, "Going single user");
1836 break;
1837 case 'Q':
1838 initlog(L_SY, "Re-reading inittab");
1839 break;
1840 case 'A':
1841 case 'B':
1842 case 'C':
1843 initlog(L_SY,
1844 "Activating demand-procedures for '%c'", foo);
1845 break;
1846 case 'U':
1847 initlog(L_SY, "Trying to re-exec init");
1848 return 'U';
1849 default:
1850 initlog(L_VB, "Switching to runlevel: %c", foo);
1851 }
1852
5f959b29
DWF
1853 if (foo == 'Q') {
1854#if defined(SIGINT_ONLYONCE) && (SIGINT_ONLYONCE == 1)
1855 /* Re-enable signal from keyboard */
1856 struct sigaction sa;
1857 SETSIG(sa, SIGINT, signal_handler, 0);
1858#endif
1859 return runlevel;
1860 }
a74aeac6
PR
1861
1862 /* Check if this is a runlevel a, b or c */
1863 if (strchr("ABC", foo)) {
1864 if (runlevel == 'S') return(runlevel);
1865
1866 /* Read inittab again first! */
1867 read_inittab();
1868
1869 /* Mark those special tasks */
1870 for(ch = family; ch; ch = ch->next)
1871 if (strchr(ch->rlevel, foo) != NULL ||
1872 strchr(ch->rlevel, tolower(foo)) != NULL) {
1873 ch->flags |= DEMAND;
1874 ch->flags &= ~XECUTED;
1875 INITDBG(L_VB,
1876 "Marking (%s) as ondemand, flags %d",
1877 ch->id, ch->flags);
1878 }
1879 return runlevel;
1880 }
1881
1882 /* Store both the old and the new runlevel. */
63a2c981
DWF
1883 wrote_utmp_rlevel = 0;
1884 wrote_wtmp_rlevel = 0;
a74aeac6
PR
1885 write_utmp_wtmp("runlevel", "~~", foo + 256*runlevel, RUN_LVL, "~");
1886 thislevel = foo;
1887 prevlevel = runlevel;
1888 return foo;
1889}
1890
1891
1892/*
1893 * This procedure is called after every signal (SIGHUP, SIGALRM..)
1894 *
1895 * Only clear the 'failing' flag if the process is sleeping
1896 * longer than 5 minutes, or inittab was read again due
1897 * to user interaction.
1898 */
5f959b29 1899static
a74aeac6
PR
1900void fail_check(void)
1901{
1902 CHILD *ch; /* Pointer to child structure */
1903 time_t t; /* System time */
1904 time_t next_alarm = 0; /* When to set next alarm */
1905
1906 time(&t);
1907
1908 for(ch = family; ch; ch = ch->next) {
1909
1910 if (ch->flags & FAILING) {
1911 /* Can we free this sucker? */
1912 if (ch->tm + SLEEPTIME < t) {
1913 ch->flags &= ~FAILING;
1914 ch->count = 0;
1915 ch->tm = 0;
1916 } else {
1917 /* No, we'll look again later */
1918 if (next_alarm == 0 ||
1919 ch->tm + SLEEPTIME > next_alarm)
1920 next_alarm = ch->tm + SLEEPTIME;
1921 }
1922 }
1923 }
1924 if (next_alarm) {
1925 next_alarm -= t;
1926 if (next_alarm < 1) next_alarm = 1;
1927 alarm(next_alarm);
1928 }
1929}
1930
1931/* Set all 'Fail' timers to 0 */
5f959b29 1932static
a74aeac6
PR
1933void fail_cancel(void)
1934{
1935 CHILD *ch;
1936
1937 for(ch = family; ch; ch = ch->next) {
1938 ch->count = 0;
1939 ch->tm = 0;
1940 ch->flags &= ~FAILING;
1941 }
1942}
1943
1944/*
1945 * Start up powerfail entries.
1946 */
5f959b29 1947static
a74aeac6
PR
1948void do_power_fail(int pwrstat)
1949{
1950 CHILD *ch;
1951
1952 /*
1953 * Tell powerwait & powerfail entries to start up
1954 */
1955 for (ch = family; ch; ch = ch->next) {
1956 if (pwrstat == 'O') {
1957 /*
1958 * The power is OK again.
1959 */
1960 if (ch->action == POWEROKWAIT)
1961 ch->flags &= ~XECUTED;
1962 } else if (pwrstat == 'L') {
1963 /*
1964 * Low battery, shut down now.
1965 */
1966 if (ch->action == POWERFAILNOW)
1967 ch->flags &= ~XECUTED;
1968 } else {
1969 /*
1970 * Power is failing, shutdown imminent
1971 */
1972 if (ch->action == POWERFAIL || ch->action == POWERWAIT)
1973 ch->flags &= ~XECUTED;
1974 }
1975 }
1976}
1977
1978/*
1979 * Check for state-pipe presence
1980 */
5f959b29 1981static
a74aeac6
PR
1982int check_pipe(int fd)
1983{
1984 struct timeval t;
1985 fd_set s;
1986 char signature[8];
1987
1988 FD_ZERO(&s);
1989 FD_SET(fd, &s);
1990 t.tv_sec = t.tv_usec = 0;
1991
1992 if (select(fd+1, &s, NULL, NULL, &t) != 1)
1993 return 0;
1994 if (read(fd, signature, 8) != 8)
1995 return 0;
1996 return strncmp(Signature, signature, 8) == 0;
1997}
1998
1999/*
2000 * Make a state-pipe.
2001 */
5f959b29 2002static
a74aeac6
PR
2003int make_pipe(int fd)
2004{
2005 int fds[2];
2006
c5ae561e
DWF
2007 if (pipe(fds)) {
2008 initlog(L_VB, "pipe: %m");
2009 return -1;
2010 }
a74aeac6
PR
2011 dup2(fds[0], fd);
2012 close(fds[0]);
2013 fcntl(fds[1], F_SETFD, 1);
2014 fcntl(fd, F_SETFD, 0);
c5ae561e 2015 safe_write(fds[1], Signature, 8);
a74aeac6
PR
2016
2017 return fds[1];
2018}
2019
2020/*
2021 * Attempt to re-exec.
2022 */
5f959b29 2023static
a74aeac6
PR
2024void re_exec(void)
2025{
2026 CHILD *ch;
2027 sigset_t mask, oldset;
2028 pid_t pid;
2029 char **env;
2030 int fd;
2031
2032 if (strchr("S0123456",runlevel) == NULL)
2033 return;
2034
2035 /*
2036 * Reset the alarm, and block all signals.
2037 */
2038 alarm(0);
2039 sigfillset(&mask);
2040 sigprocmask(SIG_BLOCK, &mask, &oldset);
2041
2042 /*
2043 * construct a pipe fd --> STATE_PIPE and write a signature
2044 */
c5ae561e
DWF
2045 if ((fd = make_pipe(STATE_PIPE)) < 0) {
2046 sigprocmask(SIG_SETMASK, &oldset, NULL);
2047 initlog(L_CO, "Attempt to re-exec failed");
2048 }
a74aeac6
PR
2049
2050 /*
2051 * It's a backup day today, so I'm pissed off. Being a BOFH, however,
2052 * does have it's advantages...
2053 */
2054 fail_cancel();
2055 close(pipe_fd);
2056 pipe_fd = -1;
2057 DELSET(got_signals, SIGCHLD);
2058 DELSET(got_signals, SIGHUP);
2059 DELSET(got_signals, SIGUSR1);
2060
2061 /*
2062 * That should be cleaned.
2063 */
2064 for(ch = family; ch; ch = ch->next)
2065 if (ch->flags & ZOMBIE) {
2066 INITDBG(L_VB, "Child died, PID= %d", ch->pid);
2067 ch->flags &= ~(RUNNING|ZOMBIE|WAITING);
2068 if (ch->process[0] != '+')
2069 write_utmp_wtmp("", ch->id, ch->pid, DEAD_PROCESS, NULL);
2070 }
2071
2072 if ((pid = fork()) == 0) {
2073 /*
2074 * Child sends state information to the parent.
2075 */
2076 send_state(fd);
2077 exit(0);
2078 }
2079
2080 /*
2081 * The existing init process execs a new init binary.
2082 */
2083 env = init_buildenv(0);
2084 execle(myname, myname, "--init", NULL, env);
2085
2086 /*
2087 * We shouldn't be here, something failed.
2088 * Bitch, close the state pipe, unblock signals and return.
2089 */
c5ae561e 2090 init_freeenv(env);
a74aeac6
PR
2091 close(fd);
2092 close(STATE_PIPE);
2093 sigprocmask(SIG_SETMASK, &oldset, NULL);
a74aeac6
PR
2094 initlog(L_CO, "Attempt to re-exec failed");
2095}
2096
63a2c981
DWF
2097/*
2098 * Redo utmp/wtmp entries if required or requested
2099 * Check for written records and size of utmp
2100 */
2101static
2102void redo_utmp_wtmp(void)
2103{
2104 struct stat ustat;
2105 const int ret = stat(UTMP_FILE, &ustat);
2106
2107 if ((ret < 0) || (ustat.st_size == 0))
2108 wrote_utmp_rlevel = wrote_utmp_reboot = 0;
2109
2110 if ((wrote_wtmp_reboot == 0) || (wrote_utmp_reboot == 0))
2111 write_utmp_wtmp("reboot", "~~", 0, BOOT_TIME, "~");
2112
2113 if ((wrote_wtmp_rlevel == 0) || (wrote_wtmp_rlevel == 0))
2114 write_utmp_wtmp("runlevel", "~~", thislevel + 256 * prevlevel, RUN_LVL, "~");
2115}
a74aeac6
PR
2116
2117/*
2118 * We got a change runlevel request through the
2119 * init.fifo. Process it.
2120 */
5f959b29 2121static
a74aeac6
PR
2122void fifo_new_level(int level)
2123{
2124#if CHANGE_WAIT
2125 CHILD *ch;
2126#endif
2127 int oldlevel;
2128
2129 if (level == runlevel) return;
2130
2131#if CHANGE_WAIT
2132 /* Are we waiting for a child? */
2133 for(ch = family; ch; ch = ch->next)
2134 if (ch->flags & WAITING) break;
2135 if (ch == NULL)
2136#endif
2137 {
2138 /* We need to go into a new runlevel */
2139 oldlevel = runlevel;
2140 runlevel = read_level(level);
2141 if (runlevel == 'U') {
2142 runlevel = oldlevel;
2143 re_exec();
2144 } else {
2145 if (oldlevel != 'S' && runlevel == 'S') console_stty();
2146 if (runlevel == '6' || runlevel == '0' ||
2147 runlevel == '1') console_stty();
63a2c981 2148 if (runlevel > '1' && runlevel < '6') redo_utmp_wtmp();
a74aeac6
PR
2149 read_inittab();
2150 fail_cancel();
5f959b29 2151 setproctitle("init [%c]", (int)runlevel);
a74aeac6
PR
2152 }
2153 }
2154}
2155
2156
2157/*
2158 * Set/unset environment variables. The variables are
2159 * encoded as KEY=VAL\0KEY=VAL\0\0. With "=VAL" it means
2160 * setenv, without it means unsetenv.
2161 */
5f959b29 2162static
a74aeac6
PR
2163void initcmd_setenv(char *data, int size)
2164{
23de6d4a
DWF
2165 char *env, *p, *e;
2166 size_t sz;
2167 int i, eq;
a74aeac6
PR
2168
2169 e = data + size;
2170
2171 while (*data && data < e) {
a74aeac6 2172 for (p = data; *p && p < e; p++)
23de6d4a 2173 ;
a74aeac6
PR
2174 if (*p) break;
2175 env = data;
2176 data = ++p;
2177
a74aeac6
PR
2178 /*
2179 * We only allow INIT_* to be set.
2180 */
2181 if (strncmp(env, "INIT_", 5) != 0)
2182 continue;
2183
23de6d4a
DWF
2184 sz = strcspn(env, "=");
2185 eq = (env[sz] == '=');
2186
2187 /*initlog(L_SY, "init_setenv: %s, %d, %d", env, eq, sz);*/
2188
a74aeac6
PR
2189 /* Free existing vars. */
2190 for (i = 0; i < NR_EXTRA_ENV; i++) {
23de6d4a
DWF
2191 if (extra_env[i] == NULL)
2192 continue;
2193 if (sz != strcspn(extra_env[i], "="))
2194 continue;
2195 if (strncmp(extra_env[i], env, sz) == 0) {
a74aeac6
PR
2196 free(extra_env[i]);
2197 extra_env[i] = NULL;
2198 }
2199 }
2200
23de6d4a
DWF
2201 if (eq == 0)
2202 continue;
2203
a74aeac6 2204 /* Set new vars if needed. */
a74aeac6
PR
2205 for (i = 0; i < NR_EXTRA_ENV; i++) {
2206 if (extra_env[i] == NULL) {
2207 extra_env[i] = istrdup(env);
2208 break;
2209 }
2210 }
2211 }
2212}
2213
2214
2215/*
2216 * Read from the init FIFO. Processes like telnetd and rlogind can
2217 * ask us to create login processes on their behalf.
2218 *
2219 * FIXME: this needs to be finished. NOT that it is buggy, but we need
2220 * to add the telnetd/rlogind stuff so people can start using it.
2221 * Maybe move to using an AF_UNIX socket so we can use
2222 * the 2.2 kernel credential stuff to see who we're talking to.
2223 *
2224 */
5f959b29 2225static
a74aeac6
PR
2226void check_init_fifo(void)
2227{
2228 struct init_request request;
2229 struct timeval tv;
2230 struct stat st, st2;
2231 fd_set fds;
2232 int n;
2233 int quit = 0;
2234
2235 /*
2236 * First, try to create /dev/initctl if not present.
2237 */
2238 if (stat(INIT_FIFO, &st2) < 0 && errno == ENOENT)
2239 (void)mkfifo(INIT_FIFO, 0600);
2240
2241 /*
2242 * If /dev/initctl is open, stat the file to see if it
2243 * is still the _same_ inode.
2244 */
2245 if (pipe_fd >= 0) {
2246 fstat(pipe_fd, &st);
2247 if (stat(INIT_FIFO, &st2) < 0 ||
2248 st.st_dev != st2.st_dev ||
2249 st.st_ino != st2.st_ino) {
2250 close(pipe_fd);
2251 pipe_fd = -1;
2252 }
2253 }
2254
2255 /*
2256 * Now finally try to open /dev/initctl
2257 */
2258 if (pipe_fd < 0) {
2259 if ((pipe_fd = open(INIT_FIFO, O_RDWR|O_NONBLOCK)) >= 0) {
2260 fstat(pipe_fd, &st);
2261 if (!S_ISFIFO(st.st_mode)) {
2262 initlog(L_VB, "%s is not a fifo", INIT_FIFO);
2263 close(pipe_fd);
2264 pipe_fd = -1;
2265 }
2266 }
2267 if (pipe_fd >= 0) {
2268 /*
2269 * Don't use fd's 0, 1 or 2.
2270 */
2271 (void) dup2(pipe_fd, PIPE_FD);
2272 close(pipe_fd);
2273 pipe_fd = PIPE_FD;
2274
2275 /*
2276 * Return to caller - we'll be back later.
2277 */
2278 }
2279 }
2280
2281 /* Wait for data to appear, _if_ the pipe was opened. */
2282 if (pipe_fd >= 0) while(!quit) {
2283
2284 /* Do select, return on EINTR. */
2285 FD_ZERO(&fds);
2286 FD_SET(pipe_fd, &fds);
2287 tv.tv_sec = 5;
2288 tv.tv_usec = 0;
2289 n = select(pipe_fd + 1, &fds, NULL, NULL, &tv);
2290 if (n <= 0) {
2291 if (n == 0 || errno == EINTR) return;
2292 continue;
2293 }
2294
2295 /* Read the data, return on EINTR. */
2296 n = read(pipe_fd, &request, sizeof(request));
2297 if (n == 0) {
2298 /*
2299 * End of file. This can't happen under Linux (because
2300 * the pipe is opened O_RDWR - see select() in the
2301 * kernel) but you never know...
2302 */
2303 close(pipe_fd);
2304 pipe_fd = -1;
2305 return;
2306 }
2307 if (n <= 0) {
2308 if (errno == EINTR) return;
2309 initlog(L_VB, "error reading initrequest");
2310 continue;
2311 }
2312
2313 /*
2314 * This is a convenient point to also try to
2315 * find the console device or check if it changed.
2316 */
2317 console_init();
2318
2319 /*
2320 * Process request.
2321 */
2322 if (request.magic != INIT_MAGIC || n != sizeof(request)) {
2323 initlog(L_VB, "got bogus initrequest");
2324 continue;
2325 }
2326 switch(request.cmd) {
2327 case INIT_CMD_RUNLVL:
2328 sltime = request.sleeptime;
2329 fifo_new_level(request.runlevel);
2330 quit = 1;
2331 break;
2332 case INIT_CMD_POWERFAIL:
2333 sltime = request.sleeptime;
2334 do_power_fail('F');
2335 quit = 1;
2336 break;
2337 case INIT_CMD_POWERFAILNOW:
2338 sltime = request.sleeptime;
2339 do_power_fail('L');
2340 quit = 1;
2341 break;
2342 case INIT_CMD_POWEROK:
2343 sltime = request.sleeptime;
2344 do_power_fail('O');
2345 quit = 1;
2346 break;
2347 case INIT_CMD_SETENV:
2348 initcmd_setenv(request.i.data, sizeof(request.i.data));
2349 break;
a74aeac6
PR
2350 default:
2351 initlog(L_VB, "got unimplemented initrequest.");
2352 break;
2353 }
2354 }
2355
2356 /*
2357 * We come here if the pipe couldn't be opened.
2358 */
2359 if (pipe_fd < 0) pause();
2360
2361}
2362
2363
2364/*
2365 * This function is used in the transition
2366 * sysinit (-> single user) boot -> multi-user.
2367 */
5f959b29 2368static
a74aeac6
PR
2369void boot_transitions()
2370{
2371 CHILD *ch;
2372 static int newlevel = 0;
2373 static int warn = 1;
2374 int loglevel;
2375 int oldlevel;
2376
2377 /* Check if there is something to wait for! */
2378 for( ch = family; ch; ch = ch->next )
2379 if ((ch->flags & RUNNING) && ch->action != BOOT) break;
2380
2381 if (ch == NULL) {
2382 /* No processes left in this level, proceed to next level. */
2383 loglevel = -1;
2384 oldlevel = 'N';
2385 switch(runlevel) {
2386 case '#': /* SYSINIT -> BOOT */
2387 INITDBG(L_VB, "SYSINIT -> BOOT");
2388
2389 /* Write a boot record. */
2390 wrote_utmp_reboot = 0;
2391 wrote_wtmp_reboot = 0;
2392 write_utmp_wtmp("reboot", "~~", 0, BOOT_TIME, "~");
2393
2394 /* Get our run level */
2395 newlevel = dfl_level ? dfl_level : get_init_default();
2396 if (newlevel == 'S') {
2397 runlevel = newlevel;
2398 /* Not really 'S' but show anyway. */
2399 setproctitle("init [S]");
2400 } else
2401 runlevel = '*';
2402 break;
2403 case '*': /* BOOT -> NORMAL */
2404 INITDBG(L_VB, "BOOT -> NORMAL");
2405 if (runlevel != newlevel)
2406 loglevel = newlevel;
2407 runlevel = newlevel;
2408 did_boot = 1;
2409 warn = 1;
2410 break;
2411 case 'S': /* Ended SU mode */
2412 case 's':
2413 INITDBG(L_VB, "END SU MODE");
2414 newlevel = get_init_default();
2415 if (!did_boot && newlevel != 'S')
2416 runlevel = '*';
2417 else {
2418 if (runlevel != newlevel)
2419 loglevel = newlevel;
2420 runlevel = newlevel;
2421 oldlevel = 'S';
2422 }
2423 warn = 1;
2424 for(ch = family; ch; ch = ch->next)
2425 if (strcmp(ch->rlevel, "S") == 0)
2426 ch->flags &= ~(FAILING|WAITING|XECUTED);
2427 break;
2428 default:
2429 if (warn)
2430 initlog(L_VB,
2431 "no more processes left in this runlevel");
2432 warn = 0;
2433 loglevel = -1;
2434 if (got_signals == 0)
2435 check_init_fifo();
2436 break;
2437 }
2438 if (loglevel > 0) {
2439 initlog(L_VB, "Entering runlevel: %c", runlevel);
63a2c981
DWF
2440 wrote_utmp_rlevel = 0;
2441 wrote_wtmp_rlevel = 0;
a74aeac6
PR
2442 write_utmp_wtmp("runlevel", "~~", runlevel + 256 * oldlevel, RUN_LVL, "~");
2443 thislevel = runlevel;
2444 prevlevel = oldlevel;
5f959b29 2445 setproctitle("init [%c]", (int)runlevel);
a74aeac6
PR
2446 }
2447 }
2448}
2449
2450/*
2451 * Init got hit by a signal. See which signal it is,
2452 * and act accordingly.
2453 */
5f959b29 2454static
a74aeac6
PR
2455void process_signals()
2456{
2457 CHILD *ch;
2458 int pwrstat;
2459 int oldlevel;
2460 int fd;
2461 char c;
2462
2463 if (ISMEMBER(got_signals, SIGPWR)) {
2464 INITDBG(L_VB, "got SIGPWR");
2465 /* See _what_ kind of SIGPWR this is. */
2466 pwrstat = 0;
2467 if ((fd = open(PWRSTAT, O_RDONLY)) >= 0) {
c5ae561e
DWF
2468 if (read(fd, &c, 1) != 1)
2469 c = 0;
a74aeac6
PR
2470 pwrstat = c;
2471 close(fd);
2472 unlink(PWRSTAT);
364b4b0b
PR
2473 } else if ((fd = open(PWRSTAT_OLD, O_RDONLY)) >= 0) {
2474 /* Path changed 2010-03-20. Look for the old path for a while. */
2475 initlog(L_VB, "warning: found obsolete path %s, use %s instead",
2476 PWRSTAT_OLD, PWRSTAT);
c5ae561e
DWF
2477 if (read(fd, &c, 1) != 1)
2478 c = 0;
364b4b0b
PR
2479 pwrstat = c;
2480 close(fd);
2481 unlink(PWRSTAT_OLD);
2482 }
a74aeac6
PR
2483 do_power_fail(pwrstat);
2484 DELSET(got_signals, SIGPWR);
2485 }
2486
2487 if (ISMEMBER(got_signals, SIGINT)) {
5f959b29
DWF
2488#if defined(SIGINT_ONLYONCE) && (SIGINT_ONLYONCE == 1)
2489 /* Ignore any further signal from keyboard */
2490 struct sigaction sa;
2491 SETSIG(sa, SIGINT, SIG_IGN, SA_RESTART);
2492#endif
a74aeac6
PR
2493 INITDBG(L_VB, "got SIGINT");
2494 /* Tell ctrlaltdel entry to start up */
2495 for(ch = family; ch; ch = ch->next)
2496 if (ch->action == CTRLALTDEL)
2497 ch->flags &= ~XECUTED;
2498 DELSET(got_signals, SIGINT);
2499 }
2500
2501 if (ISMEMBER(got_signals, SIGWINCH)) {
2502 INITDBG(L_VB, "got SIGWINCH");
2503 /* Tell kbrequest entry to start up */
2504 for(ch = family; ch; ch = ch->next)
2505 if (ch->action == KBREQUEST)
2506 ch->flags &= ~XECUTED;
2507 DELSET(got_signals, SIGWINCH);
2508 }
2509
2510 if (ISMEMBER(got_signals, SIGALRM)) {
2511 INITDBG(L_VB, "got SIGALRM");
2512 /* The timer went off: check it out */
2513 DELSET(got_signals, SIGALRM);
2514 }
2515
2516 if (ISMEMBER(got_signals, SIGCHLD)) {
2517 INITDBG(L_VB, "got SIGCHLD");
2518 /* First set flag to 0 */
2519 DELSET(got_signals, SIGCHLD);
2520
2521 /* See which child this was */
2522 for(ch = family; ch; ch = ch->next)
2523 if (ch->flags & ZOMBIE) {
2524 INITDBG(L_VB, "Child died, PID= %d", ch->pid);
2525 ch->flags &= ~(RUNNING|ZOMBIE|WAITING);
2526 if (ch->process[0] != '+')
2527 write_utmp_wtmp("", ch->id, ch->pid, DEAD_PROCESS, NULL);
2528 }
2529
2530 }
2531
2532 if (ISMEMBER(got_signals, SIGHUP)) {
2533 INITDBG(L_VB, "got SIGHUP");
2534#if CHANGE_WAIT
2535 /* Are we waiting for a child? */
2536 for(ch = family; ch; ch = ch->next)
2537 if (ch->flags & WAITING) break;
2538 if (ch == NULL)
2539#endif
2540 {
2541 /* We need to go into a new runlevel */
2542 oldlevel = runlevel;
2543#ifdef INITLVL
2544 runlevel = read_level(0);
2545#endif
2546 if (runlevel == 'U') {
2547 runlevel = oldlevel;
2548 re_exec();
2549 } else {
2550 if (oldlevel != 'S' && runlevel == 'S') console_stty();
2551 if (runlevel == '6' || runlevel == '0' ||
2552 runlevel == '1') console_stty();
2553 read_inittab();
2554 fail_cancel();
5f959b29 2555 setproctitle("init [%c]", (int)runlevel);
a74aeac6
PR
2556 DELSET(got_signals, SIGHUP);
2557 }
2558 }
2559 }
2560 if (ISMEMBER(got_signals, SIGUSR1)) {
2561 /*
2562 * SIGUSR1 means close and reopen /dev/initctl
2563 */
2564 INITDBG(L_VB, "got SIGUSR1");
2565 close(pipe_fd);
2566 pipe_fd = -1;
2567 DELSET(got_signals, SIGUSR1);
2568 }
2569}
2570
2571/*
2572 * The main loop
2573 */
5f959b29
DWF
2574static
2575void init_main(void)
a74aeac6
PR
2576{
2577 CHILD *ch;
2578 struct sigaction sa;
2579 sigset_t sgt;
a74aeac6
PR
2580 int f, st;
2581
2582 if (!reload) {
2583
2584#if INITDEBUG
2585 /*
2586 * Fork so we can debug the init process.
2587 */
2588 if ((f = fork()) > 0) {
2589 static const char killmsg[] = "PRNT: init killed.\r\n";
2590 pid_t rc;
2591
2592 while((rc = wait(&st)) != f)
2593 if (rc < 0 && errno == ECHILD)
2594 break;
c5ae561e 2595 safe_write(1, killmsg, sizeof(killmsg) - 1);
a74aeac6
PR
2596 while(1) pause();
2597 }
2598#endif
2599
2600#ifdef __linux__
2601 /*
2602 * Tell the kernel to send us SIGINT when CTRL-ALT-DEL
2603 * is pressed, and that we want to handle keyboard signals.
2604 */
2605 init_reboot(BMAGIC_SOFT);
2606 if ((f = open(VT_MASTER, O_RDWR | O_NOCTTY)) >= 0) {
2607 (void) ioctl(f, KDSIGACCEPT, SIGWINCH);
2608 close(f);
2609 } else
2610 (void) ioctl(0, KDSIGACCEPT, SIGWINCH);
2611#endif
2612
2613 /*
2614 * Ignore all signals.
2615 */
2616 for(f = 1; f <= NSIG; f++)
2617 SETSIG(sa, f, SIG_IGN, SA_RESTART);
2618 }
2619
2620 SETSIG(sa, SIGALRM, signal_handler, 0);
2621 SETSIG(sa, SIGHUP, signal_handler, 0);
2622 SETSIG(sa, SIGINT, signal_handler, 0);
2623 SETSIG(sa, SIGCHLD, chld_handler, SA_RESTART);
2624 SETSIG(sa, SIGPWR, signal_handler, 0);
2625 SETSIG(sa, SIGWINCH, signal_handler, 0);
2626 SETSIG(sa, SIGUSR1, signal_handler, 0);
2627 SETSIG(sa, SIGSTOP, stop_handler, SA_RESTART);
2628 SETSIG(sa, SIGTSTP, stop_handler, SA_RESTART);
2629 SETSIG(sa, SIGCONT, cont_handler, SA_RESTART);
2630 SETSIG(sa, SIGSEGV, (void (*)(int))segv_handler, SA_RESTART);
2631
2632 console_init();
2633
2634 if (!reload) {
63a2c981 2635 int fd;
a74aeac6
PR
2636
2637 /* Close whatever files are open, and reset the console. */
2638 close(0);
2639 close(1);
2640 close(2);
2641 console_stty();
2642 setsid();
2643
2644 /*
2645 * Set default PATH variable.
2646 */
2647 setenv("PATH", PATH_DEFAULT, 1 /* Overwrite */);
2648
2649 /*
2650 * Initialize /var/run/utmp (only works if /var is on
2651 * root and mounted rw)
2652 */
63a2c981
DWF
2653 if ((fd = open(UTMP_FILE, O_WRONLY|O_CREAT|O_TRUNC, 0644)) >= 0)
2654 close(fd);
a74aeac6
PR
2655
2656 /*
2657 * Say hello to the world
2658 */
2659 initlog(L_CO, bootmsg, "booting");
2660
2661 /*
2662 * See if we have to start an emergency shell.
2663 */
2664 if (emerg_shell) {
23d97522 2665 pid_t rc;
a74aeac6
PR
2666 SETSIG(sa, SIGCHLD, SIG_DFL, SA_RESTART);
2667 if (spawn(&ch_emerg, &f) > 0) {
2668 while((rc = wait(&st)) != f)
2669 if (rc < 0 && errno == ECHILD)
2670 break;
2671 }
2672 SETSIG(sa, SIGCHLD, chld_handler, SA_RESTART);
2673 }
2674
2675 /*
2676 * Start normal boot procedure.
2677 */
2678 runlevel = '#';
2679 read_inittab();
2680
2681 } else {
2682 /*
2683 * Restart: unblock signals and let the show go on
2684 */
2685 initlog(L_CO, bootmsg, "reloading");
2686 sigfillset(&sgt);
2687 sigprocmask(SIG_UNBLOCK, &sgt, NULL);
2688
2689 /*
2690 * Set default PATH variable.
2691 */
2692 setenv("PATH", PATH_DEFAULT, 0 /* Don't overwrite */);
2693 }
2694 start_if_needed();
2695
2696 while(1) {
2697
2698 /* See if we need to make the boot transitions. */
2699 boot_transitions();
2700 INITDBG(L_VB, "init_main: waiting..");
2701
2702 /* Check if there are processes to be waited on. */
2703 for(ch = family; ch; ch = ch->next)
2704 if ((ch->flags & RUNNING) && ch->action != BOOT) break;
2705
2706#if CHANGE_WAIT
2707 /* Wait until we get hit by some signal. */
2708 while (ch != NULL && got_signals == 0) {
2709 if (ISMEMBER(got_signals, SIGHUP)) {
2710 /* See if there are processes to be waited on. */
2711 for(ch = family; ch; ch = ch->next)
2712 if (ch->flags & WAITING) break;
2713 }
2714 if (ch != NULL) check_init_fifo();
2715 }
2716#else /* CHANGE_WAIT */
2717 if (ch != NULL && got_signals == 0) check_init_fifo();
2718#endif /* CHANGE_WAIT */
2719
2720 /* Check the 'failing' flags */
2721 fail_check();
2722
2723 /* Process any signals. */
2724 process_signals();
2725
2726 /* See what we need to start up (again) */
2727 start_if_needed();
2728 }
2729 /*NOTREACHED*/
2730}
2731
2732/*
2733 * Tell the user about the syntax we expect.
2734 */
5f959b29 2735static
a74aeac6
PR
2736void usage(char *s)
2737{
2738 fprintf(stderr, "Usage: %s {-e VAR[=VAL] | [-t SECONDS] {0|1|2|3|4|5|6|S|s|Q|q|A|a|B|b|C|c|U|u}}\n", s);
2739 exit(1);
2740}
2741
5f959b29 2742static
a74aeac6
PR
2743int telinit(char *progname, int argc, char **argv)
2744{
2745#ifdef TELINIT_USES_INITLVL
2746 FILE *fp;
2747#endif
2748 struct init_request request;
2749 struct sigaction sa;
2750 int f, fd, l;
2751 char *env = NULL;
2752
2753 memset(&request, 0, sizeof(request));
2754 request.magic = INIT_MAGIC;
2755
2756 while ((f = getopt(argc, argv, "t:e:")) != EOF) switch(f) {
2757 case 't':
2758 sltime = atoi(optarg);
2759 break;
2760 case 'e':
2761 if (env == NULL)
2762 env = request.i.data;
2763 l = strlen(optarg);
2764 if (env + l + 2 > request.i.data + sizeof(request.i.data)) {
2765 fprintf(stderr, "%s: -e option data "
2766 "too large\n", progname);
2767 exit(1);
2768 }
2769 memcpy(env, optarg, l);
2770 env += l;
2771 *env++ = 0;
2772 break;
2773 default:
2774 usage(progname);
2775 break;
2776 }
2777
2778 if (env) *env++ = 0;
2779
2780 if (env) {
2781 if (argc != optind)
2782 usage(progname);
2783 request.cmd = INIT_CMD_SETENV;
2784 } else {
2785 if (argc - optind != 1 || strlen(argv[optind]) != 1)
2786 usage(progname);
2787 if (!strchr("0123456789SsQqAaBbCcUu", argv[optind][0]))
2788 usage(progname);
2789 request.cmd = INIT_CMD_RUNLVL;
2790 request.runlevel = env ? 0 : argv[optind][0];
2791 request.sleeptime = sltime;
2792 }
2793
5f959b29
DWF
2794 /* Change to the root directory. */
2795 chdir("/");
2796
a74aeac6
PR
2797 /* Open the fifo and write a command. */
2798 /* Make sure we don't hang on opening /dev/initctl */
2799 SETSIG(sa, SIGALRM, signal_handler, 0);
2800 alarm(3);
5f959b29
DWF
2801 if ((fd = open(INIT_FIFO, O_WRONLY)) >= 0) {
2802 ssize_t p = 0;
2803 size_t s = sizeof(request);
2804 void *ptr = &request;
2805
2806 while (s > 0) {
2807 p = write(fd, ptr, s);
2808 if (p < 0) {
2809 if (errno == EINTR || errno == EAGAIN)
2810 continue;
2811 break;
2812 }
2813 ptr += p;
2814 s -= p;
2815 }
a74aeac6
PR
2816 close(fd);
2817 alarm(0);
2818 return 0;
2819 }
2820
2821#ifdef TELINIT_USES_INITLVL
2822 if (request.cmd == INIT_CMD_RUNLVL) {
2823 /* Fallthrough to the old method. */
2824
2825 /* Now write the new runlevel. */
2826 if ((fp = fopen(INITLVL, "w")) == NULL) {
2827 fprintf(stderr, "%s: cannot create %s\n",
2828 progname, INITLVL);
2829 exit(1);
2830 }
2831 fprintf(fp, "%s %d", argv[optind], sltime);
2832 fclose(fp);
2833
2834 /* And tell init about the pending runlevel change. */
2835 if (kill(INITPID, SIGHUP) < 0) perror(progname);
2836
2837 return 0;
2838 }
2839#endif
2840
2841 fprintf(stderr, "%s: ", progname);
2842 if (ISMEMBER(got_signals, SIGALRM)) {
2843 fprintf(stderr, "timeout opening/writing control channel %s\n",
2844 INIT_FIFO);
2845 } else {
2846 perror(INIT_FIFO);
2847 }
2848 return 1;
2849}
2850
2851/*
2852 * Main entry for init and telinit.
2853 */
2854int main(int argc, char **argv)
2855{
2856 char *p;
2857 int f;
2858 int isinit;
e481cba6 2859#ifdef WITH_SELINUX
a74aeac6 2860 int enforce = 0;
e481cba6 2861#endif
a74aeac6
PR
2862
2863 /* Get my own name */
2864 if ((p = strrchr(argv[0], '/')) != NULL)
2865 p++;
2866 else
2867 p = argv[0];
5f959b29
DWF
2868
2869 /* Common umask */
c5ae561e 2870 umask(umask(077) | 022);
a74aeac6
PR
2871
2872 /* Quick check */
2873 if (geteuid() != 0) {
2874 fprintf(stderr, "%s: must be superuser.\n", p);
2875 exit(1);
2876 }
2877
2878 /*
2879 * Is this telinit or init ?
2880 */
2881 isinit = (getpid() == 1);
2882 for (f = 1; f < argc; f++) {
54cb4b75 2883 if (!strcmp(argv[f], "-i") || !strcmp(argv[f], "--init")) {
a74aeac6
PR
2884 isinit = 1;
2885 break;
54cb4b75 2886 }
a74aeac6
PR
2887 }
2888 if (!isinit) exit(telinit(p, argc, argv));
2889
2890 /*
2891 * Check for re-exec
2892 */
2893 if (check_pipe(STATE_PIPE)) {
2894
2895 receive_state(STATE_PIPE);
2896
2897 myname = istrdup(argv[0]);
2898 argv0 = argv[0];
2899 maxproclen = 0;
2900 for (f = 0; f < argc; f++)
2901 maxproclen += strlen(argv[f]) + 1;
2902 reload = 1;
5f959b29 2903 setproctitle("init [%c]", (int)runlevel);
a74aeac6
PR
2904
2905 init_main();
2906 }
2907
2908 /* Check command line arguments */
2909 maxproclen = strlen(argv[0]) + 1;
2910 for(f = 1; f < argc; f++) {
2911 if (!strcmp(argv[f], "single") || !strcmp(argv[f], "-s"))
2912 dfl_level = 'S';
2913 else if (!strcmp(argv[f], "-a") || !strcmp(argv[f], "auto"))
2914 putenv("AUTOBOOT=YES");
2915 else if (!strcmp(argv[f], "-b") || !strcmp(argv[f],"emergency"))
2916 emerg_shell = 1;
2917 else if (!strcmp(argv[f], "-z")) {
2918 /* Ignore -z xxx */
2919 if (argv[f + 1]) f++;
2920 } else if (strchr("0123456789sS", argv[f][0])
2921 && strlen(argv[f]) == 1)
2922 dfl_level = argv[f][0];
2923 /* "init u" in the very beginning makes no sense */
2924 if (dfl_level == 's') dfl_level = 'S';
2925 maxproclen += strlen(argv[f]) + 1;
2926 }
2927
2928#ifdef WITH_SELINUX
9af2d863 2929 if (getenv("SELINUX_INIT") == NULL) {
be62ca92 2930 if (is_selinux_enabled() != 1) {
9af2d863 2931 if (selinux_init_load_policy(&enforce) == 0) {
be62ca92 2932 putenv("SELINUX_INIT=YES");
9af2d863
DWF
2933 execv(myname, argv);
2934 } else {
2935 if (enforce > 0) {
2936 /* SELinux in enforcing mode but load_policy failed */
2937 /* At this point, we probably can't open /dev/console, so log() won't work */
2938 fprintf(stderr,"Unable to load SELinux Policy. Machine is in enforcing mode. Halting now.\n");
2939 exit(1);
2940 }
a74aeac6
PR
2941 }
2942 }
2943 }
2944#endif
2945 /* Start booting. */
2946 argv0 = argv[0];
2947 argv[1] = NULL;
2948 setproctitle("init boot");
5f959b29 2949 init_main();
a74aeac6
PR
2950
2951 /*NOTREACHED*/
2952 return 0;
2953}