xref: /original-bsd/sbin/reboot/halt.c (revision 4ec22e22)
1 /*
2  * Copyright (c) 1980, 1986 The Regents of the University of California.
3  * All rights reserved.
4  *
5  * %sccs.include.redist.c%
6  */
7 
8 #ifndef lint
9 char copyright[] =
10 "@(#) Copyright (c) 1980, 1986 The Regents of the University of California.\n\
11  All rights reserved.\n";
12 #endif /* not lint */
13 
14 #ifndef lint
15 static char sccsid[] = "@(#)halt.c	5.7 (Berkeley) 06/01/90";
16 #endif /* not lint */
17 
18 /*
19  * Halt
20  */
21 #include <sys/types.h>
22 #include <sys/reboot.h>
23 #include <sys/time.h>
24 #include <sys/syslog.h>
25 #include <sys/signal.h>
26 #include <errno.h>
27 #include <pwd.h>
28 #include <stdio.h>
29 #include <paths.h>
30 
31 main(argc, argv)
32 	int argc;
33 	char **argv;
34 {
35 	register int i;
36 	register int qflag = 0;
37 	struct passwd *pw, *getpwuid();
38 	int ch, howto, needlog = 1;
39 	char *user, *ttyn, *getlogin(), *ttyname();
40 
41 	howto = RB_HALT;
42 	ttyn = ttyname(2);
43 	while ((ch = getopt(argc, argv, "lnqy")) != EOF)
44 		switch((char)ch) {
45 		case 'l':		/* undocumented; for shutdown(8) */
46 			needlog = 0;
47 			break;
48 		case 'n':
49 			howto |= RB_NOSYNC;
50 			break;
51 		case 'q':
52 			qflag++;
53 			break;
54 		case 'y':
55 			ttyn = 0;
56 			break;
57 		case '?':
58 		default:
59 			fprintf(stderr, "usage: halt [-nqy]\n");
60 			exit(1);
61 		}
62 
63 	if (ttyn && ttyn[sizeof(_PATH_TTY) - 1] == 'd') {
64 		fprintf(stderr, "halt: dangerous on a dialup; use ``halt -y'' if you are really sure\n");
65 		exit(1);
66 	}
67 
68 	if (needlog) {
69 		openlog("halt", 0, LOG_AUTH);
70 		if ((user = getlogin()) == NULL)
71 			if ((pw = getpwuid(getuid())))
72 				user = pw->pw_name;
73 			else
74 				user = "???";
75 		syslog(LOG_CRIT, "halted by %s", user);
76 	}
77 
78 	signal(SIGHUP, SIG_IGN);		/* for network connections */
79 	if (kill(1, SIGTSTP) == -1) {
80 		fprintf(stderr, "halt: can't idle init\n");
81 		exit(1);
82 	}
83 	sleep(1);
84 	(void) kill(-1, SIGTERM);	/* one chance to catch it */
85 	sleep(5);
86 
87 	if (!qflag) for (i = 1; ; i++) {
88 		if (kill(-1, SIGKILL) == -1) {
89 			extern int errno;
90 
91 			if (errno == ESRCH)
92 				break;
93 
94 			perror("halt: kill");
95 			kill(1, SIGHUP);
96 			exit(1);
97 		}
98 		if (i > 5) {
99 			fprintf(stderr,
100 			    "CAUTION: some process(es) wouldn't die\n");
101 			break;
102 		}
103 		setalarm(2 * i);
104 		pause();
105 	}
106 
107 	if (!qflag && (howto & RB_NOSYNC) == 0) {
108 		logwtmp("~", "shutdown", "");
109 		sync();
110 		setalarm(5);
111 		pause();
112 	}
113 	syscall(55, howto);
114 	perror("halt");
115 }
116 
117 dingdong()
118 {
119 	/* RRRIIINNNGGG RRRIIINNNGGG */
120 }
121 
122 setalarm(n)
123 {
124 	signal(SIGALRM, dingdong);
125 	alarm(n);
126 }
127