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