xref: /original-bsd/sbin/reboot/halt.c (revision 23c6a147)
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