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