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