1 /* 2 * Copyright (c) 1980, 1986 The Regents of the University of California. 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms are permitted 6 * provided that the above copyright notice and this paragraph are 7 * duplicated in all such forms and that any documentation, 8 * advertising materials, and other materials related to such 9 * distribution and use acknowledge that the software was developed 10 * by the University of California, Berkeley. The name of the 11 * University may not be used to endorse or promote products derived 12 * from this software without specific prior written permission. 13 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR 14 * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED 15 * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. 16 */ 17 18 #ifndef lint 19 char copyright[] = 20 "@(#) Copyright (c) 1980, 1986 The Regents of the University of California.\n\ 21 All rights reserved.\n"; 22 #endif /* not lint */ 23 24 #ifndef lint 25 static char sccsid[] = "@(#)halt.c 5.6 (Berkeley) 05/11/89"; 26 #endif /* not lint */ 27 28 /* 29 * Halt 30 */ 31 #include <sys/types.h> 32 #include <sys/reboot.h> 33 #include <sys/time.h> 34 #include <sys/syslog.h> 35 #include <sys/signal.h> 36 #include <errno.h> 37 #include <pwd.h> 38 #include <stdio.h> 39 #include <paths.h> 40 41 main(argc, argv) 42 int argc; 43 char **argv; 44 { 45 register int i; 46 register int qflag = 0; 47 struct passwd *pw, *getpwuid(); 48 int ch, howto, needlog = 1; 49 char *user, *ttyn, *getlogin(), *ttyname(); 50 51 howto = RB_HALT; 52 ttyn = ttyname(2); 53 while ((ch = getopt(argc, argv, "lnqy")) != EOF) 54 switch((char)ch) { 55 case 'l': /* undocumented; for shutdown(8) */ 56 needlog = 0; 57 break; 58 case 'n': 59 howto |= RB_NOSYNC; 60 break; 61 case 'q': 62 qflag++; 63 break; 64 case 'y': 65 ttyn = 0; 66 break; 67 case '?': 68 default: 69 fprintf(stderr, "usage: halt [-nqy]\n"); 70 exit(1); 71 } 72 73 if (ttyn && ttyn[sizeof(_PATH_TTY) - 1] == 'd') { 74 fprintf(stderr, "halt: dangerous on a dialup; use ``halt -y'' if you are really sure\n"); 75 exit(1); 76 } 77 78 if (needlog) { 79 openlog("halt", 0, LOG_AUTH); 80 if ((user = getlogin()) == NULL) 81 if ((pw = getpwuid(getuid()))) 82 user = pw->pw_name; 83 else 84 user = "???"; 85 syslog(LOG_CRIT, "halted by %s", user); 86 } 87 88 signal(SIGHUP, SIG_IGN); /* for network connections */ 89 if (kill(1, SIGTSTP) == -1) { 90 fprintf(stderr, "halt: can't idle init\n"); 91 exit(1); 92 } 93 sleep(1); 94 (void) kill(-1, SIGTERM); /* one chance to catch it */ 95 sleep(5); 96 97 if (!qflag) for (i = 1; ; i++) { 98 if (kill(-1, SIGKILL) == -1) { 99 extern int errno; 100 101 if (errno == ESRCH) 102 break; 103 104 perror("halt: kill"); 105 kill(1, SIGHUP); 106 exit(1); 107 } 108 if (i > 5) { 109 fprintf(stderr, 110 "CAUTION: some process(es) wouldn't die\n"); 111 break; 112 } 113 setalarm(2 * i); 114 pause(); 115 } 116 117 if (!qflag && (howto & RB_NOSYNC) == 0) { 118 logwtmp("~", "shutdown", ""); 119 sync(); 120 setalarm(5); 121 pause(); 122 } 123 syscall(55, howto); 124 perror("halt"); 125 } 126 127 dingdong() 128 { 129 /* RRRIIINNNGGG RRRIIINNNGGG */ 130 } 131 132 setalarm(n) 133 { 134 signal(SIGALRM, dingdong); 135 alarm(n); 136 } 137