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