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