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