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