1/*-
2 * Copyright (c) 1991, 1993
3 *	The Regents of the University of California.  All rights reserved.
4 *
5 * This code is derived from software contributed to Berkeley by
6 * Donn Seeley at Berkeley Software Design, Inc.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 * 1. Redistributions of source code must retain the above copyright
12 *    notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 *    notice, this list of conditions and the following disclaimer in the
15 *    documentation and/or other materials provided with the distribution.
16 * 4. Neither the name of the University nor the names of its contributors
17 *    may be used to endorse or promote products derived from this software
18 *    without specific prior written permission.
19 *
20 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
21 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23 * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
24 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
26 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
27 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
28 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
29 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
30 * SUCH DAMAGE.
31 */
32
33#ifndef lint
34static const char copyright[] =
35"@(#) Copyright (c) 1991, 1993\n\
36	The Regents of the University of California.  All rights reserved.\n";
37#endif /* not lint */
38
39#ifndef lint
40#if 0
41static char sccsid[] = "@(#)init.c	8.1 (Berkeley) 7/15/93";
42#endif
43static const char rcsid[] =
44  "$FreeBSD$";
45#endif /* not lint */
46
47#include <sys/param.h>
48#include <sys/ioctl.h>
49#include <sys/mount.h>
50#include <sys/sysctl.h>
51#include <sys/wait.h>
52#include <sys/stat.h>
53#include <sys/uio.h>
54
55#include <db.h>
56#include <errno.h>
57#include <fcntl.h>
58#include <kenv.h>
59#include <libutil.h>
60#include <paths.h>
61#include <signal.h>
62#include <stdio.h>
63#include <stdlib.h>
64#include <string.h>
65#include <syslog.h>
66#include <time.h>
67#include <ttyent.h>
68#include <unistd.h>
69#include <utmpx.h>
70#include <sys/reboot.h>
71#include <err.h>
72
73#include <stdarg.h>
74
75#ifdef SECURE
76#include <pwd.h>
77#endif
78
79#ifdef LOGIN_CAP
80#include <login_cap.h>
81#endif
82
83#include "pathnames.h"
84
85/*
86 * Sleep times; used to prevent thrashing.
87 */
88#define	GETTY_SPACING		 5	/* N secs minimum getty spacing */
89#define	GETTY_SLEEP		30	/* sleep N secs after spacing problem */
90#define	GETTY_NSPACE		 3	/* max. spacing count to bring reaction */
91#define	WINDOW_WAIT		 3	/* wait N secs after starting window */
92#define	STALL_TIMEOUT		30	/* wait N secs after warning */
93#define	DEATH_WATCH		10	/* wait N secs for procs to die */
94#define	DEATH_SCRIPT		120	/* wait for 2min for /etc/rc.shutdown */
95#define	RESOURCE_RC		"daemon"
96#define	RESOURCE_WINDOW		"default"
97#define	RESOURCE_GETTY		"default"
98
99static void handle(sig_t, ...);
100static void delset(sigset_t *, ...);
101
102static void stall(const char *, ...) __printflike(1, 2);
103static void warning(const char *, ...) __printflike(1, 2);
104static void emergency(const char *, ...) __printflike(1, 2);
105static void disaster(int);
106static void badsys(int);
107static int  runshutdown(void);
108static char *strk(char *);
109
110/*
111 * We really need a recursive typedef...
112 * The following at least guarantees that the return type of (*state_t)()
113 * is sufficiently wide to hold a function pointer.
114 */
115typedef long (*state_func_t)(void);
116typedef state_func_t (*state_t)(void);
117
118static state_func_t single_user(void);
119static state_func_t runcom(void);
120static state_func_t read_ttys(void);
121static state_func_t multi_user(void);
122static state_func_t clean_ttys(void);
123static state_func_t catatonia(void);
124static state_func_t death(void);
125static state_func_t death_single(void);
126
127static state_func_t run_script(const char *);
128
129enum { AUTOBOOT, FASTBOOT } runcom_mode = AUTOBOOT;
130#define FALSE	0
131#define TRUE	1
132
133int Reboot = FALSE;
134int howto = RB_AUTOBOOT;
135
136int devfs;
137
138static void transition(state_t);
139static state_t requested_transition;
140static state_t current_state = death_single;
141
142static void open_console(void);
143static const char *get_shell(void);
144static void write_stderr(const char *message);
145
146typedef struct init_session {
147	int	se_index;		/* index of entry in ttys file */
148	pid_t	se_process;		/* controlling process */
149	time_t	se_started;		/* used to avoid thrashing */
150	int	se_flags;		/* status of session */
151#define	SE_SHUTDOWN	0x1		/* session won't be restarted */
152#define	SE_PRESENT	0x2		/* session is in /etc/ttys */
153	int	se_nspace;		/* spacing count */
154	char	*se_device;		/* filename of port */
155	char	*se_getty;		/* what to run on that port */
156	char	*se_getty_argv_space;   /* pre-parsed argument array space */
157	char	**se_getty_argv;	/* pre-parsed argument array */
158	char	*se_window;		/* window system (started only once) */
159	char	*se_window_argv_space;  /* pre-parsed argument array space */
160	char	**se_window_argv;	/* pre-parsed argument array */
161	char	*se_type;		/* default terminal type */
162	struct	init_session *se_prev;
163	struct	init_session *se_next;
164} session_t;
165
166static void free_session(session_t *);
167static session_t *new_session(session_t *, int, struct ttyent *);
168static session_t *sessions;
169
170static char **construct_argv(char *);
171static void start_window_system(session_t *);
172static void collect_child(pid_t);
173static pid_t start_getty(session_t *);
174static void transition_handler(int);
175static void alrm_handler(int);
176static void setsecuritylevel(int);
177static int getsecuritylevel(void);
178static int setupargv(session_t *, struct ttyent *);
179#ifdef LOGIN_CAP
180static void setprocresources(const char *);
181#endif
182static int clang;
183
184static void clear_session_logs(session_t *);
185
186static int start_session_db(void);
187static void add_session(session_t *);
188static void del_session(session_t *);
189static session_t *find_session(pid_t);
190static DB *session_db;
191
192/*
193 * The mother of all processes.
194 */
195int
196main(int argc, char *argv[])
197{
198	state_t initial_transition = runcom;
199	char kenv_value[PATH_MAX];
200	int c;
201	struct sigaction sa;
202	sigset_t mask;
203
204	/* Dispose of random users. */
205	if (getuid() != 0)
206		errx(1, "%s", strerror(EPERM));
207
208	/* System V users like to reexec init. */
209	if (getpid() != 1) {
210#ifdef COMPAT_SYSV_INIT
211		/* So give them what they want */
212		if (argc > 1) {
213			if (strlen(argv[1]) == 1) {
214				char runlevel = *argv[1];
215				int sig;
216
217				switch (runlevel) {
218				case '0': /* halt + poweroff */
219					sig = SIGUSR2;
220					break;
221				case '1': /* single-user */
222					sig = SIGTERM;
223					break;
224				case '6': /* reboot */
225					sig = SIGINT;
226					break;
227				case 'c': /* block further logins */
228					sig = SIGTSTP;
229					break;
230				case 'q': /* rescan /etc/ttys */
231					sig = SIGHUP;
232					break;
233				default:
234					goto invalid;
235				}
236				kill(1, sig);
237				_exit(0);
238			} else
239invalid:
240				errx(1, "invalid run-level ``%s''", argv[1]);
241		} else
242#endif
243			errx(1, "already running");
244	}
245	/*
246	 * Note that this does NOT open a file...
247	 * Does 'init' deserve its own facility number?
248	 */
249	openlog("init", LOG_CONS|LOG_ODELAY, LOG_AUTH);
250
251	/*
252	 * Create an initial session.
253	 */
254	if (setsid() < 0)
255		warning("initial setsid() failed: %m");
256
257	/*
258	 * Establish an initial user so that programs running
259	 * single user do not freak out and die (like passwd).
260	 */
261	if (setlogin("root") < 0)
262		warning("setlogin() failed: %m");
263
264	/*
265	 * This code assumes that we always get arguments through flags,
266	 * never through bits set in some random machine register.
267	 */
268	while ((c = getopt(argc, argv, "dsf")) != -1)
269		switch (c) {
270		case 'd':
271			devfs = 1;
272			break;
273		case 's':
274			initial_transition = single_user;
275			break;
276		case 'f':
277			runcom_mode = FASTBOOT;
278			break;
279		default:
280			warning("unrecognized flag '-%c'", c);
281			break;
282		}
283
284	if (optind != argc)
285		warning("ignoring excess arguments");
286
287	/*
288	 * We catch or block signals rather than ignore them,
289	 * so that they get reset on exec.
290	 */
291	handle(badsys, SIGSYS, 0);
292	handle(disaster, SIGABRT, SIGFPE, SIGILL, SIGSEGV, SIGBUS, SIGXCPU,
293	    SIGXFSZ, 0);
294	handle(transition_handler, SIGHUP, SIGINT, SIGTERM, SIGTSTP, SIGUSR1,
295	    SIGUSR2, 0);
296	handle(alrm_handler, SIGALRM, 0);
297	sigfillset(&mask);
298	delset(&mask, SIGABRT, SIGFPE, SIGILL, SIGSEGV, SIGBUS, SIGSYS,
299	    SIGXCPU, SIGXFSZ, SIGHUP, SIGINT, SIGTERM, SIGTSTP, SIGALRM,
300	    SIGUSR1, SIGUSR2, 0);
301	sigprocmask(SIG_SETMASK, &mask, (sigset_t *) 0);
302	sigemptyset(&sa.sa_mask);
303	sa.sa_flags = 0;
304	sa.sa_handler = SIG_IGN;
305	sigaction(SIGTTIN, &sa, (struct sigaction *)0);
306	sigaction(SIGTTOU, &sa, (struct sigaction *)0);
307
308	/*
309	 * Paranoia.
310	 */
311	close(0);
312	close(1);
313	close(2);
314
315	if (kenv(KENV_GET, "init_script", kenv_value, sizeof(kenv_value)) > 0) {
316		state_func_t next_transition;
317
318		if ((next_transition = run_script(kenv_value)) != 0)
319			initial_transition = (state_t) next_transition;
320	}
321
322	if (kenv(KENV_GET, "init_chroot", kenv_value, sizeof(kenv_value)) > 0) {
323		if (chdir(kenv_value) != 0 || chroot(".") != 0)
324			warning("Can't chroot to %s: %m", kenv_value);
325	}
326
327	/*
328	 * Additional check if devfs needs to be mounted:
329	 * If "/" and "/dev" have the same device number,
330	 * then it hasn't been mounted yet.
331	 */
332	if (!devfs) {
333		struct stat stst;
334		dev_t root_devno;
335
336		stat("/", &stst);
337		root_devno = stst.st_dev;
338		if (stat("/dev", &stst) != 0)
339			warning("Can't stat /dev: %m");
340		else if (stst.st_dev == root_devno)
341			devfs++;
342	}
343
344	if (devfs) {
345		struct iovec iov[4];
346		char *s;
347		int i;
348
349		char _fstype[]	= "fstype";
350		char _devfs[]	= "devfs";
351		char _fspath[]	= "fspath";
352		char _path_dev[]= _PATH_DEV;
353
354		iov[0].iov_base = _fstype;
355		iov[0].iov_len = sizeof(_fstype);
356		iov[1].iov_base = _devfs;
357		iov[1].iov_len = sizeof(_devfs);
358		iov[2].iov_base = _fspath;
359		iov[2].iov_len = sizeof(_fspath);
360		/*
361		 * Try to avoid the trailing slash in _PATH_DEV.
362		 * Be *very* defensive.
363		 */
364		s = strdup(_PATH_DEV);
365		if (s != NULL) {
366			i = strlen(s);
367			if (i > 0 && s[i - 1] == '/')
368				s[i - 1] = '\0';
369			iov[3].iov_base = s;
370			iov[3].iov_len = strlen(s) + 1;
371		} else {
372			iov[3].iov_base = _path_dev;
373			iov[3].iov_len = sizeof(_path_dev);
374		}
375		nmount(iov, 4, 0);
376		if (s != NULL)
377			free(s);
378	}
379
380	/*
381	 * Start the state machine.
382	 */
383	transition(initial_transition);
384
385	/*
386	 * Should never reach here.
387	 */
388	return 1;
389}
390
391/*
392 * Associate a function with a signal handler.
393 */
394static void
395handle(sig_t handler, ...)
396{
397	int sig;
398	struct sigaction sa;
399	sigset_t mask_everything;
400	va_list ap;
401	va_start(ap, handler);
402
403	sa.sa_handler = handler;
404	sigfillset(&mask_everything);
405
406	while ((sig = va_arg(ap, int)) != 0) {
407		sa.sa_mask = mask_everything;
408		/* XXX SA_RESTART? */
409		sa.sa_flags = sig == SIGCHLD ? SA_NOCLDSTOP : 0;
410		sigaction(sig, &sa, (struct sigaction *) 0);
411	}
412	va_end(ap);
413}
414
415/*
416 * Delete a set of signals from a mask.
417 */
418static void
419delset(sigset_t *maskp, ...)
420{
421	int sig;
422	va_list ap;
423	va_start(ap, maskp);
424
425	while ((sig = va_arg(ap, int)) != 0)
426		sigdelset(maskp, sig);
427	va_end(ap);
428}
429
430/*
431 * Log a message and sleep for a while (to give someone an opportunity
432 * to read it and to save log or hardcopy output if the problem is chronic).
433 * NB: should send a message to the session logger to avoid blocking.
434 */
435static void
436stall(const char *message, ...)
437{
438	va_list ap;
439	va_start(ap, message);
440
441	vsyslog(LOG_ALERT, message, ap);
442	va_end(ap);
443	sleep(STALL_TIMEOUT);
444}
445
446/*
447 * Like stall(), but doesn't sleep.
448 * If cpp had variadic macros, the two functions could be #defines for another.
449 * NB: should send a message to the session logger to avoid blocking.
450 */
451static void
452warning(const char *message, ...)
453{
454	va_list ap;
455	va_start(ap, message);
456
457	vsyslog(LOG_ALERT, message, ap);
458	va_end(ap);
459}
460
461/*
462 * Log an emergency message.
463 * NB: should send a message to the session logger to avoid blocking.
464 */
465static void
466emergency(const char *message, ...)
467{
468	va_list ap;
469	va_start(ap, message);
470
471	vsyslog(LOG_EMERG, message, ap);
472	va_end(ap);
473}
474
475/*
476 * Catch a SIGSYS signal.
477 *
478 * These may arise if a system does not support sysctl.
479 * We tolerate up to 25 of these, then throw in the towel.
480 */
481static void
482badsys(int sig)
483{
484	static int badcount = 0;
485
486	if (badcount++ < 25)
487		return;
488	disaster(sig);
489}
490
491/*
492 * Catch an unexpected signal.
493 */
494static void
495disaster(int sig)
496{
497
498	emergency("fatal signal: %s",
499	    (unsigned)sig < NSIG ? sys_siglist[sig] : "unknown signal");
500
501	sleep(STALL_TIMEOUT);
502	_exit(sig);		/* reboot */
503}
504
505/*
506 * Get the security level of the kernel.
507 */
508static int
509getsecuritylevel(void)
510{
511#ifdef KERN_SECURELVL
512	int name[2], curlevel;
513	size_t len;
514
515	name[0] = CTL_KERN;
516	name[1] = KERN_SECURELVL;
517	len = sizeof curlevel;
518	if (sysctl(name, 2, &curlevel, &len, NULL, 0) == -1) {
519		emergency("cannot get kernel security level: %s",
520		    strerror(errno));
521		return (-1);
522	}
523	return (curlevel);
524#else
525	return (-1);
526#endif
527}
528
529/*
530 * Set the security level of the kernel.
531 */
532static void
533setsecuritylevel(int newlevel)
534{
535#ifdef KERN_SECURELVL
536	int name[2], curlevel;
537
538	curlevel = getsecuritylevel();
539	if (newlevel == curlevel)
540		return;
541	name[0] = CTL_KERN;
542	name[1] = KERN_SECURELVL;
543	if (sysctl(name, 2, NULL, NULL, &newlevel, sizeof newlevel) == -1) {
544		emergency(
545		    "cannot change kernel security level from %d to %d: %s",
546		    curlevel, newlevel, strerror(errno));
547		return;
548	}
549#ifdef SECURE
550	warning("kernel security level changed from %d to %d",
551	    curlevel, newlevel);
552#endif
553#endif
554}
555
556/*
557 * Change states in the finite state machine.
558 * The initial state is passed as an argument.
559 */
560static void
561transition(state_t s)
562{
563
564	current_state = s;
565	for (;;)
566		current_state = (state_t) (*current_state)();
567}
568
569/*
570 * Close out the accounting files for a login session.
571 * NB: should send a message to the session logger to avoid blocking.
572 */
573static void
574clear_session_logs(session_t *sp __unused)
575{
576
577	/*
578	 * XXX: Use getutxline() and call pututxline() for each entry.
579	 * Is this safe to do this here?  Is it really required anyway?
580	 */
581}
582
583/*
584 * Start a session and allocate a controlling terminal.
585 * Only called by children of init after forking.
586 */
587static void
588open_console(void)
589{
590	int fd;
591
592	/*
593	 * Try to open /dev/console.  Open the device with O_NONBLOCK to
594	 * prevent potential blocking on a carrier.
595	 */
596	revoke(_PATH_CONSOLE);
597	if ((fd = open(_PATH_CONSOLE, O_RDWR | O_NONBLOCK)) != -1) {
598		(void)fcntl(fd, F_SETFL, fcntl(fd, F_GETFL) & ~O_NONBLOCK);
599		if (login_tty(fd) == 0)
600			return;
601		close(fd);
602	}
603
604	/* No luck.  Log output to file if possible. */
605	if ((fd = open(_PATH_DEVNULL, O_RDWR)) == -1) {
606		stall("cannot open null device.");
607		_exit(1);
608	}
609	if (fd != STDIN_FILENO) {
610		dup2(fd, STDIN_FILENO);
611		close(fd);
612	}
613	fd = open(_PATH_INITLOG, O_WRONLY | O_APPEND | O_CREAT, 0644);
614	if (fd == -1)
615		dup2(STDIN_FILENO, STDOUT_FILENO);
616	else if (fd != STDOUT_FILENO) {
617		dup2(fd, STDOUT_FILENO);
618		close(fd);
619	}
620	dup2(STDOUT_FILENO, STDERR_FILENO);
621}
622
623static const char *
624get_shell(void)
625{
626	static char kenv_value[PATH_MAX];
627
628	if (kenv(KENV_GET, "init_shell", kenv_value, sizeof(kenv_value)) > 0)
629		return kenv_value;
630	else
631		return _PATH_BSHELL;
632}
633
634static void
635write_stderr(const char *message)
636{
637
638	write(STDERR_FILENO, message, strlen(message));
639}
640
641/*
642 * Bring the system up single user.
643 */
644static state_func_t
645single_user(void)
646{
647	pid_t pid, wpid;
648	int status;
649	sigset_t mask;
650	const char *shell;
651	char *argv[2];
652#ifdef SECURE
653	struct ttyent *typ;
654	struct passwd *pp;
655	static const char banner[] =
656		"Enter root password, or ^D to go multi-user\n";
657	char *clear, *password;
658#endif
659#ifdef DEBUGSHELL
660	char altshell[128];
661#endif
662
663	if (Reboot) {
664		/* Instead of going single user, let's reboot the machine */
665		sync();
666		alarm(2);
667		pause();
668		reboot(howto);
669		_exit(0);
670	}
671
672	shell = get_shell();
673
674	if ((pid = fork()) == 0) {
675		/*
676		 * Start the single user session.
677		 */
678		open_console();
679
680#ifdef SECURE
681		/*
682		 * Check the root password.
683		 * We don't care if the console is 'on' by default;
684		 * it's the only tty that can be 'off' and 'secure'.
685		 */
686		typ = getttynam("console");
687		pp = getpwnam("root");
688		if (typ && (typ->ty_status & TTY_SECURE) == 0 &&
689		    pp && *pp->pw_passwd) {
690			write_stderr(banner);
691			for (;;) {
692				clear = getpass("Password:");
693				if (clear == 0 || *clear == '\0')
694					_exit(0);
695				password = crypt(clear, pp->pw_passwd);
696				bzero(clear, _PASSWORD_LEN);
697				if (strcmp(password, pp->pw_passwd) == 0)
698					break;
699				warning("single-user login failed\n");
700			}
701		}
702		endttyent();
703		endpwent();
704#endif /* SECURE */
705
706#ifdef DEBUGSHELL
707		{
708			char *cp = altshell;
709			int num;
710
711#define	SHREQUEST "Enter full pathname of shell or RETURN for "
712			write_stderr(SHREQUEST);
713			write_stderr(shell);
714			write_stderr(": ");
715			while ((num = read(STDIN_FILENO, cp, 1)) != -1 &&
716			    num != 0 && *cp != '\n' && cp < &altshell[127])
717				cp++;
718			*cp = '\0';
719			if (altshell[0] != '\0')
720				shell = altshell;
721		}
722#endif /* DEBUGSHELL */
723
724		/*
725		 * Unblock signals.
726		 * We catch all the interesting ones,
727		 * and those are reset to SIG_DFL on exec.
728		 */
729		sigemptyset(&mask);
730		sigprocmask(SIG_SETMASK, &mask, (sigset_t *) 0);
731
732		/*
733		 * Fire off a shell.
734		 * If the default one doesn't work, try the Bourne shell.
735		 */
736
737		char name[] = "-sh";
738
739		argv[0] = name;
740		argv[1] = 0;
741		execv(shell, argv);
742		emergency("can't exec %s for single user: %m", shell);
743		execv(_PATH_BSHELL, argv);
744		emergency("can't exec %s for single user: %m", _PATH_BSHELL);
745		sleep(STALL_TIMEOUT);
746		_exit(1);
747	}
748
749	if (pid == -1) {
750		/*
751		 * We are seriously hosed.  Do our best.
752		 */
753		emergency("can't fork single-user shell, trying again");
754		while (waitpid(-1, (int *) 0, WNOHANG) > 0)
755			continue;
756		return (state_func_t) single_user;
757	}
758
759	requested_transition = 0;
760	do {
761		if ((wpid = waitpid(-1, &status, WUNTRACED)) != -1)
762			collect_child(wpid);
763		if (wpid == -1) {
764			if (errno == EINTR)
765				continue;
766			warning("wait for single-user shell failed: %m; restarting");
767			return (state_func_t) single_user;
768		}
769		if (wpid == pid && WIFSTOPPED(status)) {
770			warning("init: shell stopped, restarting\n");
771			kill(pid, SIGCONT);
772			wpid = -1;
773		}
774	} while (wpid != pid && !requested_transition);
775
776	if (requested_transition)
777		return (state_func_t) requested_transition;
778
779	if (!WIFEXITED(status)) {
780		if (WTERMSIG(status) == SIGKILL) {
781			/*
782			 *  reboot(8) killed shell?
783			 */
784			warning("single user shell terminated.");
785			sleep(STALL_TIMEOUT);
786			_exit(0);
787		} else {
788			warning("single user shell terminated, restarting");
789			return (state_func_t) single_user;
790		}
791	}
792
793	runcom_mode = FASTBOOT;
794	return (state_func_t) runcom;
795}
796
797/*
798 * Run the system startup script.
799 */
800static state_func_t
801runcom(void)
802{
803	struct utmpx utx;
804	state_func_t next_transition;
805
806	if ((next_transition = run_script(_PATH_RUNCOM)) != 0)
807		return next_transition;
808
809	runcom_mode = AUTOBOOT;		/* the default */
810	/* NB: should send a message to the session logger to avoid blocking. */
811	utx.ut_type = BOOT_TIME;
812	gettimeofday(&utx.ut_tv, NULL);
813	pututxline(&utx);
814	return (state_func_t) read_ttys;
815}
816
817/*
818 * Run a shell script.
819 * Returns 0 on success, otherwise the next transition to enter:
820 *  - single_user if fork/execv/waitpid failed, or if the script
821 *    terminated with a signal or exit code != 0.
822 *  - death_single if a SIGTERM was delivered to init(8).
823 */
824static state_func_t
825run_script(const char *script)
826{
827	pid_t pid, wpid;
828	int status;
829	char *argv[4];
830	const char *shell;
831	struct sigaction sa;
832
833	shell = get_shell();
834
835	if ((pid = fork()) == 0) {
836		sigemptyset(&sa.sa_mask);
837		sa.sa_flags = 0;
838		sa.sa_handler = SIG_IGN;
839		sigaction(SIGTSTP, &sa, (struct sigaction *)0);
840		sigaction(SIGHUP, &sa, (struct sigaction *)0);
841
842		open_console();
843
844		char _sh[]		= "sh";
845		char _autoboot[]	= "autoboot";
846
847		argv[0] = _sh;
848		argv[1] = __DECONST(char *, script);
849		argv[2] = runcom_mode == AUTOBOOT ? _autoboot : 0;
850		argv[3] = 0;
851
852		sigprocmask(SIG_SETMASK, &sa.sa_mask, (sigset_t *) 0);
853
854#ifdef LOGIN_CAP
855		setprocresources(RESOURCE_RC);
856#endif
857		execv(shell, argv);
858		stall("can't exec %s for %s: %m", shell, script);
859		_exit(1);	/* force single user mode */
860	}
861
862	if (pid == -1) {
863		emergency("can't fork for %s on %s: %m", shell, script);
864		while (waitpid(-1, (int *) 0, WNOHANG) > 0)
865			continue;
866		sleep(STALL_TIMEOUT);
867		return (state_func_t) single_user;
868	}
869
870	/*
871	 * Copied from single_user().  This is a bit paranoid.
872	 */
873	requested_transition = 0;
874	do {
875		if ((wpid = waitpid(-1, &status, WUNTRACED)) != -1)
876			collect_child(wpid);
877		if (wpid == -1) {
878			if (requested_transition == death_single)
879				return (state_func_t) death_single;
880			if (errno == EINTR)
881				continue;
882			warning("wait for %s on %s failed: %m; going to "
883			    "single user mode", shell, script);
884			return (state_func_t) single_user;
885		}
886		if (wpid == pid && WIFSTOPPED(status)) {
887			warning("init: %s on %s stopped, restarting\n",
888			    shell, script);
889			kill(pid, SIGCONT);
890			wpid = -1;
891		}
892	} while (wpid != pid);
893
894	if (WIFSIGNALED(status) && WTERMSIG(status) == SIGTERM &&
895	    requested_transition == catatonia) {
896		/* /etc/rc executed /sbin/reboot; wait for the end quietly */
897		sigset_t s;
898
899		sigfillset(&s);
900		for (;;)
901			sigsuspend(&s);
902	}
903
904	if (!WIFEXITED(status)) {
905		warning("%s on %s terminated abnormally, going to single "
906		    "user mode", shell, script);
907		return (state_func_t) single_user;
908	}
909
910	if (WEXITSTATUS(status))
911		return (state_func_t) single_user;
912
913	return (state_func_t) 0;
914}
915
916/*
917 * Open the session database.
918 *
919 * NB: We could pass in the size here; is it necessary?
920 */
921static int
922start_session_db(void)
923{
924	if (session_db && (*session_db->close)(session_db))
925		emergency("session database close: %s", strerror(errno));
926	if ((session_db = dbopen(NULL, O_RDWR, 0, DB_HASH, NULL)) == 0) {
927		emergency("session database open: %s", strerror(errno));
928		return (1);
929	}
930	return (0);
931
932}
933
934/*
935 * Add a new login session.
936 */
937static void
938add_session(session_t *sp)
939{
940	DBT key;
941	DBT data;
942
943	key.data = &sp->se_process;
944	key.size = sizeof sp->se_process;
945	data.data = &sp;
946	data.size = sizeof sp;
947
948	if ((*session_db->put)(session_db, &key, &data, 0))
949		emergency("insert %d: %s", sp->se_process, strerror(errno));
950}
951
952/*
953 * Delete an old login session.
954 */
955static void
956del_session(session_t *sp)
957{
958	DBT key;
959
960	key.data = &sp->se_process;
961	key.size = sizeof sp->se_process;
962
963	if ((*session_db->del)(session_db, &key, 0))
964		emergency("delete %d: %s", sp->se_process, strerror(errno));
965}
966
967/*
968 * Look up a login session by pid.
969 */
970static session_t *
971find_session(pid_t pid)
972{
973	DBT key;
974	DBT data;
975	session_t *ret;
976
977	key.data = &pid;
978	key.size = sizeof pid;
979	if ((*session_db->get)(session_db, &key, &data, 0) != 0)
980		return 0;
981	bcopy(data.data, (char *)&ret, sizeof(ret));
982	return ret;
983}
984
985/*
986 * Construct an argument vector from a command line.
987 */
988static char **
989construct_argv(char *command)
990{
991	int argc = 0;
992	char **argv = (char **) malloc(((strlen(command) + 1) / 2 + 1)
993						* sizeof (char *));
994
995	if ((argv[argc++] = strk(command)) == 0) {
996		free(argv);
997		return (NULL);
998	}
999	while ((argv[argc++] = strk((char *) 0)) != NULL)
1000		continue;
1001	return argv;
1002}
1003
1004/*
1005 * Deallocate a session descriptor.
1006 */
1007static void
1008free_session(session_t *sp)
1009{
1010	free(sp->se_device);
1011	if (sp->se_getty) {
1012		free(sp->se_getty);
1013		free(sp->se_getty_argv_space);
1014		free(sp->se_getty_argv);
1015	}
1016	if (sp->se_window) {
1017		free(sp->se_window);
1018		free(sp->se_window_argv_space);
1019		free(sp->se_window_argv);
1020	}
1021	if (sp->se_type)
1022		free(sp->se_type);
1023	free(sp);
1024}
1025
1026/*
1027 * Allocate a new session descriptor.
1028 * Mark it SE_PRESENT.
1029 */
1030static session_t *
1031new_session(session_t *sprev, int session_index, struct ttyent *typ)
1032{
1033	session_t *sp;
1034	int fd;
1035
1036	if ((typ->ty_status & TTY_ON) == 0 ||
1037	    typ->ty_name == 0 ||
1038	    typ->ty_getty == 0)
1039		return 0;
1040
1041	sp = (session_t *) calloc(1, sizeof (session_t));
1042
1043	sp->se_index = session_index;
1044	sp->se_flags |= SE_PRESENT;
1045
1046	sp->se_device = malloc(sizeof(_PATH_DEV) + strlen(typ->ty_name));
1047	sprintf(sp->se_device, "%s%s", _PATH_DEV, typ->ty_name);
1048
1049	/*
1050	 * Attempt to open the device, if we get "device not configured"
1051	 * then don't add the device to the session list.
1052	 */
1053	if ((fd = open(sp->se_device, O_RDONLY | O_NONBLOCK, 0)) < 0) {
1054		if (errno == ENXIO) {
1055			free_session(sp);
1056			return (0);
1057		}
1058	} else
1059		close(fd);
1060
1061	if (setupargv(sp, typ) == 0) {
1062		free_session(sp);
1063		return (0);
1064	}
1065
1066	sp->se_next = 0;
1067	if (sprev == 0) {
1068		sessions = sp;
1069		sp->se_prev = 0;
1070	} else {
1071		sprev->se_next = sp;
1072		sp->se_prev = sprev;
1073	}
1074
1075	return sp;
1076}
1077
1078/*
1079 * Calculate getty and if useful window argv vectors.
1080 */
1081static int
1082setupargv(session_t *sp, struct ttyent *typ)
1083{
1084
1085	if (sp->se_getty) {
1086		free(sp->se_getty);
1087		free(sp->se_getty_argv_space);
1088		free(sp->se_getty_argv);
1089	}
1090	sp->se_getty = malloc(strlen(typ->ty_getty) + strlen(typ->ty_name) + 2);
1091	sprintf(sp->se_getty, "%s %s", typ->ty_getty, typ->ty_name);
1092	sp->se_getty_argv_space = strdup(sp->se_getty);
1093	sp->se_getty_argv = construct_argv(sp->se_getty_argv_space);
1094	if (sp->se_getty_argv == 0) {
1095		warning("can't parse getty for port %s", sp->se_device);
1096		free(sp->se_getty);
1097		free(sp->se_getty_argv_space);
1098		sp->se_getty = sp->se_getty_argv_space = 0;
1099		return (0);
1100	}
1101	if (sp->se_window) {
1102		free(sp->se_window);
1103		free(sp->se_window_argv_space);
1104		free(sp->se_window_argv);
1105	}
1106	sp->se_window = sp->se_window_argv_space = 0;
1107	sp->se_window_argv = 0;
1108	if (typ->ty_window) {
1109		sp->se_window = strdup(typ->ty_window);
1110		sp->se_window_argv_space = strdup(sp->se_window);
1111		sp->se_window_argv = construct_argv(sp->se_window_argv_space);
1112		if (sp->se_window_argv == 0) {
1113			warning("can't parse window for port %s",
1114			    sp->se_device);
1115			free(sp->se_window_argv_space);
1116			free(sp->se_window);
1117			sp->se_window = sp->se_window_argv_space = 0;
1118			return (0);
1119		}
1120	}
1121	if (sp->se_type)
1122		free(sp->se_type);
1123	sp->se_type = typ->ty_type ? strdup(typ->ty_type) : 0;
1124	return (1);
1125}
1126
1127/*
1128 * Walk the list of ttys and create sessions for each active line.
1129 */
1130static state_func_t
1131read_ttys(void)
1132{
1133	int session_index = 0;
1134	session_t *sp, *snext;
1135	struct ttyent *typ;
1136
1137	/*
1138	 * Destroy any previous session state.
1139	 * There shouldn't be any, but just in case...
1140	 */
1141	for (sp = sessions; sp; sp = snext) {
1142		if (sp->se_process)
1143			clear_session_logs(sp);
1144		snext = sp->se_next;
1145		free_session(sp);
1146	}
1147	sessions = 0;
1148	if (start_session_db())
1149		return (state_func_t) single_user;
1150
1151	/*
1152	 * Allocate a session entry for each active port.
1153	 * Note that sp starts at 0.
1154	 */
1155	while ((typ = getttyent()) != NULL)
1156		if ((snext = new_session(sp, ++session_index, typ)) != NULL)
1157			sp = snext;
1158
1159	endttyent();
1160
1161	return (state_func_t) multi_user;
1162}
1163
1164/*
1165 * Start a window system running.
1166 */
1167static void
1168start_window_system(session_t *sp)
1169{
1170	pid_t pid;
1171	sigset_t mask;
1172	char term[64], *env[2];
1173	int status;
1174
1175	if ((pid = fork()) == -1) {
1176		emergency("can't fork for window system on port %s: %m",
1177		    sp->se_device);
1178		/* hope that getty fails and we can try again */
1179		return;
1180	}
1181	if (pid) {
1182		waitpid(-1, &status, 0);
1183		return;
1184	}
1185
1186	/* reparent window process to the init to not make a zombie on exit */
1187	if ((pid = fork()) == -1) {
1188		emergency("can't fork for window system on port %s: %m",
1189		    sp->se_device);
1190		_exit(1);
1191	}
1192	if (pid)
1193		_exit(0);
1194
1195	sigemptyset(&mask);
1196	sigprocmask(SIG_SETMASK, &mask, (sigset_t *) 0);
1197
1198	if (setsid() < 0)
1199		emergency("setsid failed (window) %m");
1200
1201#ifdef LOGIN_CAP
1202	setprocresources(RESOURCE_WINDOW);
1203#endif
1204	if (sp->se_type) {
1205		/* Don't use malloc after fork */
1206		strcpy(term, "TERM=");
1207		strncat(term, sp->se_type, sizeof(term) - 6);
1208		env[0] = term;
1209		env[1] = 0;
1210	}
1211	else
1212		env[0] = 0;
1213	execve(sp->se_window_argv[0], sp->se_window_argv, env);
1214	stall("can't exec window system '%s' for port %s: %m",
1215		sp->se_window_argv[0], sp->se_device);
1216	_exit(1);
1217}
1218
1219/*
1220 * Start a login session running.
1221 */
1222static pid_t
1223start_getty(session_t *sp)
1224{
1225	pid_t pid;
1226	sigset_t mask;
1227	time_t current_time = time((time_t *) 0);
1228	int too_quick = 0;
1229	char term[64], *env[2];
1230
1231	if (current_time >= sp->se_started &&
1232	    current_time - sp->se_started < GETTY_SPACING) {
1233		if (++sp->se_nspace > GETTY_NSPACE) {
1234			sp->se_nspace = 0;
1235			too_quick = 1;
1236		}
1237	} else
1238		sp->se_nspace = 0;
1239
1240	/*
1241	 * fork(), not vfork() -- we can't afford to block.
1242	 */
1243	if ((pid = fork()) == -1) {
1244		emergency("can't fork for getty on port %s: %m", sp->se_device);
1245		return -1;
1246	}
1247
1248	if (pid)
1249		return pid;
1250
1251	if (too_quick) {
1252		warning("getty repeating too quickly on port %s, sleeping %d secs",
1253		    sp->se_device, GETTY_SLEEP);
1254		sleep((unsigned) GETTY_SLEEP);
1255	}
1256
1257	if (sp->se_window) {
1258		start_window_system(sp);
1259		sleep(WINDOW_WAIT);
1260	}
1261
1262	sigemptyset(&mask);
1263	sigprocmask(SIG_SETMASK, &mask, (sigset_t *) 0);
1264
1265#ifdef LOGIN_CAP
1266	setprocresources(RESOURCE_GETTY);
1267#endif
1268	if (sp->se_type) {
1269		/* Don't use malloc after fork */
1270		strcpy(term, "TERM=");
1271		strncat(term, sp->se_type, sizeof(term) - 6);
1272		env[0] = term;
1273		env[1] = 0;
1274	} else
1275		env[0] = 0;
1276	execve(sp->se_getty_argv[0], sp->se_getty_argv, env);
1277	stall("can't exec getty '%s' for port %s: %m",
1278		sp->se_getty_argv[0], sp->se_device);
1279	_exit(1);
1280}
1281
1282/*
1283 * Collect exit status for a child.
1284 * If an exiting login, start a new login running.
1285 */
1286static void
1287collect_child(pid_t pid)
1288{
1289	session_t *sp, *sprev, *snext;
1290
1291	if (! sessions)
1292		return;
1293
1294	if (! (sp = find_session(pid)))
1295		return;
1296
1297	clear_session_logs(sp);
1298	del_session(sp);
1299	sp->se_process = 0;
1300
1301	if (sp->se_flags & SE_SHUTDOWN) {
1302		if ((sprev = sp->se_prev) != NULL)
1303			sprev->se_next = sp->se_next;
1304		else
1305			sessions = sp->se_next;
1306		if ((snext = sp->se_next) != NULL)
1307			snext->se_prev = sp->se_prev;
1308		free_session(sp);
1309		return;
1310	}
1311
1312	if ((pid = start_getty(sp)) == -1) {
1313		/* serious trouble */
1314		requested_transition = clean_ttys;
1315		return;
1316	}
1317
1318	sp->se_process = pid;
1319	sp->se_started = time((time_t *) 0);
1320	add_session(sp);
1321}
1322
1323/*
1324 * Catch a signal and request a state transition.
1325 */
1326static void
1327transition_handler(int sig)
1328{
1329
1330	switch (sig) {
1331	case SIGHUP:
1332		if (current_state == read_ttys || current_state == multi_user ||
1333		    current_state == clean_ttys || current_state == catatonia)
1334			requested_transition = clean_ttys;
1335		break;
1336	case SIGUSR2:
1337		howto = RB_POWEROFF;
1338	case SIGUSR1:
1339		howto |= RB_HALT;
1340	case SIGINT:
1341		Reboot = TRUE;
1342	case SIGTERM:
1343		if (current_state == read_ttys || current_state == multi_user ||
1344		    current_state == clean_ttys || current_state == catatonia)
1345			requested_transition = death;
1346		else
1347			requested_transition = death_single;
1348		break;
1349	case SIGTSTP:
1350		if (current_state == runcom || current_state == read_ttys ||
1351		    current_state == clean_ttys ||
1352		    current_state == multi_user || current_state == catatonia)
1353			requested_transition = catatonia;
1354		break;
1355	default:
1356		requested_transition = 0;
1357		break;
1358	}
1359}
1360
1361/*
1362 * Take the system multiuser.
1363 */
1364static state_func_t
1365multi_user(void)
1366{
1367	pid_t pid;
1368	session_t *sp;
1369
1370	requested_transition = 0;
1371
1372	/*
1373	 * If the administrator has not set the security level to -1
1374	 * to indicate that the kernel should not run multiuser in secure
1375	 * mode, and the run script has not set a higher level of security
1376	 * than level 1, then put the kernel into secure mode.
1377	 */
1378	if (getsecuritylevel() == 0)
1379		setsecuritylevel(1);
1380
1381	for (sp = sessions; sp; sp = sp->se_next) {
1382		if (sp->se_process)
1383			continue;
1384		if ((pid = start_getty(sp)) == -1) {
1385			/* serious trouble */
1386			requested_transition = clean_ttys;
1387			break;
1388		}
1389		sp->se_process = pid;
1390		sp->se_started = time((time_t *) 0);
1391		add_session(sp);
1392	}
1393
1394	while (!requested_transition)
1395		if ((pid = waitpid(-1, (int *) 0, 0)) != -1)
1396			collect_child(pid);
1397
1398	return (state_func_t) requested_transition;
1399}
1400
1401/*
1402 * This is an (n*2)+(n^2) algorithm.  We hope it isn't run often...
1403 */
1404static state_func_t
1405clean_ttys(void)
1406{
1407	session_t *sp, *sprev;
1408	struct ttyent *typ;
1409	int session_index = 0;
1410	int devlen;
1411	char *old_getty, *old_window, *old_type;
1412
1413	/*
1414	 * mark all sessions for death, (!SE_PRESENT)
1415	 * as we find or create new ones they'll be marked as keepers,
1416	 * we'll later nuke all the ones not found in /etc/ttys
1417	 */
1418	for (sp = sessions; sp != NULL; sp = sp->se_next)
1419		sp->se_flags &= ~SE_PRESENT;
1420
1421	devlen = sizeof(_PATH_DEV) - 1;
1422	while ((typ = getttyent()) != NULL) {
1423		++session_index;
1424
1425		for (sprev = 0, sp = sessions; sp; sprev = sp, sp = sp->se_next)
1426			if (strcmp(typ->ty_name, sp->se_device + devlen) == 0)
1427				break;
1428
1429		if (sp) {
1430			/* we want this one to live */
1431			sp->se_flags |= SE_PRESENT;
1432			if (sp->se_index != session_index) {
1433				warning("port %s changed utmp index from %d to %d",
1434				       sp->se_device, sp->se_index,
1435				       session_index);
1436				sp->se_index = session_index;
1437			}
1438			if ((typ->ty_status & TTY_ON) == 0 ||
1439			    typ->ty_getty == 0) {
1440				sp->se_flags |= SE_SHUTDOWN;
1441				kill(sp->se_process, SIGHUP);
1442				continue;
1443			}
1444			sp->se_flags &= ~SE_SHUTDOWN;
1445			old_getty = sp->se_getty ? strdup(sp->se_getty) : 0;
1446			old_window = sp->se_window ? strdup(sp->se_window) : 0;
1447			old_type = sp->se_type ? strdup(sp->se_type) : 0;
1448			if (setupargv(sp, typ) == 0) {
1449				warning("can't parse getty for port %s",
1450					sp->se_device);
1451				sp->se_flags |= SE_SHUTDOWN;
1452				kill(sp->se_process, SIGHUP);
1453			}
1454			else if (   !old_getty
1455				 || (!old_type && sp->se_type)
1456				 || (old_type && !sp->se_type)
1457				 || (!old_window && sp->se_window)
1458				 || (old_window && !sp->se_window)
1459				 || (strcmp(old_getty, sp->se_getty) != 0)
1460				 || (old_window && strcmp(old_window, sp->se_window) != 0)
1461				 || (old_type && strcmp(old_type, sp->se_type) != 0)
1462				) {
1463				/* Don't set SE_SHUTDOWN here */
1464				sp->se_nspace = 0;
1465				sp->se_started = 0;
1466				kill(sp->se_process, SIGHUP);
1467			}
1468			if (old_getty)
1469				free(old_getty);
1470			if (old_window)
1471				free(old_window);
1472			if (old_type)
1473				free(old_type);
1474			continue;
1475		}
1476
1477		new_session(sprev, session_index, typ);
1478	}
1479
1480	endttyent();
1481
1482	/*
1483	 * sweep through and kill all deleted sessions
1484	 * ones who's /etc/ttys line was deleted (SE_PRESENT unset)
1485	 */
1486	for (sp = sessions; sp != NULL; sp = sp->se_next) {
1487		if ((sp->se_flags & SE_PRESENT) == 0) {
1488			sp->se_flags |= SE_SHUTDOWN;
1489			kill(sp->se_process, SIGHUP);
1490		}
1491	}
1492
1493	return (state_func_t) multi_user;
1494}
1495
1496/*
1497 * Block further logins.
1498 */
1499static state_func_t
1500catatonia(void)
1501{
1502	session_t *sp;
1503
1504	for (sp = sessions; sp; sp = sp->se_next)
1505		sp->se_flags |= SE_SHUTDOWN;
1506
1507	return (state_func_t) multi_user;
1508}
1509
1510/*
1511 * Note SIGALRM.
1512 */
1513static void
1514alrm_handler(int sig)
1515{
1516
1517	(void)sig;
1518	clang = 1;
1519}
1520
1521/*
1522 * Bring the system down to single user.
1523 */
1524static state_func_t
1525death(void)
1526{
1527	struct utmpx utx;
1528	session_t *sp;
1529
1530	/* NB: should send a message to the session logger to avoid blocking. */
1531	utx.ut_type = SHUTDOWN_TIME;
1532	gettimeofday(&utx.ut_tv, NULL);
1533	pututxline(&utx);
1534
1535	/*
1536	 * Also revoke the TTY here.  Because runshutdown() may reopen
1537	 * the TTY whose getty we're killing here, there is no guarantee
1538	 * runshutdown() will perform the initial open() call, causing
1539	 * the terminal attributes to be misconfigured.
1540	 */
1541	for (sp = sessions; sp; sp = sp->se_next) {
1542		sp->se_flags |= SE_SHUTDOWN;
1543		kill(sp->se_process, SIGHUP);
1544		revoke(sp->se_device);
1545	}
1546
1547	/* Try to run the rc.shutdown script within a period of time */
1548	runshutdown();
1549
1550	return (state_func_t) death_single;
1551}
1552
1553/*
1554 * Do what is necessary to reinitialize single user mode or reboot
1555 * from an incomplete state.
1556 */
1557static state_func_t
1558death_single(void)
1559{
1560	int i;
1561	pid_t pid;
1562	static const int death_sigs[2] = { SIGTERM, SIGKILL };
1563
1564	revoke(_PATH_CONSOLE);
1565
1566	for (i = 0; i < 2; ++i) {
1567		if (kill(-1, death_sigs[i]) == -1 && errno == ESRCH)
1568			return (state_func_t) single_user;
1569
1570		clang = 0;
1571		alarm(DEATH_WATCH);
1572		do
1573			if ((pid = waitpid(-1, (int *)0, 0)) != -1)
1574				collect_child(pid);
1575		while (clang == 0 && errno != ECHILD);
1576
1577		if (errno == ECHILD)
1578			return (state_func_t) single_user;
1579	}
1580
1581	warning("some processes would not die; ps axl advised");
1582
1583	return (state_func_t) single_user;
1584}
1585
1586/*
1587 * Run the system shutdown script.
1588 *
1589 * Exit codes:      XXX I should document more
1590 * -2       shutdown script terminated abnormally
1591 * -1       fatal error - can't run script
1592 * 0        good.
1593 * >0       some error (exit code)
1594 */
1595static int
1596runshutdown(void)
1597{
1598	pid_t pid, wpid;
1599	int status;
1600	int shutdowntimeout;
1601	size_t len;
1602	char *argv[4];
1603	const char *shell;
1604	struct sigaction sa;
1605	struct stat sb;
1606
1607	/*
1608	 * rc.shutdown is optional, so to prevent any unnecessary
1609	 * complaints from the shell we simply don't run it if the
1610	 * file does not exist. If the stat() here fails for other
1611	 * reasons, we'll let the shell complain.
1612	 */
1613	if (stat(_PATH_RUNDOWN, &sb) == -1 && errno == ENOENT)
1614		return 0;
1615
1616	shell = get_shell();
1617
1618	if ((pid = fork()) == 0) {
1619		sigemptyset(&sa.sa_mask);
1620		sa.sa_flags = 0;
1621		sa.sa_handler = SIG_IGN;
1622		sigaction(SIGTSTP, &sa, (struct sigaction *)0);
1623		sigaction(SIGHUP, &sa, (struct sigaction *)0);
1624
1625		open_console();
1626
1627		char _sh[]	= "sh";
1628		char _reboot[]	= "reboot";
1629		char _single[]	= "single";
1630		char _path_rundown[] = _PATH_RUNDOWN;
1631
1632		argv[0] = _sh;
1633		argv[1] = _path_rundown;
1634		argv[2] = Reboot ? _reboot : _single;
1635		argv[3] = 0;
1636
1637		sigprocmask(SIG_SETMASK, &sa.sa_mask, (sigset_t *) 0);
1638
1639#ifdef LOGIN_CAP
1640		setprocresources(RESOURCE_RC);
1641#endif
1642		execv(shell, argv);
1643		warning("can't exec %s for %s: %m", shell, _PATH_RUNDOWN);
1644		_exit(1);	/* force single user mode */
1645	}
1646
1647	if (pid == -1) {
1648		emergency("can't fork for %s on %s: %m", shell, _PATH_RUNDOWN);
1649		while (waitpid(-1, (int *) 0, WNOHANG) > 0)
1650			continue;
1651		sleep(STALL_TIMEOUT);
1652		return -1;
1653	}
1654
1655	len = sizeof(shutdowntimeout);
1656	if (sysctlbyname("kern.init_shutdown_timeout", &shutdowntimeout, &len,
1657	    NULL, 0) == -1 || shutdowntimeout < 2)
1658		shutdowntimeout = DEATH_SCRIPT;
1659	alarm(shutdowntimeout);
1660	clang = 0;
1661	/*
1662	 * Copied from single_user().  This is a bit paranoid.
1663	 * Use the same ALRM handler.
1664	 */
1665	do {
1666		if ((wpid = waitpid(-1, &status, WUNTRACED)) != -1)
1667			collect_child(wpid);
1668		if (clang == 1) {
1669			/* we were waiting for the sub-shell */
1670			kill(wpid, SIGTERM);
1671			warning("timeout expired for %s on %s: %m; going to "
1672			    "single user mode", shell, _PATH_RUNDOWN);
1673			return -1;
1674		}
1675		if (wpid == -1) {
1676			if (errno == EINTR)
1677				continue;
1678			warning("wait for %s on %s failed: %m; going to "
1679			    "single user mode", shell, _PATH_RUNDOWN);
1680			return -1;
1681		}
1682		if (wpid == pid && WIFSTOPPED(status)) {
1683			warning("init: %s on %s stopped, restarting\n",
1684				shell, _PATH_RUNDOWN);
1685			kill(pid, SIGCONT);
1686			wpid = -1;
1687		}
1688	} while (wpid != pid && !clang);
1689
1690	/* Turn off the alarm */
1691	alarm(0);
1692
1693	if (WIFSIGNALED(status) && WTERMSIG(status) == SIGTERM &&
1694	    requested_transition == catatonia) {
1695		/*
1696		 * /etc/rc.shutdown executed /sbin/reboot;
1697		 * wait for the end quietly
1698		 */
1699		sigset_t s;
1700
1701		sigfillset(&s);
1702		for (;;)
1703			sigsuspend(&s);
1704	}
1705
1706	if (!WIFEXITED(status)) {
1707		warning("%s on %s terminated abnormally, going to "
1708		    "single user mode", shell, _PATH_RUNDOWN);
1709		return -2;
1710	}
1711
1712	if ((status = WEXITSTATUS(status)) != 0)
1713		warning("%s returned status %d", _PATH_RUNDOWN, status);
1714
1715	return status;
1716}
1717
1718static char *
1719strk(char *p)
1720{
1721	static char *t;
1722	char *q;
1723	int c;
1724
1725	if (p)
1726		t = p;
1727	if (!t)
1728		return 0;
1729
1730	c = *t;
1731	while (c == ' ' || c == '\t' )
1732		c = *++t;
1733	if (!c) {
1734		t = 0;
1735		return 0;
1736	}
1737	q = t;
1738	if (c == '\'') {
1739		c = *++t;
1740		q = t;
1741		while (c && c != '\'')
1742			c = *++t;
1743		if (!c)  /* unterminated string */
1744			q = t = 0;
1745		else
1746			*t++ = 0;
1747	} else {
1748		while (c && c != ' ' && c != '\t' )
1749			c = *++t;
1750		*t++ = 0;
1751		if (!c)
1752			t = 0;
1753	}
1754	return q;
1755}
1756
1757#ifdef LOGIN_CAP
1758static void
1759setprocresources(const char *cname)
1760{
1761	login_cap_t *lc;
1762	if ((lc = login_getclassbyname(cname, NULL)) != NULL) {
1763		setusercontext(lc, (struct passwd*)NULL, 0,
1764		    LOGIN_SETPRIORITY | LOGIN_SETRESOURCES);
1765		login_close(lc);
1766	}
1767}
1768#endif
1769