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