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: stable/11/sbin/init/init.c 365534 2020-09-09 22:40:39Z brooks $";
45#endif /* not lint */
46
47#include <sys/param.h>
48#include <sys/ioctl.h>
49#include <sys/mman.h>
50#include <sys/mount.h>
51#include <sys/sysctl.h>
52#include <sys/wait.h>
53#include <sys/stat.h>
54#include <sys/uio.h>
55
56#include <db.h>
57#include <errno.h>
58#include <fcntl.h>
59#include <kenv.h>
60#include <libutil.h>
61#include <paths.h>
62#include <signal.h>
63#include <stdio.h>
64#include <stdlib.h>
65#include <string.h>
66#include <syslog.h>
67#include <time.h>
68#include <ttyent.h>
69#include <unistd.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 "mntopts.h"
84#include "pathnames.h"
85
86/*
87 * Sleep times; used to prevent thrashing.
88 */
89#define	GETTY_SPACING		 5	/* N secs minimum getty spacing */
90#define	GETTY_SLEEP		30	/* sleep N secs after spacing problem */
91#define	GETTY_NSPACE		 3	/* max. spacing count to bring reaction */
92#define	WINDOW_WAIT		 3	/* wait N secs after starting window */
93#define	STALL_TIMEOUT		30	/* wait N secs after warning */
94#define	DEATH_WATCH		10	/* wait N secs for procs to die */
95#define	DEATH_SCRIPT		120	/* wait for 2min for /etc/rc.shutdown */
96#define	RESOURCE_RC		"daemon"
97#define	RESOURCE_WINDOW		"default"
98#define	RESOURCE_GETTY		"default"
99
100static void handle(sig_t, ...);
101static void delset(sigset_t *, ...);
102
103static void stall(const char *, ...) __printflike(1, 2);
104static void warning(const char *, ...) __printflike(1, 2);
105static void emergency(const char *, ...) __printflike(1, 2);
106static void disaster(int);
107static void revoke_ttys(void);
108static int  runshutdown(void);
109static char *strk(char *);
110
111/*
112 * We really need a recursive typedef...
113 * The following at least guarantees that the return type of (*state_t)()
114 * is sufficiently wide to hold a function pointer.
115 */
116typedef long (*state_func_t)(void);
117typedef state_func_t (*state_t)(void);
118
119static state_func_t single_user(void);
120static state_func_t runcom(void);
121static state_func_t read_ttys(void);
122static state_func_t multi_user(void);
123static state_func_t clean_ttys(void);
124static state_func_t catatonia(void);
125static state_func_t death(void);
126static state_func_t death_single(void);
127static state_func_t reroot(void);
128static state_func_t reroot_phase_two(void);
129
130static state_func_t run_script(const char *);
131
132static enum { AUTOBOOT, FASTBOOT } runcom_mode = AUTOBOOT;
133#define FALSE	0
134#define TRUE	1
135
136static int Reboot = FALSE;
137static int howto = RB_AUTOBOOT;
138
139static int devfs;
140static char *init_path_argv0;
141
142static void transition(state_t);
143static state_t requested_transition;
144static state_t current_state = death_single;
145
146static void execute_script(char *argv[]);
147static void open_console(void);
148static const char *get_shell(void);
149static void replace_init(char *path);
150static void write_stderr(const char *message);
151
152typedef struct init_session {
153	pid_t	se_process;		/* controlling process */
154	time_t	se_started;		/* used to avoid thrashing */
155	int	se_flags;		/* status of session */
156#define	SE_SHUTDOWN	0x1		/* session won't be restarted */
157#define	SE_PRESENT	0x2		/* session is in /etc/ttys */
158#define	SE_IFEXISTS	0x4		/* session defined as "onifexists" */
159#define	SE_IFCONSOLE	0x8		/* session defined as "onifconsole" */
160	int	se_nspace;		/* spacing count */
161	char	*se_device;		/* filename of port */
162	char	*se_getty;		/* what to run on that port */
163	char	*se_getty_argv_space;   /* pre-parsed argument array space */
164	char	**se_getty_argv;	/* pre-parsed argument array */
165	char	*se_window;		/* window system (started only once) */
166	char	*se_window_argv_space;  /* pre-parsed argument array space */
167	char	**se_window_argv;	/* pre-parsed argument array */
168	char	*se_type;		/* default terminal type */
169	struct	init_session *se_prev;
170	struct	init_session *se_next;
171} session_t;
172
173static void free_session(session_t *);
174static session_t *new_session(session_t *, struct ttyent *);
175static session_t *sessions;
176
177static char **construct_argv(char *);
178static void start_window_system(session_t *);
179static void collect_child(pid_t);
180static pid_t start_getty(session_t *);
181static void transition_handler(int);
182static void alrm_handler(int);
183static void setsecuritylevel(int);
184static int getsecuritylevel(void);
185static int setupargv(session_t *, struct ttyent *);
186#ifdef LOGIN_CAP
187static void setprocresources(const char *);
188#endif
189static int clang;
190
191static int start_session_db(void);
192static void add_session(session_t *);
193static void del_session(session_t *);
194static session_t *find_session(pid_t);
195static DB *session_db;
196
197/*
198 * The mother of all processes.
199 */
200int
201main(int argc, char *argv[])
202{
203	state_t initial_transition = runcom;
204	char kenv_value[PATH_MAX];
205	int c, error;
206	struct sigaction sa;
207	sigset_t mask;
208
209	/* Dispose of random users. */
210	if (getuid() != 0)
211		errx(1, "%s", strerror(EPERM));
212
213	/* System V users like to reexec init. */
214	if (getpid() != 1) {
215#ifdef COMPAT_SYSV_INIT
216		/* So give them what they want */
217		if (argc > 1) {
218			if (strlen(argv[1]) == 1) {
219				char runlevel = *argv[1];
220				int sig;
221
222				switch (runlevel) {
223				case '0': /* halt + poweroff */
224					sig = SIGUSR2;
225					break;
226				case '1': /* single-user */
227					sig = SIGTERM;
228					break;
229				case '6': /* reboot */
230					sig = SIGINT;
231					break;
232				case 'c': /* block further logins */
233					sig = SIGTSTP;
234					break;
235				case 'q': /* rescan /etc/ttys */
236					sig = SIGHUP;
237					break;
238				case 'r': /* remount root */
239					sig = SIGEMT;
240					break;
241				default:
242					goto invalid;
243				}
244				kill(1, sig);
245				_exit(0);
246			} else
247invalid:
248				errx(1, "invalid run-level ``%s''", argv[1]);
249		} else
250#endif
251			errx(1, "already running");
252	}
253
254	init_path_argv0 = strdup(argv[0]);
255	if (init_path_argv0 == NULL)
256		err(1, "strdup");
257
258	/*
259	 * Note that this does NOT open a file...
260	 * Does 'init' deserve its own facility number?
261	 */
262	openlog("init", LOG_CONS, LOG_AUTH);
263
264	/*
265	 * Create an initial session.
266	 */
267	if (setsid() < 0 && (errno != EPERM || getsid(0) != 1))
268		warning("initial setsid() failed: %m");
269
270	/*
271	 * Establish an initial user so that programs running
272	 * single user do not freak out and die (like passwd).
273	 */
274	if (setlogin("root") < 0)
275		warning("setlogin() failed: %m");
276
277	/*
278	 * This code assumes that we always get arguments through flags,
279	 * never through bits set in some random machine register.
280	 */
281	while ((c = getopt(argc, argv, "dsfr")) != -1)
282		switch (c) {
283		case 'd':
284			devfs = 1;
285			break;
286		case 's':
287			initial_transition = single_user;
288			break;
289		case 'f':
290			runcom_mode = FASTBOOT;
291			break;
292		case 'r':
293			initial_transition = reroot_phase_two;
294			break;
295		default:
296			warning("unrecognized flag '-%c'", c);
297			break;
298		}
299
300	if (optind != argc)
301		warning("ignoring excess arguments");
302
303	/*
304	 * We catch or block signals rather than ignore them,
305	 * so that they get reset on exec.
306	 */
307	handle(disaster, SIGABRT, SIGFPE, SIGILL, SIGSEGV, SIGBUS, SIGSYS,
308	    SIGXCPU, SIGXFSZ, 0);
309	handle(transition_handler, SIGHUP, SIGINT, SIGEMT, SIGTERM, SIGTSTP,
310	    SIGUSR1, SIGUSR2, 0);
311	handle(alrm_handler, SIGALRM, 0);
312	sigfillset(&mask);
313	delset(&mask, SIGABRT, SIGFPE, SIGILL, SIGSEGV, SIGBUS, SIGSYS,
314	    SIGXCPU, SIGXFSZ, SIGHUP, SIGINT, SIGEMT, SIGTERM, SIGTSTP,
315	    SIGALRM, SIGUSR1, SIGUSR2, 0);
316	sigprocmask(SIG_SETMASK, &mask, NULL);
317	sigemptyset(&sa.sa_mask);
318	sa.sa_flags = 0;
319	sa.sa_handler = SIG_IGN;
320	sigaction(SIGTTIN, &sa, NULL);
321	sigaction(SIGTTOU, &sa, NULL);
322
323	/*
324	 * Paranoia.
325	 */
326	close(0);
327	close(1);
328	close(2);
329
330	if (kenv(KENV_GET, "init_exec", kenv_value, sizeof(kenv_value)) > 0) {
331		replace_init(kenv_value);
332		_exit(0); /* reboot */
333	}
334
335	if (kenv(KENV_GET, "init_script", kenv_value, sizeof(kenv_value)) > 0) {
336		state_func_t next_transition;
337
338		if ((next_transition = run_script(kenv_value)) != NULL)
339			initial_transition = (state_t) next_transition;
340	}
341
342	if (kenv(KENV_GET, "init_chroot", kenv_value, sizeof(kenv_value)) > 0) {
343		if (chdir(kenv_value) != 0 || chroot(".") != 0)
344			warning("Can't chroot to %s: %m", kenv_value);
345	}
346
347	/*
348	 * Additional check if devfs needs to be mounted:
349	 * If "/" and "/dev" have the same device number,
350	 * then it hasn't been mounted yet.
351	 */
352	if (!devfs) {
353		struct stat stst;
354		dev_t root_devno;
355
356		stat("/", &stst);
357		root_devno = stst.st_dev;
358		if (stat("/dev", &stst) != 0)
359			warning("Can't stat /dev: %m");
360		else if (stst.st_dev == root_devno)
361			devfs++;
362	}
363
364	if (devfs) {
365		struct iovec iov[4];
366		char *s;
367		int i;
368
369		char _fstype[]	= "fstype";
370		char _devfs[]	= "devfs";
371		char _fspath[]	= "fspath";
372		char _path_dev[]= _PATH_DEV;
373
374		iov[0].iov_base = _fstype;
375		iov[0].iov_len = sizeof(_fstype);
376		iov[1].iov_base = _devfs;
377		iov[1].iov_len = sizeof(_devfs);
378		iov[2].iov_base = _fspath;
379		iov[2].iov_len = sizeof(_fspath);
380		/*
381		 * Try to avoid the trailing slash in _PATH_DEV.
382		 * Be *very* defensive.
383		 */
384		s = strdup(_PATH_DEV);
385		if (s != NULL) {
386			i = strlen(s);
387			if (i > 0 && s[i - 1] == '/')
388				s[i - 1] = '\0';
389			iov[3].iov_base = s;
390			iov[3].iov_len = strlen(s) + 1;
391		} else {
392			iov[3].iov_base = _path_dev;
393			iov[3].iov_len = sizeof(_path_dev);
394		}
395		nmount(iov, 4, 0);
396		if (s != NULL)
397			free(s);
398	}
399
400	if (initial_transition != reroot_phase_two) {
401		/*
402		 * Unmount reroot leftovers.  This runs after init(8)
403		 * gets reexecuted after reroot_phase_two() is done.
404		 */
405		error = unmount(_PATH_REROOT, MNT_FORCE);
406		if (error != 0 && errno != EINVAL)
407			warning("Cannot unmount %s: %m", _PATH_REROOT);
408	}
409
410	/*
411	 * Start the state machine.
412	 */
413	transition(initial_transition);
414
415	/*
416	 * Should never reach here.
417	 */
418	return 1;
419}
420
421/*
422 * Associate a function with a signal handler.
423 */
424static void
425handle(sig_t handler, ...)
426{
427	int sig;
428	struct sigaction sa;
429	sigset_t mask_everything;
430	va_list ap;
431	va_start(ap, handler);
432
433	sa.sa_handler = handler;
434	sigfillset(&mask_everything);
435
436	while ((sig = va_arg(ap, int)) != 0) {
437		sa.sa_mask = mask_everything;
438		/* XXX SA_RESTART? */
439		sa.sa_flags = sig == SIGCHLD ? SA_NOCLDSTOP : 0;
440		sigaction(sig, &sa, NULL);
441	}
442	va_end(ap);
443}
444
445/*
446 * Delete a set of signals from a mask.
447 */
448static void
449delset(sigset_t *maskp, ...)
450{
451	int sig;
452	va_list ap;
453	va_start(ap, maskp);
454
455	while ((sig = va_arg(ap, int)) != 0)
456		sigdelset(maskp, sig);
457	va_end(ap);
458}
459
460/*
461 * Log a message and sleep for a while (to give someone an opportunity
462 * to read it and to save log or hardcopy output if the problem is chronic).
463 * NB: should send a message to the session logger to avoid blocking.
464 */
465static void
466stall(const char *message, ...)
467{
468	va_list ap;
469	va_start(ap, message);
470
471	vsyslog(LOG_ALERT, message, ap);
472	va_end(ap);
473	sleep(STALL_TIMEOUT);
474}
475
476/*
477 * Like stall(), but doesn't sleep.
478 * If cpp had variadic macros, the two functions could be #defines for another.
479 * NB: should send a message to the session logger to avoid blocking.
480 */
481static void
482warning(const char *message, ...)
483{
484	va_list ap;
485	va_start(ap, message);
486
487	vsyslog(LOG_ALERT, message, ap);
488	va_end(ap);
489}
490
491/*
492 * Log an emergency message.
493 * NB: should send a message to the session logger to avoid blocking.
494 */
495static void
496emergency(const char *message, ...)
497{
498	va_list ap;
499	va_start(ap, message);
500
501	vsyslog(LOG_EMERG, message, ap);
502	va_end(ap);
503}
504
505/*
506 * Catch an unexpected signal.
507 */
508static void
509disaster(int sig)
510{
511
512	emergency("fatal signal: %s",
513	    (unsigned)sig < NSIG ? sys_siglist[sig] : "unknown signal");
514
515	sleep(STALL_TIMEOUT);
516	_exit(sig);		/* reboot */
517}
518
519/*
520 * Get the security level of the kernel.
521 */
522static int
523getsecuritylevel(void)
524{
525#ifdef KERN_SECURELVL
526	int name[2], curlevel;
527	size_t len;
528
529	name[0] = CTL_KERN;
530	name[1] = KERN_SECURELVL;
531	len = sizeof curlevel;
532	if (sysctl(name, 2, &curlevel, &len, NULL, 0) == -1) {
533		emergency("cannot get kernel security level: %s",
534		    strerror(errno));
535		return (-1);
536	}
537	return (curlevel);
538#else
539	return (-1);
540#endif
541}
542
543/*
544 * Set the security level of the kernel.
545 */
546static void
547setsecuritylevel(int newlevel)
548{
549#ifdef KERN_SECURELVL
550	int name[2], curlevel;
551
552	curlevel = getsecuritylevel();
553	if (newlevel == curlevel)
554		return;
555	name[0] = CTL_KERN;
556	name[1] = KERN_SECURELVL;
557	if (sysctl(name, 2, NULL, NULL, &newlevel, sizeof newlevel) == -1) {
558		emergency(
559		    "cannot change kernel security level from %d to %d: %s",
560		    curlevel, newlevel, strerror(errno));
561		return;
562	}
563#ifdef SECURE
564	warning("kernel security level changed from %d to %d",
565	    curlevel, newlevel);
566#endif
567#endif
568}
569
570/*
571 * Change states in the finite state machine.
572 * The initial state is passed as an argument.
573 */
574static void
575transition(state_t s)
576{
577
578	current_state = s;
579	for (;;)
580		current_state = (state_t) (*current_state)();
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
641static int
642read_file(const char *path, void **bufp, size_t *bufsizep)
643{
644	struct stat sb;
645	size_t bufsize;
646	void *buf;
647	ssize_t nbytes;
648	int error, fd;
649
650	fd = open(path, O_RDONLY);
651	if (fd < 0) {
652		emergency("%s: %s", path, strerror(errno));
653		return (-1);
654	}
655
656	error = fstat(fd, &sb);
657	if (error != 0) {
658		emergency("fstat: %s", strerror(errno));
659		close(fd);
660		return (error);
661	}
662
663	bufsize = sb.st_size;
664	buf = malloc(bufsize);
665	if (buf == NULL) {
666		emergency("malloc: %s", strerror(errno));
667		close(fd);
668		return (error);
669	}
670
671	nbytes = read(fd, buf, bufsize);
672	if (nbytes != (ssize_t)bufsize) {
673		emergency("read: %s", strerror(errno));
674		close(fd);
675		free(buf);
676		return (error);
677	}
678
679	error = close(fd);
680	if (error != 0) {
681		emergency("close: %s", strerror(errno));
682		free(buf);
683		return (error);
684	}
685
686	*bufp = buf;
687	*bufsizep = bufsize;
688
689	return (0);
690}
691
692static int
693create_file(const char *path, const void *buf, size_t bufsize)
694{
695	ssize_t nbytes;
696	int error, fd;
697
698	fd = open(path, O_WRONLY | O_CREAT | O_EXCL, 0700);
699	if (fd < 0) {
700		emergency("%s: %s", path, strerror(errno));
701		return (-1);
702	}
703
704	nbytes = write(fd, buf, bufsize);
705	if (nbytes != (ssize_t)bufsize) {
706		emergency("write: %s", strerror(errno));
707		close(fd);
708		return (-1);
709	}
710
711	error = close(fd);
712	if (error != 0) {
713		emergency("close: %s", strerror(errno));
714		return (-1);
715	}
716
717	return (0);
718}
719
720static int
721mount_tmpfs(const char *fspath)
722{
723	struct iovec *iov;
724	char errmsg[255];
725	int error, iovlen;
726
727	iov = NULL;
728	iovlen = 0;
729	memset(errmsg, 0, sizeof(errmsg));
730	build_iovec(&iov, &iovlen, "fstype",
731	    __DECONST(void *, "tmpfs"), (size_t)-1);
732	build_iovec(&iov, &iovlen, "fspath",
733	    __DECONST(void *, fspath), (size_t)-1);
734	build_iovec(&iov, &iovlen, "errmsg",
735	    errmsg, sizeof(errmsg));
736
737	error = nmount(iov, iovlen, 0);
738	if (error != 0) {
739		if (*errmsg != '\0') {
740			emergency("cannot mount tmpfs on %s: %s: %s",
741			    fspath, errmsg, strerror(errno));
742		} else {
743			emergency("cannot mount tmpfs on %s: %s",
744			    fspath, strerror(errno));
745		}
746		return (error);
747	}
748	return (0);
749}
750
751static state_func_t
752reroot(void)
753{
754	void *buf;
755	size_t bufsize;
756	int error;
757
758	buf = NULL;
759	bufsize = 0;
760
761	revoke_ttys();
762	runshutdown();
763
764	/*
765	 * Make sure nobody can interfere with our scheme.
766	 * Ignore ESRCH, which can apparently happen when
767	 * there are no processes to kill.
768	 */
769	error = kill(-1, SIGKILL);
770	if (error != 0 && errno != ESRCH) {
771		emergency("kill(2) failed: %s", strerror(errno));
772		goto out;
773	}
774
775	/*
776	 * Copy the init binary into tmpfs, so that we can unmount
777	 * the old rootfs without committing suicide.
778	 */
779	error = read_file(init_path_argv0, &buf, &bufsize);
780	if (error != 0)
781		goto out;
782	error = mount_tmpfs(_PATH_REROOT);
783	if (error != 0)
784		goto out;
785	error = create_file(_PATH_REROOT_INIT, buf, bufsize);
786	if (error != 0)
787		goto out;
788
789	/*
790	 * Execute the temporary init.
791	 */
792	execl(_PATH_REROOT_INIT, _PATH_REROOT_INIT, "-r", NULL);
793	emergency("cannot exec %s: %s", _PATH_REROOT_INIT, strerror(errno));
794
795out:
796	emergency("reroot failed; going to single user mode");
797	free(buf);
798	return (state_func_t) single_user;
799}
800
801static state_func_t
802reroot_phase_two(void)
803{
804	char init_path[PATH_MAX], *path, *path_component;
805	size_t init_path_len;
806	int nbytes, error;
807
808	/*
809	 * Ask the kernel to mount the new rootfs.
810	 */
811	error = reboot(RB_REROOT);
812	if (error != 0) {
813		emergency("RB_REBOOT failed: %s", strerror(errno));
814		goto out;
815	}
816
817	/*
818	 * Figure out where the destination init(8) binary is.  Note that
819	 * the path could be different than what we've started with.  Use
820	 * the value from kenv, if set, or the one from sysctl otherwise.
821	 * The latter defaults to a hardcoded value, but can be overridden
822	 * by a build time option.
823	 */
824	nbytes = kenv(KENV_GET, "init_path", init_path, sizeof(init_path));
825	if (nbytes <= 0) {
826		init_path_len = sizeof(init_path);
827		error = sysctlbyname("kern.init_path",
828		    init_path, &init_path_len, NULL, 0);
829		if (error != 0) {
830			emergency("failed to retrieve kern.init_path: %s",
831			    strerror(errno));
832			goto out;
833		}
834	}
835
836	/*
837	 * Repeat the init search logic from sys/kern/init_path.c
838	 */
839	path_component = init_path;
840	while ((path = strsep(&path_component, ":")) != NULL) {
841		/*
842		 * Execute init(8) from the new rootfs.
843		 */
844		execl(path, path, NULL);
845	}
846	emergency("cannot exec init from %s: %s", init_path, strerror(errno));
847
848out:
849	emergency("reroot failed; going to single user mode");
850	return (state_func_t) single_user;
851}
852
853/*
854 * Bring the system up single user.
855 */
856static state_func_t
857single_user(void)
858{
859	pid_t pid, wpid;
860	int status;
861	sigset_t mask;
862	const char *shell;
863	char *argv[2];
864	struct timeval tv, tn;
865#ifdef SECURE
866	struct ttyent *typ;
867	struct passwd *pp;
868	static const char banner[] =
869		"Enter root password, or ^D to go multi-user\n";
870	char *clear, *password;
871#endif
872#ifdef DEBUGSHELL
873	char altshell[128];
874#endif
875
876	if (Reboot) {
877		/* Instead of going single user, let's reboot the machine */
878		sync();
879		if (reboot(howto) == -1) {
880			emergency("reboot(%#x) failed, %s", howto,
881			    strerror(errno));
882			_exit(1); /* panic and reboot */
883		}
884		warning("reboot(%#x) returned", howto);
885		_exit(0); /* panic as well */
886	}
887
888	shell = get_shell();
889
890	if ((pid = fork()) == 0) {
891		/*
892		 * Start the single user session.
893		 */
894		open_console();
895
896#ifdef SECURE
897		/*
898		 * Check the root password.
899		 * We don't care if the console is 'on' by default;
900		 * it's the only tty that can be 'off' and 'secure'.
901		 */
902		typ = getttynam("console");
903		pp = getpwnam("root");
904		if (typ && (typ->ty_status & TTY_SECURE) == 0 &&
905		    pp && *pp->pw_passwd) {
906			write_stderr(banner);
907			for (;;) {
908				clear = getpass("Password:");
909				if (clear == NULL || *clear == '\0')
910					_exit(0);
911				password = crypt(clear, pp->pw_passwd);
912				bzero(clear, _PASSWORD_LEN);
913				if (password == NULL ||
914				    strcmp(password, pp->pw_passwd) == 0)
915					break;
916				warning("single-user login failed\n");
917			}
918		}
919		endttyent();
920		endpwent();
921#endif /* SECURE */
922
923#ifdef DEBUGSHELL
924		{
925			char *cp = altshell;
926			int num;
927
928#define	SHREQUEST "Enter full pathname of shell or RETURN for "
929			write_stderr(SHREQUEST);
930			write_stderr(shell);
931			write_stderr(": ");
932			while ((num = read(STDIN_FILENO, cp, 1)) != -1 &&
933			    num != 0 && *cp != '\n' && cp < &altshell[127])
934				cp++;
935			*cp = '\0';
936			if (altshell[0] != '\0')
937				shell = altshell;
938		}
939#endif /* DEBUGSHELL */
940
941		/*
942		 * Unblock signals.
943		 * We catch all the interesting ones,
944		 * and those are reset to SIG_DFL on exec.
945		 */
946		sigemptyset(&mask);
947		sigprocmask(SIG_SETMASK, &mask, NULL);
948
949		/*
950		 * Fire off a shell.
951		 * If the default one doesn't work, try the Bourne shell.
952		 */
953
954		char name[] = "-sh";
955
956		argv[0] = name;
957		argv[1] = NULL;
958		execv(shell, argv);
959		emergency("can't exec %s for single user: %m", shell);
960		execv(_PATH_BSHELL, argv);
961		emergency("can't exec %s for single user: %m", _PATH_BSHELL);
962		sleep(STALL_TIMEOUT);
963		_exit(1);
964	}
965
966	if (pid == -1) {
967		/*
968		 * We are seriously hosed.  Do our best.
969		 */
970		emergency("can't fork single-user shell, trying again");
971		while (waitpid(-1, (int *) 0, WNOHANG) > 0)
972			continue;
973		return (state_func_t) single_user;
974	}
975
976	requested_transition = 0;
977	do {
978		if ((wpid = waitpid(-1, &status, WUNTRACED)) != -1)
979			collect_child(wpid);
980		if (wpid == -1) {
981			if (errno == EINTR)
982				continue;
983			warning("wait for single-user shell failed: %m; restarting");
984			return (state_func_t) single_user;
985		}
986		if (wpid == pid && WIFSTOPPED(status)) {
987			warning("init: shell stopped, restarting\n");
988			kill(pid, SIGCONT);
989			wpid = -1;
990		}
991	} while (wpid != pid && !requested_transition);
992
993	if (requested_transition)
994		return (state_func_t) requested_transition;
995
996	if (!WIFEXITED(status)) {
997		if (WTERMSIG(status) == SIGKILL) {
998			/*
999			 *  reboot(8) killed shell?
1000			 */
1001			warning("single user shell terminated.");
1002			gettimeofday(&tv, NULL);
1003			tn = tv;
1004			tv.tv_sec += STALL_TIMEOUT;
1005			while (tv.tv_sec > tn.tv_sec || (tv.tv_sec ==
1006			    tn.tv_sec && tv.tv_usec > tn.tv_usec)) {
1007				sleep(1);
1008				gettimeofday(&tn, NULL);
1009			}
1010			_exit(0);
1011		} else {
1012			warning("single user shell terminated, restarting");
1013			return (state_func_t) single_user;
1014		}
1015	}
1016
1017	runcom_mode = FASTBOOT;
1018	return (state_func_t) runcom;
1019}
1020
1021/*
1022 * Run the system startup script.
1023 */
1024static state_func_t
1025runcom(void)
1026{
1027	state_func_t next_transition;
1028
1029	if ((next_transition = run_script(_PATH_RUNCOM)) != NULL)
1030		return next_transition;
1031
1032	runcom_mode = AUTOBOOT;		/* the default */
1033	return (state_func_t) read_ttys;
1034}
1035
1036static void
1037execute_script(char *argv[])
1038{
1039	struct sigaction sa;
1040	const char *shell, *script;
1041	int error;
1042
1043	bzero(&sa, sizeof(sa));
1044	sigemptyset(&sa.sa_mask);
1045	sa.sa_handler = SIG_IGN;
1046	sigaction(SIGTSTP, &sa, NULL);
1047	sigaction(SIGHUP, &sa, NULL);
1048
1049	open_console();
1050
1051	sigprocmask(SIG_SETMASK, &sa.sa_mask, NULL);
1052#ifdef LOGIN_CAP
1053	setprocresources(RESOURCE_RC);
1054#endif
1055
1056	/*
1057	 * Try to directly execute the script first.  If it
1058	 * fails, try the old method of passing the script path
1059	 * to sh(1).  Don't complain if it fails because of
1060	 * the missing execute bit.
1061	 */
1062	script = argv[1];
1063	error = access(script, X_OK);
1064	if (error == 0) {
1065		execv(script, argv + 1);
1066		warning("can't exec %s: %m", script);
1067	} else if (errno != EACCES) {
1068		warning("can't access %s: %m", script);
1069	}
1070
1071	shell = get_shell();
1072	execv(shell, argv);
1073	stall("can't exec %s for %s: %m", shell, script);
1074}
1075
1076/*
1077 * Execute binary, replacing init(8) as PID 1.
1078 */
1079static void
1080replace_init(char *path)
1081{
1082	char *argv[3];
1083	char sh[] = "sh";
1084
1085	argv[0] = sh;
1086	argv[1] = path;
1087	argv[2] = NULL;
1088
1089	execute_script(argv);
1090}
1091
1092/*
1093 * Run a shell script.
1094 * Returns 0 on success, otherwise the next transition to enter:
1095 *  - single_user if fork/execv/waitpid failed, or if the script
1096 *    terminated with a signal or exit code != 0.
1097 *  - death_single if a SIGTERM was delivered to init(8).
1098 */
1099static state_func_t
1100run_script(const char *script)
1101{
1102	pid_t pid, wpid;
1103	int status;
1104	char *argv[4];
1105	const char *shell;
1106
1107	shell = get_shell();
1108
1109	if ((pid = fork()) == 0) {
1110
1111		char _sh[]		= "sh";
1112		char _autoboot[]	= "autoboot";
1113
1114		argv[0] = _sh;
1115		argv[1] = __DECONST(char *, script);
1116		argv[2] = runcom_mode == AUTOBOOT ? _autoboot : 0;
1117		argv[3] = NULL;
1118
1119		execute_script(argv);
1120		sleep(STALL_TIMEOUT);
1121		_exit(1);	/* force single user mode */
1122	}
1123
1124	if (pid == -1) {
1125		emergency("can't fork for %s on %s: %m", shell, script);
1126		while (waitpid(-1, (int *) 0, WNOHANG) > 0)
1127			continue;
1128		sleep(STALL_TIMEOUT);
1129		return (state_func_t) single_user;
1130	}
1131
1132	/*
1133	 * Copied from single_user().  This is a bit paranoid.
1134	 */
1135	requested_transition = 0;
1136	do {
1137		if ((wpid = waitpid(-1, &status, WUNTRACED)) != -1)
1138			collect_child(wpid);
1139		if (wpid == -1) {
1140			if (requested_transition == death_single ||
1141			    requested_transition == reroot)
1142				return (state_func_t) requested_transition;
1143			if (errno == EINTR)
1144				continue;
1145			warning("wait for %s on %s failed: %m; going to "
1146			    "single user mode", shell, script);
1147			return (state_func_t) single_user;
1148		}
1149		if (wpid == pid && WIFSTOPPED(status)) {
1150			warning("init: %s on %s stopped, restarting\n",
1151			    shell, script);
1152			kill(pid, SIGCONT);
1153			wpid = -1;
1154		}
1155	} while (wpid != pid);
1156
1157	if (WIFSIGNALED(status) && WTERMSIG(status) == SIGTERM &&
1158	    requested_transition == catatonia) {
1159		/* /etc/rc executed /sbin/reboot; wait for the end quietly */
1160		sigset_t s;
1161
1162		sigfillset(&s);
1163		for (;;)
1164			sigsuspend(&s);
1165	}
1166
1167	if (!WIFEXITED(status)) {
1168		warning("%s on %s terminated abnormally, going to single "
1169		    "user mode", shell, script);
1170		return (state_func_t) single_user;
1171	}
1172
1173	if (WEXITSTATUS(status))
1174		return (state_func_t) single_user;
1175
1176	return (state_func_t) 0;
1177}
1178
1179/*
1180 * Open the session database.
1181 *
1182 * NB: We could pass in the size here; is it necessary?
1183 */
1184static int
1185start_session_db(void)
1186{
1187	if (session_db && (*session_db->close)(session_db))
1188		emergency("session database close: %s", strerror(errno));
1189	if ((session_db = dbopen(NULL, O_RDWR, 0, DB_HASH, NULL)) == NULL) {
1190		emergency("session database open: %s", strerror(errno));
1191		return (1);
1192	}
1193	return (0);
1194
1195}
1196
1197/*
1198 * Add a new login session.
1199 */
1200static void
1201add_session(session_t *sp)
1202{
1203	DBT key;
1204	DBT data;
1205
1206	key.data = &sp->se_process;
1207	key.size = sizeof sp->se_process;
1208	data.data = &sp;
1209	data.size = sizeof sp;
1210
1211	if ((*session_db->put)(session_db, &key, &data, 0))
1212		emergency("insert %d: %s", sp->se_process, strerror(errno));
1213}
1214
1215/*
1216 * Delete an old login session.
1217 */
1218static void
1219del_session(session_t *sp)
1220{
1221	DBT key;
1222
1223	key.data = &sp->se_process;
1224	key.size = sizeof sp->se_process;
1225
1226	if ((*session_db->del)(session_db, &key, 0))
1227		emergency("delete %d: %s", sp->se_process, strerror(errno));
1228}
1229
1230/*
1231 * Look up a login session by pid.
1232 */
1233static session_t *
1234find_session(pid_t pid)
1235{
1236	DBT key;
1237	DBT data;
1238	session_t *ret;
1239
1240	key.data = &pid;
1241	key.size = sizeof pid;
1242	if ((*session_db->get)(session_db, &key, &data, 0) != 0)
1243		return 0;
1244	bcopy(data.data, (char *)&ret, sizeof(ret));
1245	return ret;
1246}
1247
1248/*
1249 * Construct an argument vector from a command line.
1250 */
1251static char **
1252construct_argv(char *command)
1253{
1254	int argc = 0;
1255	char **argv = (char **) malloc(((strlen(command) + 1) / 2 + 1)
1256						* sizeof (char *));
1257
1258	if ((argv[argc++] = strk(command)) == NULL) {
1259		free(argv);
1260		return (NULL);
1261	}
1262	while ((argv[argc++] = strk((char *) 0)) != NULL)
1263		continue;
1264	return argv;
1265}
1266
1267/*
1268 * Deallocate a session descriptor.
1269 */
1270static void
1271free_session(session_t *sp)
1272{
1273	free(sp->se_device);
1274	if (sp->se_getty) {
1275		free(sp->se_getty);
1276		free(sp->se_getty_argv_space);
1277		free(sp->se_getty_argv);
1278	}
1279	if (sp->se_window) {
1280		free(sp->se_window);
1281		free(sp->se_window_argv_space);
1282		free(sp->se_window_argv);
1283	}
1284	if (sp->se_type)
1285		free(sp->se_type);
1286	free(sp);
1287}
1288
1289/*
1290 * Allocate a new session descriptor.
1291 * Mark it SE_PRESENT.
1292 */
1293static session_t *
1294new_session(session_t *sprev, struct ttyent *typ)
1295{
1296	session_t *sp;
1297
1298	if ((typ->ty_status & TTY_ON) == 0 ||
1299	    typ->ty_name == 0 ||
1300	    typ->ty_getty == 0)
1301		return 0;
1302
1303	sp = (session_t *) calloc(1, sizeof (session_t));
1304
1305	sp->se_flags |= SE_PRESENT;
1306
1307	if ((typ->ty_status & TTY_IFEXISTS) != 0)
1308		sp->se_flags |= SE_IFEXISTS;
1309
1310	if ((typ->ty_status & TTY_IFCONSOLE) != 0)
1311		sp->se_flags |= SE_IFCONSOLE;
1312
1313	if (asprintf(&sp->se_device, "%s%s", _PATH_DEV, typ->ty_name) < 0)
1314		err(1, "asprintf");
1315
1316	if (setupargv(sp, typ) == 0) {
1317		free_session(sp);
1318		return (0);
1319	}
1320
1321	sp->se_next = 0;
1322	if (sprev == NULL) {
1323		sessions = sp;
1324		sp->se_prev = 0;
1325	} else {
1326		sprev->se_next = sp;
1327		sp->se_prev = sprev;
1328	}
1329
1330	return sp;
1331}
1332
1333/*
1334 * Calculate getty and if useful window argv vectors.
1335 */
1336static int
1337setupargv(session_t *sp, struct ttyent *typ)
1338{
1339
1340	if (sp->se_getty) {
1341		free(sp->se_getty);
1342		free(sp->se_getty_argv_space);
1343		free(sp->se_getty_argv);
1344	}
1345	if (asprintf(&sp->se_getty, "%s %s", typ->ty_getty, typ->ty_name) < 0)
1346		err(1, "asprintf");
1347	sp->se_getty_argv_space = strdup(sp->se_getty);
1348	sp->se_getty_argv = construct_argv(sp->se_getty_argv_space);
1349	if (sp->se_getty_argv == NULL) {
1350		warning("can't parse getty for port %s", sp->se_device);
1351		free(sp->se_getty);
1352		free(sp->se_getty_argv_space);
1353		sp->se_getty = sp->se_getty_argv_space = 0;
1354		return (0);
1355	}
1356	if (sp->se_window) {
1357		free(sp->se_window);
1358		free(sp->se_window_argv_space);
1359		free(sp->se_window_argv);
1360	}
1361	sp->se_window = sp->se_window_argv_space = 0;
1362	sp->se_window_argv = 0;
1363	if (typ->ty_window) {
1364		sp->se_window = strdup(typ->ty_window);
1365		sp->se_window_argv_space = strdup(sp->se_window);
1366		sp->se_window_argv = construct_argv(sp->se_window_argv_space);
1367		if (sp->se_window_argv == NULL) {
1368			warning("can't parse window for port %s",
1369			    sp->se_device);
1370			free(sp->se_window_argv_space);
1371			free(sp->se_window);
1372			sp->se_window = sp->se_window_argv_space = 0;
1373			return (0);
1374		}
1375	}
1376	if (sp->se_type)
1377		free(sp->se_type);
1378	sp->se_type = typ->ty_type ? strdup(typ->ty_type) : 0;
1379	return (1);
1380}
1381
1382/*
1383 * Walk the list of ttys and create sessions for each active line.
1384 */
1385static state_func_t
1386read_ttys(void)
1387{
1388	session_t *sp, *snext;
1389	struct ttyent *typ;
1390
1391	/*
1392	 * Destroy any previous session state.
1393	 * There shouldn't be any, but just in case...
1394	 */
1395	for (sp = sessions; sp; sp = snext) {
1396		snext = sp->se_next;
1397		free_session(sp);
1398	}
1399	sessions = 0;
1400	if (start_session_db())
1401		return (state_func_t) single_user;
1402
1403	/*
1404	 * Allocate a session entry for each active port.
1405	 * Note that sp starts at 0.
1406	 */
1407	while ((typ = getttyent()) != NULL)
1408		if ((snext = new_session(sp, typ)) != NULL)
1409			sp = snext;
1410
1411	endttyent();
1412
1413	return (state_func_t) multi_user;
1414}
1415
1416/*
1417 * Start a window system running.
1418 */
1419static void
1420start_window_system(session_t *sp)
1421{
1422	pid_t pid;
1423	sigset_t mask;
1424	char term[64], *env[2];
1425	int status;
1426
1427	if ((pid = fork()) == -1) {
1428		emergency("can't fork for window system on port %s: %m",
1429		    sp->se_device);
1430		/* hope that getty fails and we can try again */
1431		return;
1432	}
1433	if (pid) {
1434		waitpid(-1, &status, 0);
1435		return;
1436	}
1437
1438	/* reparent window process to the init to not make a zombie on exit */
1439	if ((pid = fork()) == -1) {
1440		emergency("can't fork for window system on port %s: %m",
1441		    sp->se_device);
1442		_exit(1);
1443	}
1444	if (pid)
1445		_exit(0);
1446
1447	sigemptyset(&mask);
1448	sigprocmask(SIG_SETMASK, &mask, NULL);
1449
1450	if (setsid() < 0)
1451		emergency("setsid failed (window) %m");
1452
1453#ifdef LOGIN_CAP
1454	setprocresources(RESOURCE_WINDOW);
1455#endif
1456	if (sp->se_type) {
1457		/* Don't use malloc after fork */
1458		strcpy(term, "TERM=");
1459		strlcat(term, sp->se_type, sizeof(term));
1460		env[0] = term;
1461		env[1] = NULL;
1462	}
1463	else
1464		env[0] = NULL;
1465	execve(sp->se_window_argv[0], sp->se_window_argv, env);
1466	stall("can't exec window system '%s' for port %s: %m",
1467		sp->se_window_argv[0], sp->se_device);
1468	_exit(1);
1469}
1470
1471/*
1472 * Start a login session running.
1473 */
1474static pid_t
1475start_getty(session_t *sp)
1476{
1477	pid_t pid;
1478	sigset_t mask;
1479	time_t current_time = time((time_t *) 0);
1480	int too_quick = 0;
1481	char term[64], *env[2];
1482
1483	if (current_time >= sp->se_started &&
1484	    current_time - sp->se_started < GETTY_SPACING) {
1485		if (++sp->se_nspace > GETTY_NSPACE) {
1486			sp->se_nspace = 0;
1487			too_quick = 1;
1488		}
1489	} else
1490		sp->se_nspace = 0;
1491
1492	/*
1493	 * fork(), not vfork() -- we can't afford to block.
1494	 */
1495	if ((pid = fork()) == -1) {
1496		emergency("can't fork for getty on port %s: %m", sp->se_device);
1497		return -1;
1498	}
1499
1500	if (pid)
1501		return pid;
1502
1503	if (too_quick) {
1504		warning("getty repeating too quickly on port %s, sleeping %d secs",
1505		    sp->se_device, GETTY_SLEEP);
1506		sleep((unsigned) GETTY_SLEEP);
1507	}
1508
1509	if (sp->se_window) {
1510		start_window_system(sp);
1511		sleep(WINDOW_WAIT);
1512	}
1513
1514	sigemptyset(&mask);
1515	sigprocmask(SIG_SETMASK, &mask, NULL);
1516
1517#ifdef LOGIN_CAP
1518	setprocresources(RESOURCE_GETTY);
1519#endif
1520	if (sp->se_type) {
1521		/* Don't use malloc after fork */
1522		strcpy(term, "TERM=");
1523		strlcat(term, sp->se_type, sizeof(term));
1524		env[0] = term;
1525		env[1] = NULL;
1526	} else
1527		env[0] = NULL;
1528	execve(sp->se_getty_argv[0], sp->se_getty_argv, env);
1529	stall("can't exec getty '%s' for port %s: %m",
1530		sp->se_getty_argv[0], sp->se_device);
1531	_exit(1);
1532}
1533
1534/*
1535 * Return 1 if the session is defined as "onifexists"
1536 * or "onifconsole" and the device node does not exist.
1537 */
1538static int
1539session_has_no_tty(session_t *sp)
1540{
1541	int fd;
1542
1543	if ((sp->se_flags & SE_IFEXISTS) == 0 &&
1544	    (sp->se_flags & SE_IFCONSOLE) == 0)
1545		return (0);
1546
1547	fd = open(sp->se_device, O_RDONLY | O_NONBLOCK, 0);
1548	if (fd < 0) {
1549		if (errno == ENOENT)
1550			return (1);
1551		return (0);
1552	}
1553
1554	close(fd);
1555	return (0);
1556}
1557
1558/*
1559 * Collect exit status for a child.
1560 * If an exiting login, start a new login running.
1561 */
1562static void
1563collect_child(pid_t pid)
1564{
1565	session_t *sp, *sprev, *snext;
1566
1567	if (! sessions)
1568		return;
1569
1570	if (! (sp = find_session(pid)))
1571		return;
1572
1573	del_session(sp);
1574	sp->se_process = 0;
1575
1576	if (sp->se_flags & SE_SHUTDOWN ||
1577	    session_has_no_tty(sp)) {
1578		if ((sprev = sp->se_prev) != NULL)
1579			sprev->se_next = sp->se_next;
1580		else
1581			sessions = sp->se_next;
1582		if ((snext = sp->se_next) != NULL)
1583			snext->se_prev = sp->se_prev;
1584		free_session(sp);
1585		return;
1586	}
1587
1588	if ((pid = start_getty(sp)) == -1) {
1589		/* serious trouble */
1590		requested_transition = clean_ttys;
1591		return;
1592	}
1593
1594	sp->se_process = pid;
1595	sp->se_started = time((time_t *) 0);
1596	add_session(sp);
1597}
1598
1599/*
1600 * Catch a signal and request a state transition.
1601 */
1602static void
1603transition_handler(int sig)
1604{
1605
1606	switch (sig) {
1607	case SIGHUP:
1608		if (current_state == read_ttys || current_state == multi_user ||
1609		    current_state == clean_ttys || current_state == catatonia)
1610			requested_transition = clean_ttys;
1611		break;
1612	case SIGUSR2:
1613		howto = RB_POWEROFF;
1614	case SIGUSR1:
1615		howto |= RB_HALT;
1616	case SIGINT:
1617		Reboot = TRUE;
1618	case SIGTERM:
1619		if (current_state == read_ttys || current_state == multi_user ||
1620		    current_state == clean_ttys || current_state == catatonia)
1621			requested_transition = death;
1622		else
1623			requested_transition = death_single;
1624		break;
1625	case SIGTSTP:
1626		if (current_state == runcom || current_state == read_ttys ||
1627		    current_state == clean_ttys ||
1628		    current_state == multi_user || current_state == catatonia)
1629			requested_transition = catatonia;
1630		break;
1631	case SIGEMT:
1632		requested_transition = reroot;
1633		break;
1634	default:
1635		requested_transition = 0;
1636		break;
1637	}
1638}
1639
1640/*
1641 * Take the system multiuser.
1642 */
1643static state_func_t
1644multi_user(void)
1645{
1646	pid_t pid;
1647	session_t *sp;
1648
1649	requested_transition = 0;
1650
1651	/*
1652	 * If the administrator has not set the security level to -1
1653	 * to indicate that the kernel should not run multiuser in secure
1654	 * mode, and the run script has not set a higher level of security
1655	 * than level 1, then put the kernel into secure mode.
1656	 */
1657	if (getsecuritylevel() == 0)
1658		setsecuritylevel(1);
1659
1660	for (sp = sessions; sp; sp = sp->se_next) {
1661		if (sp->se_process)
1662			continue;
1663		if (session_has_no_tty(sp))
1664			continue;
1665		if ((pid = start_getty(sp)) == -1) {
1666			/* serious trouble */
1667			requested_transition = clean_ttys;
1668			break;
1669		}
1670		sp->se_process = pid;
1671		sp->se_started = time((time_t *) 0);
1672		add_session(sp);
1673	}
1674
1675	while (!requested_transition)
1676		if ((pid = waitpid(-1, (int *) 0, 0)) != -1)
1677			collect_child(pid);
1678
1679	return (state_func_t) requested_transition;
1680}
1681
1682/*
1683 * This is an (n*2)+(n^2) algorithm.  We hope it isn't run often...
1684 */
1685static state_func_t
1686clean_ttys(void)
1687{
1688	session_t *sp, *sprev;
1689	struct ttyent *typ;
1690	int devlen;
1691	char *old_getty, *old_window, *old_type;
1692
1693	/*
1694	 * mark all sessions for death, (!SE_PRESENT)
1695	 * as we find or create new ones they'll be marked as keepers,
1696	 * we'll later nuke all the ones not found in /etc/ttys
1697	 */
1698	for (sp = sessions; sp != NULL; sp = sp->se_next)
1699		sp->se_flags &= ~SE_PRESENT;
1700
1701	devlen = sizeof(_PATH_DEV) - 1;
1702	while ((typ = getttyent()) != NULL) {
1703		for (sprev = 0, sp = sessions; sp; sprev = sp, sp = sp->se_next)
1704			if (strcmp(typ->ty_name, sp->se_device + devlen) == 0)
1705				break;
1706
1707		if (sp) {
1708			/* we want this one to live */
1709			sp->se_flags |= SE_PRESENT;
1710			if ((typ->ty_status & TTY_ON) == 0 ||
1711			    typ->ty_getty == 0) {
1712				sp->se_flags |= SE_SHUTDOWN;
1713				kill(sp->se_process, SIGHUP);
1714				continue;
1715			}
1716			sp->se_flags &= ~SE_SHUTDOWN;
1717			old_getty = sp->se_getty ? strdup(sp->se_getty) : 0;
1718			old_window = sp->se_window ? strdup(sp->se_window) : 0;
1719			old_type = sp->se_type ? strdup(sp->se_type) : 0;
1720			if (setupargv(sp, typ) == 0) {
1721				warning("can't parse getty for port %s",
1722					sp->se_device);
1723				sp->se_flags |= SE_SHUTDOWN;
1724				kill(sp->se_process, SIGHUP);
1725			}
1726			else if (   !old_getty
1727				 || (!old_type && sp->se_type)
1728				 || (old_type && !sp->se_type)
1729				 || (!old_window && sp->se_window)
1730				 || (old_window && !sp->se_window)
1731				 || (strcmp(old_getty, sp->se_getty) != 0)
1732				 || (old_window && strcmp(old_window, sp->se_window) != 0)
1733				 || (old_type && strcmp(old_type, sp->se_type) != 0)
1734				) {
1735				/* Don't set SE_SHUTDOWN here */
1736				sp->se_nspace = 0;
1737				sp->se_started = 0;
1738				kill(sp->se_process, SIGHUP);
1739			}
1740			if (old_getty)
1741				free(old_getty);
1742			if (old_window)
1743				free(old_window);
1744			if (old_type)
1745				free(old_type);
1746			continue;
1747		}
1748
1749		new_session(sprev, typ);
1750	}
1751
1752	endttyent();
1753
1754	/*
1755	 * sweep through and kill all deleted sessions
1756	 * ones who's /etc/ttys line was deleted (SE_PRESENT unset)
1757	 */
1758	for (sp = sessions; sp != NULL; sp = sp->se_next) {
1759		if ((sp->se_flags & SE_PRESENT) == 0) {
1760			sp->se_flags |= SE_SHUTDOWN;
1761			kill(sp->se_process, SIGHUP);
1762		}
1763	}
1764
1765	return (state_func_t) multi_user;
1766}
1767
1768/*
1769 * Block further logins.
1770 */
1771static state_func_t
1772catatonia(void)
1773{
1774	session_t *sp;
1775
1776	for (sp = sessions; sp; sp = sp->se_next)
1777		sp->se_flags |= SE_SHUTDOWN;
1778
1779	return (state_func_t) multi_user;
1780}
1781
1782/*
1783 * Note SIGALRM.
1784 */
1785static void
1786alrm_handler(int sig)
1787{
1788
1789	(void)sig;
1790	clang = 1;
1791}
1792
1793/*
1794 * Bring the system down to single user.
1795 */
1796static state_func_t
1797death(void)
1798{
1799	int block, blocked;
1800	size_t len;
1801
1802	/* Temporarily block suspend. */
1803	len = sizeof(blocked);
1804	block = 1;
1805	if (sysctlbyname("kern.suspend_blocked", &blocked, &len,
1806	    &block, sizeof(block)) == -1)
1807		blocked = 0;
1808
1809	/*
1810	 * Also revoke the TTY here.  Because runshutdown() may reopen
1811	 * the TTY whose getty we're killing here, there is no guarantee
1812	 * runshutdown() will perform the initial open() call, causing
1813	 * the terminal attributes to be misconfigured.
1814	 */
1815	revoke_ttys();
1816
1817	/* Try to run the rc.shutdown script within a period of time */
1818	runshutdown();
1819
1820	/* Unblock suspend if we blocked it. */
1821	if (!blocked)
1822		sysctlbyname("kern.suspend_blocked", NULL, NULL,
1823		    &blocked, sizeof(blocked));
1824
1825	return (state_func_t) death_single;
1826}
1827
1828/*
1829 * Do what is necessary to reinitialize single user mode or reboot
1830 * from an incomplete state.
1831 */
1832static state_func_t
1833death_single(void)
1834{
1835	int i;
1836	pid_t pid;
1837	static const int death_sigs[2] = { SIGTERM, SIGKILL };
1838
1839	revoke(_PATH_CONSOLE);
1840
1841	for (i = 0; i < 2; ++i) {
1842		if (kill(-1, death_sigs[i]) == -1 && errno == ESRCH)
1843			return (state_func_t) single_user;
1844
1845		clang = 0;
1846		alarm(DEATH_WATCH);
1847		do
1848			if ((pid = waitpid(-1, (int *)0, 0)) != -1)
1849				collect_child(pid);
1850		while (clang == 0 && errno != ECHILD);
1851
1852		if (errno == ECHILD)
1853			return (state_func_t) single_user;
1854	}
1855
1856	warning("some processes would not die; ps axl advised");
1857
1858	return (state_func_t) single_user;
1859}
1860
1861static void
1862revoke_ttys(void)
1863{
1864	session_t *sp;
1865
1866	for (sp = sessions; sp; sp = sp->se_next) {
1867		sp->se_flags |= SE_SHUTDOWN;
1868		kill(sp->se_process, SIGHUP);
1869		revoke(sp->se_device);
1870	}
1871}
1872
1873/*
1874 * Run the system shutdown script.
1875 *
1876 * Exit codes:      XXX I should document more
1877 * -2       shutdown script terminated abnormally
1878 * -1       fatal error - can't run script
1879 * 0        good.
1880 * >0       some error (exit code)
1881 */
1882static int
1883runshutdown(void)
1884{
1885	pid_t pid, wpid;
1886	int status;
1887	int shutdowntimeout;
1888	size_t len;
1889	char *argv[4];
1890	struct stat sb;
1891
1892	/*
1893	 * rc.shutdown is optional, so to prevent any unnecessary
1894	 * complaints from the shell we simply don't run it if the
1895	 * file does not exist. If the stat() here fails for other
1896	 * reasons, we'll let the shell complain.
1897	 */
1898	if (stat(_PATH_RUNDOWN, &sb) == -1 && errno == ENOENT)
1899		return 0;
1900
1901	if ((pid = fork()) == 0) {
1902		char _sh[]	= "sh";
1903		char _reboot[]	= "reboot";
1904		char _single[]	= "single";
1905		char _path_rundown[] = _PATH_RUNDOWN;
1906
1907		argv[0] = _sh;
1908		argv[1] = _path_rundown;
1909		argv[2] = Reboot ? _reboot : _single;
1910		argv[3] = NULL;
1911
1912		execute_script(argv);
1913		_exit(1);	/* force single user mode */
1914	}
1915
1916	if (pid == -1) {
1917		emergency("can't fork for %s: %m", _PATH_RUNDOWN);
1918		while (waitpid(-1, (int *) 0, WNOHANG) > 0)
1919			continue;
1920		sleep(STALL_TIMEOUT);
1921		return -1;
1922	}
1923
1924	len = sizeof(shutdowntimeout);
1925	if (sysctlbyname("kern.init_shutdown_timeout", &shutdowntimeout, &len,
1926	    NULL, 0) == -1 || shutdowntimeout < 2)
1927		shutdowntimeout = DEATH_SCRIPT;
1928	alarm(shutdowntimeout);
1929	clang = 0;
1930	/*
1931	 * Copied from single_user().  This is a bit paranoid.
1932	 * Use the same ALRM handler.
1933	 */
1934	do {
1935		if ((wpid = waitpid(-1, &status, WUNTRACED)) != -1)
1936			collect_child(wpid);
1937		if (clang == 1) {
1938			/* we were waiting for the sub-shell */
1939			kill(wpid, SIGTERM);
1940			warning("timeout expired for %s: %m; going to "
1941			    "single user mode", _PATH_RUNDOWN);
1942			return -1;
1943		}
1944		if (wpid == -1) {
1945			if (errno == EINTR)
1946				continue;
1947			warning("wait for %s failed: %m; going to "
1948			    "single user mode", _PATH_RUNDOWN);
1949			return -1;
1950		}
1951		if (wpid == pid && WIFSTOPPED(status)) {
1952			warning("init: %s stopped, restarting\n",
1953			    _PATH_RUNDOWN);
1954			kill(pid, SIGCONT);
1955			wpid = -1;
1956		}
1957	} while (wpid != pid && !clang);
1958
1959	/* Turn off the alarm */
1960	alarm(0);
1961
1962	if (WIFSIGNALED(status) && WTERMSIG(status) == SIGTERM &&
1963	    requested_transition == catatonia) {
1964		/*
1965		 * /etc/rc.shutdown executed /sbin/reboot;
1966		 * wait for the end quietly
1967		 */
1968		sigset_t s;
1969
1970		sigfillset(&s);
1971		for (;;)
1972			sigsuspend(&s);
1973	}
1974
1975	if (!WIFEXITED(status)) {
1976		warning("%s terminated abnormally, going to "
1977		    "single user mode", _PATH_RUNDOWN);
1978		return -2;
1979	}
1980
1981	if ((status = WEXITSTATUS(status)) != 0)
1982		warning("%s returned status %d", _PATH_RUNDOWN, status);
1983
1984	return status;
1985}
1986
1987static char *
1988strk(char *p)
1989{
1990	static char *t;
1991	char *q;
1992	int c;
1993
1994	if (p)
1995		t = p;
1996	if (!t)
1997		return 0;
1998
1999	c = *t;
2000	while (c == ' ' || c == '\t' )
2001		c = *++t;
2002	if (!c) {
2003		t = 0;
2004		return 0;
2005	}
2006	q = t;
2007	if (c == '\'') {
2008		c = *++t;
2009		q = t;
2010		while (c && c != '\'')
2011			c = *++t;
2012		if (!c)  /* unterminated string */
2013			q = t = 0;
2014		else
2015			*t++ = 0;
2016	} else {
2017		while (c && c != ' ' && c != '\t' )
2018			c = *++t;
2019		*t++ = 0;
2020		if (!c)
2021			t = 0;
2022	}
2023	return q;
2024}
2025
2026#ifdef LOGIN_CAP
2027static void
2028setprocresources(const char *cname)
2029{
2030	login_cap_t *lc;
2031	if ((lc = login_getclassbyname(cname, NULL)) != NULL) {
2032		setusercontext(lc, (struct passwd*)NULL, 0,
2033		    LOGIN_SETPRIORITY | LOGIN_SETRESOURCES |
2034		    LOGIN_SETLOGINCLASS | LOGIN_SETCPUMASK);
2035		login_close(lc);
2036	}
2037}
2038#endif
2039