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.5 (Berkeley) 09/20/88"; 26 #endif /* not lint */ 27 28 /* 29 * Halt 30 */ 31 #include <stdio.h> 32 #include <sys/reboot.h> 33 #include <sys/types.h> 34 #include <sys/time.h> 35 #include <sys/syslog.h> 36 #include <errno.h> 37 #include <signal.h> 38 #include <pwd.h> 39 40 main(argc, argv) 41 int argc; 42 char **argv; 43 { 44 register int i; 45 register int qflag = 0; 46 struct passwd *pw, *getpwuid(); 47 int ch, howto, needlog = 1; 48 char *user, *ttyn, *getlogin(), *ttyname(); 49 50 howto = RB_HALT; 51 ttyn = ttyname(2); 52 while ((ch = getopt(argc, argv, "lnqy")) != EOF) 53 switch((char)ch) { 54 case 'l': /* undocumented; for shutdown(8) */ 55 needlog = 0; 56 break; 57 case 'n': 58 howto |= RB_NOSYNC; 59 break; 60 case 'q': 61 qflag++; 62 break; 63 case 'y': 64 ttyn = 0; 65 break; 66 case '?': 67 default: 68 fprintf(stderr, "usage: halt [-nqy]\n"); 69 exit(1); 70 } 71 72 if (ttyn && *(ttyn+strlen("/dev/tty")) == 'd') { 73 fprintf(stderr, "halt: dangerous on a dialup; use ``halt -y'' if you are really sure\n"); 74 exit(1); 75 } 76 77 if (needlog) { 78 openlog("halt", 0, LOG_AUTH); 79 if ((user = getlogin()) == NULL) 80 if ((pw = getpwuid(getuid()))) 81 user = pw->pw_name; 82 else 83 user = "???"; 84 syslog(LOG_CRIT, "halted by %s", user); 85 } 86 87 signal(SIGHUP, SIG_IGN); /* for network connections */ 88 if (kill(1, SIGTSTP) == -1) { 89 fprintf(stderr, "halt: can't idle init\n"); 90 exit(1); 91 } 92 sleep(1); 93 (void) kill(-1, SIGTERM); /* one chance to catch it */ 94 sleep(5); 95 96 if (!qflag) for (i = 1; ; i++) { 97 if (kill(-1, SIGKILL) == -1) { 98 extern int errno; 99 100 if (errno == ESRCH) 101 break; 102 103 perror("halt: kill"); 104 kill(1, SIGHUP); 105 exit(1); 106 } 107 if (i > 5) { 108 fprintf(stderr, 109 "CAUTION: some process(es) wouldn't die\n"); 110 break; 111 } 112 setalarm(2 * i); 113 pause(); 114 } 115 116 if (!qflag && (howto & RB_NOSYNC) == 0) { 117 logwtmp("~", "shutdown", ""); 118 sync(); 119 setalarm(5); 120 pause(); 121 } 122 syscall(55, howto); 123 perror("halt"); 124 } 125 126 dingdong() 127 { 128 /* RRRIIINNNGGG RRRIIINNNGGG */ 129 } 130 131 setalarm(n) 132 { 133 signal(SIGALRM, dingdong); 134 alarm(n); 135 } 136