xref: /csrg-svn/sbin/reboot/halt.c (revision 28801)
1 /*
2  * Copyright (c) 1980,1986 Regents of the University of California.
3  * All rights reserved.  The Berkeley software License Agreement
4  * specifies the terms and conditions for redistribution.
5  */
6 
7 #ifndef lint
8 char copyright[] =
9 "@(#) Copyright (c) 1980,1986 Regents of the University of California.\n\
10  All rights reserved.\n";
11 #endif not lint
12 
13 #ifndef lint
14 static char sccsid[] = "@(#)halt.c	5.4 (Berkeley) 05/26/86";
15 #endif not lint
16 
17 /*
18  * Halt
19  */
20 #include <stdio.h>
21 #include <sys/reboot.h>
22 #include <sys/types.h>
23 #include <sys/time.h>
24 #include <sys/syslog.h>
25 #include <errno.h>
26 #include <signal.h>
27 #include <pwd.h>
28 
29 main(argc, argv)
30 	int argc;
31 	char **argv;
32 {
33 	int howto;
34 	char *ttyn = (char *)ttyname(2);
35 	register i;
36 	register qflag = 0;
37 	int needlog = 1;
38 	char *user, *getlogin();
39 	struct passwd *pw, *getpwuid();
40 
41 	openlog("halt", 0, LOG_AUTH);
42 	howto = RB_HALT;
43 	argc--, argv++;
44 	while (argc > 0) {
45 		if (!strcmp(*argv, "-n"))
46 			howto |= RB_NOSYNC;
47 		else if (!strcmp(*argv, "-y"))
48 			ttyn = 0;
49 		else if (!strcmp(*argv, "-q"))
50 			qflag++;
51 		else if (!strcmp(*argv, "-l"))
52 			needlog = 0;
53 		else {
54 			fprintf(stderr, "usage: halt [ -n ]\n");
55 			exit(1);
56 		}
57 		argc--, argv++;
58 	}
59 	if (ttyn && *(ttyn+strlen("/dev/tty")) == 'd') {
60 		fprintf(stderr, "halt: dangerous on a dialup; use ``halt -y'' if you are really sure\n");
61 		exit(1);
62 	}
63 
64 	if (needlog) {
65 		user = getlogin();
66 		if (user == (char *)0 && (pw = getpwuid(getuid())))
67 			user = pw->pw_name;
68 		if (user == (char *)0)
69 			user = "root";
70 		syslog(LOG_CRIT, "halted by %s", user);
71 	}
72 
73 	signal(SIGHUP, SIG_IGN);		/* for network connections */
74 	if (kill(1, SIGTSTP) == -1) {
75 		fprintf(stderr, "reboot: can't idle init\n");
76 		exit(1);
77 	}
78 	sleep(1);
79 	(void) kill(-1, SIGTERM);	/* one chance to catch it */
80 	sleep(5);
81 
82 	if (!qflag) for (i = 1; ; i++) {
83 		if (kill(-1, SIGKILL) == -1) {
84 			extern int errno;
85 
86 			if (errno == ESRCH)
87 				break;
88 
89 			perror("reboot: kill");
90 			kill(1, SIGHUP);
91 			exit(1);
92 		}
93 		if (i > 5) {
94 			fprintf(stderr,
95 			    "CAUTION: some process(es) wouldn't die\n");
96 			break;
97 		}
98 		setalarm(2 * i);
99 		pause();
100 	}
101 
102 	if (!qflag && (howto & RB_NOSYNC) == 0) {
103 		markdown();
104 		sync();
105 		setalarm(5);
106 		pause();
107 	}
108 	syscall(55, howto);
109 	perror("reboot");
110 }
111 
112 dingdong()
113 {
114 	/* RRRIIINNNGGG RRRIIINNNGGG */
115 }
116 
117 setalarm(n)
118 {
119 	signal(SIGALRM, dingdong);
120 	alarm(n);
121 }
122 
123 #include <utmp.h>
124 #define SCPYN(a, b)	strncpy(a, b, sizeof(a))
125 char	wtmpf[]	= "/usr/adm/wtmp";
126 struct utmp wtmp;
127 
128 markdown()
129 {
130 	register f = open(wtmpf, 1);
131 	if (f >= 0) {
132 		lseek(f, 0L, 2);
133 		SCPYN(wtmp.ut_line, "~");
134 		SCPYN(wtmp.ut_name, "shutdown");
135 		SCPYN(wtmp.ut_host, "");
136 		time(&wtmp.ut_time);
137 		write(f, (char *)&wtmp, sizeof(wtmp));
138 		close(f);
139 	}
140 }
141