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