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