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