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