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