| @@ -1,14 +1,14 @@ | | | @@ -1,14 +1,14 @@ |
1 | /* $NetBSD: shutdown.c,v 1.54 2011/02/16 19:33:48 wiz Exp $ */ | | 1 | /* $NetBSD: shutdown.c,v 1.55 2011/08/27 18:54:39 joerg Exp $ */ |
2 | | | 2 | |
3 | /* | | 3 | /* |
4 | * Copyright (c) 1988, 1990, 1993 | | 4 | * Copyright (c) 1988, 1990, 1993 |
5 | * The Regents of the University of California. All rights reserved. | | 5 | * The Regents of the University of California. All rights reserved. |
6 | * | | 6 | * |
7 | * Redistribution and use in source and binary forms, with or without | | 7 | * Redistribution and use in source and binary forms, with or without |
8 | * modification, are permitted provided that the following conditions | | 8 | * modification, are permitted provided that the following conditions |
9 | * are met: | | 9 | * are met: |
10 | * 1. Redistributions of source code must retain the above copyright | | 10 | * 1. Redistributions of source code must retain the above copyright |
11 | * notice, this list of conditions and the following disclaimer. | | 11 | * notice, this list of conditions and the following disclaimer. |
12 | * 2. Redistributions in binary form must reproduce the above copyright | | 12 | * 2. Redistributions in binary form must reproduce the above copyright |
13 | * notice, this list of conditions and the following disclaimer in the | | 13 | * notice, this list of conditions and the following disclaimer in the |
14 | * documentation and/or other materials provided with the distribution. | | 14 | * documentation and/or other materials provided with the distribution. |
| @@ -29,27 +29,27 @@ | | | @@ -29,27 +29,27 @@ |
29 | * SUCH DAMAGE. | | 29 | * SUCH DAMAGE. |
30 | */ | | 30 | */ |
31 | | | 31 | |
32 | #include <sys/cdefs.h> | | 32 | #include <sys/cdefs.h> |
33 | #ifndef lint | | 33 | #ifndef lint |
34 | __COPYRIGHT("@(#) Copyright (c) 1988, 1990, 1993\ | | 34 | __COPYRIGHT("@(#) Copyright (c) 1988, 1990, 1993\ |
35 | The Regents of the University of California. All rights reserved."); | | 35 | The Regents of the University of California. All rights reserved."); |
36 | #endif /* not lint */ | | 36 | #endif /* not lint */ |
37 | | | 37 | |
38 | #ifndef lint | | 38 | #ifndef lint |
39 | #if 0 | | 39 | #if 0 |
40 | static char sccsid[] = "@(#)shutdown.c 8.4 (Berkeley) 4/28/95"; | | 40 | static char sccsid[] = "@(#)shutdown.c 8.4 (Berkeley) 4/28/95"; |
41 | #else | | 41 | #else |
42 | __RCSID("$NetBSD: shutdown.c,v 1.54 2011/02/16 19:33:48 wiz Exp $"); | | 42 | __RCSID("$NetBSD: shutdown.c,v 1.55 2011/08/27 18:54:39 joerg Exp $"); |
43 | #endif | | 43 | #endif |
44 | #endif /* not lint */ | | 44 | #endif /* not lint */ |
45 | | | 45 | |
46 | #include <sys/param.h> | | 46 | #include <sys/param.h> |
47 | #include <sys/time.h> | | 47 | #include <sys/time.h> |
48 | #include <sys/resource.h> | | 48 | #include <sys/resource.h> |
49 | #include <sys/syslog.h> | | 49 | #include <sys/syslog.h> |
50 | | | 50 | |
51 | #include <ctype.h> | | 51 | #include <ctype.h> |
52 | #include <err.h> | | 52 | #include <err.h> |
53 | #include <fcntl.h> | | 53 | #include <fcntl.h> |
54 | #include <pwd.h> | | 54 | #include <pwd.h> |
55 | #include <setjmp.h> | | 55 | #include <setjmp.h> |
| @@ -89,32 +89,32 @@ static const struct interval { | | | @@ -89,32 +89,32 @@ static const struct interval { |
89 | | | 89 | |
90 | static time_t offset, shuttime; | | 90 | static time_t offset, shuttime; |
91 | static int dofast, dohalt, doreboot, killflg, nofork, nosync, dodump; | | 91 | static int dofast, dohalt, doreboot, killflg, nofork, nosync, dodump; |
92 | static size_t mbuflen; | | 92 | static size_t mbuflen; |
93 | static int dopowerdown; | | 93 | static int dopowerdown; |
94 | static int dodebug, dosilent, doverbose; | | 94 | static int dodebug, dosilent, doverbose; |
95 | static const char *whom; | | 95 | static const char *whom; |
96 | static char mbuf[BUFSIZ]; | | 96 | static char mbuf[BUFSIZ]; |
97 | static char *bootstr; | | 97 | static char *bootstr; |
98 | | | 98 | |
99 | static void badtime(void) __dead; | | 99 | static void badtime(void) __dead; |
100 | static void die_you_gravy_sucking_pig_dog(void) __dead; | | 100 | static void die_you_gravy_sucking_pig_dog(void) __dead; |
101 | static void doitfast(void); | | 101 | static void doitfast(void); |
102 | void dorcshutdown(void); | | 102 | static void dorcshutdown(void); |
103 | static void finish(int) __dead; | | 103 | static void finish(int) __dead; |
104 | static void getoffset(char *); | | 104 | static void getoffset(char *); |
105 | static void loop(void); | | 105 | static void loop(void) __dead; |
106 | static void nolog(void); | | 106 | static void nolog(void); |
107 | static void timeout(int); | | 107 | static void timeout(int) __dead; |
108 | static void timewarn(time_t); | | 108 | static void timewarn(time_t); |
109 | static void usage(void) __dead; | | 109 | static void usage(void) __dead; |
110 | | | 110 | |
111 | int | | 111 | int |
112 | main(int argc, char *argv[]) | | 112 | main(int argc, char *argv[]) |
113 | { | | 113 | { |
114 | char *p, *endp; | | 114 | char *p, *endp; |
115 | struct passwd *pw; | | 115 | struct passwd *pw; |
116 | size_t arglen, len; | | 116 | size_t arglen, len; |
117 | int ch; | | 117 | int ch; |
118 | | | 118 | |
119 | (void)setprogname(argv[0]); | | 119 | (void)setprogname(argv[0]); |
120 | #ifndef DEBUG | | 120 | #ifndef DEBUG |
| @@ -240,27 +240,27 @@ main(int argc, char *argv[]) | | | @@ -240,27 +240,27 @@ main(int argc, char *argv[]) |
240 | exit(0); | | 240 | exit(0); |
241 | } | | 241 | } |
242 | (void)setsid(); | | 242 | (void)setsid(); |
243 | } | | 243 | } |
244 | #endif | | 244 | #endif |
245 | openlog("shutdown", LOG_CONS, LOG_AUTH); | | 245 | openlog("shutdown", LOG_CONS, LOG_AUTH); |
246 | loop(); | | 246 | loop(); |
247 | /* NOTREACHED */ | | 247 | /* NOTREACHED */ |
248 | #ifdef __GNUC__ | | 248 | #ifdef __GNUC__ |
249 | return 1; | | 249 | return 1; |
250 | #endif | | 250 | #endif |
251 | } | | 251 | } |
252 | | | 252 | |
253 | void | | 253 | static void |
254 | loop(void) | | 254 | loop(void) |
255 | { | | 255 | { |
256 | const struct interval *tp; | | 256 | const struct interval *tp; |
257 | u_int sltime; | | 257 | u_int sltime; |
258 | int logged; | | 258 | int logged; |
259 | | | 259 | |
260 | if (offset <= NOLOG_TIME) { | | 260 | if (offset <= NOLOG_TIME) { |
261 | logged = 1; | | 261 | logged = 1; |
262 | nolog(); | | 262 | nolog(); |
263 | } | | 263 | } |
264 | else | | 264 | else |
265 | logged = 0; | | 265 | logged = 0; |
266 | tp = tlist; | | 266 | tp = tlist; |
| @@ -284,27 +284,27 @@ loop(void) | | | @@ -284,27 +284,27 @@ loop(void) |
284 | if (!logged && tp->timeleft <= NOLOG_TIME) { | | 284 | if (!logged && tp->timeleft <= NOLOG_TIME) { |
285 | logged = 1; | | 285 | logged = 1; |
286 | nolog(); | | 286 | nolog(); |
287 | } | | 287 | } |
288 | (void)sleep((u_int)tp->timetowait); | | 288 | (void)sleep((u_int)tp->timetowait); |
289 | if (!tp->timeleft) | | 289 | if (!tp->timeleft) |
290 | break; | | 290 | break; |
291 | } | | 291 | } |
292 | die_you_gravy_sucking_pig_dog(); | | 292 | die_you_gravy_sucking_pig_dog(); |
293 | } | | 293 | } |
294 | | | 294 | |
295 | static jmp_buf alarmbuf; | | 295 | static jmp_buf alarmbuf; |
296 | | | 296 | |
297 | void | | 297 | static void |
298 | timewarn(time_t timeleft) | | 298 | timewarn(time_t timeleft) |
299 | { | | 299 | { |
300 | static int first; | | 300 | static int first; |
301 | static char hostname[MAXHOSTNAMELEN + 1]; | | 301 | static char hostname[MAXHOSTNAMELEN + 1]; |
302 | FILE *pf; | | 302 | FILE *pf; |
303 | char wcmd[MAXPATHLEN + 4]; | | 303 | char wcmd[MAXPATHLEN + 4]; |
304 | | | 304 | |
305 | if (!first++) { | | 305 | if (!first++) { |
306 | (void)gethostname(hostname, sizeof(hostname)); | | 306 | (void)gethostname(hostname, sizeof(hostname)); |
307 | hostname[sizeof(hostname) - 1] = '\0'; | | 307 | hostname[sizeof(hostname) - 1] = '\0'; |
308 | } | | 308 | } |
309 | | | 309 | |
310 | /* undoc -n option to wall suppresses normal wall banner */ | | 310 | /* undoc -n option to wall suppresses normal wall banner */ |
| @@ -425,27 +425,27 @@ die_you_gravy_sucking_pig_dog(void) | | | @@ -425,27 +425,27 @@ die_you_gravy_sucking_pig_dog(void) |
425 | #endif | | 425 | #endif |
426 | } else { | | 426 | } else { |
427 | #ifndef DEBUG | | 427 | #ifndef DEBUG |
428 | (void)kill(1, SIGTERM); /* to single user */ | | 428 | (void)kill(1, SIGTERM); /* to single user */ |
429 | #else | | 429 | #else |
430 | printf("kill 1\n"); | | 430 | printf("kill 1\n"); |
431 | #endif | | 431 | #endif |
432 | } | | 432 | } |
433 | finish(0); | | 433 | finish(0); |
434 | } | | 434 | } |
435 | | | 435 | |
436 | #define ATOI2(s) ((s) += 2, ((s)[-2] - '0') * 10 + ((s)[-1] - '0')) | | 436 | #define ATOI2(s) ((s) += 2, ((s)[-2] - '0') * 10 + ((s)[-1] - '0')) |
437 | | | 437 | |
438 | void | | 438 | static void |
439 | getoffset(char *timearg) | | 439 | getoffset(char *timearg) |
440 | { | | 440 | { |
441 | struct tm *lt; | | 441 | struct tm *lt; |
442 | char *p; | | 442 | char *p; |
443 | time_t now; | | 443 | time_t now; |
444 | int yearset; | | 444 | int yearset; |
445 | | | 445 | |
446 | (void)time(&now); | | 446 | (void)time(&now); |
447 | if (!strcasecmp(timearg, "now")) { /* now */ | | 447 | if (!strcasecmp(timearg, "now")) { /* now */ |
448 | offset = 0; | | 448 | offset = 0; |
449 | shuttime = now; | | 449 | shuttime = now; |
450 | return; | | 450 | return; |
451 | } | | 451 | } |
| @@ -505,53 +505,53 @@ getoffset(char *timearg) | | | @@ -505,53 +505,53 @@ getoffset(char *timearg) |
505 | case 2: | | 505 | case 2: |
506 | lt->tm_min = ATOI2(timearg); | | 506 | lt->tm_min = ATOI2(timearg); |
507 | break; | | 507 | break; |
508 | default: | | 508 | default: |
509 | badtime(); | | 509 | badtime(); |
510 | } | | 510 | } |
511 | | | 511 | |
512 | if ((shuttime = mktime(lt)) == -1) | | 512 | if ((shuttime = mktime(lt)) == -1) |
513 | badtime(); | | 513 | badtime(); |
514 | if ((offset = shuttime - now) < 0) | | 514 | if ((offset = shuttime - now) < 0) |
515 | errx(1, "time is already past"); | | 515 | errx(1, "time is already past"); |
516 | } | | 516 | } |
517 | | | 517 | |
518 | void | | 518 | static void |
519 | dorcshutdown(void) | | 519 | dorcshutdown(void) |
520 | { | | 520 | { |
521 | (void)printf("\r\nAbout to run shutdown hooks...\r\n"); | | 521 | (void)printf("\r\nAbout to run shutdown hooks...\r\n"); |
522 | #ifndef DEBUG | | 522 | #ifndef DEBUG |
523 | (void)setuid(0); | | 523 | (void)setuid(0); |
524 | (void)system(". " _PATH_RCSHUTDOWN); | | 524 | (void)system(". " _PATH_RCSHUTDOWN); |
525 | #endif | | 525 | #endif |
526 | (void)sleep(5); /* Give operator a chance to abort this. */ | | 526 | (void)sleep(5); /* Give operator a chance to abort this. */ |
527 | (void)printf("\r\nDone running shutdown hooks.\r\n"); | | 527 | (void)printf("\r\nDone running shutdown hooks.\r\n"); |
528 | } | | 528 | } |
529 | | | 529 | |
530 | #define FSMSG "fastboot file for fsck\n" | | 530 | #define FSMSG "fastboot file for fsck\n" |
531 | void | | 531 | static void |
532 | doitfast(void) | | 532 | doitfast(void) |
533 | { | | 533 | { |
534 | int fastfd; | | 534 | int fastfd; |
535 | | | 535 | |
536 | if ((fastfd = open(_PATH_FASTBOOT, O_WRONLY|O_CREAT|O_TRUNC, | | 536 | if ((fastfd = open(_PATH_FASTBOOT, O_WRONLY|O_CREAT|O_TRUNC, |
537 | 0664)) >= 0) { | | 537 | 0664)) >= 0) { |
538 | (void)write(fastfd, FSMSG, sizeof(FSMSG) - 1); | | 538 | (void)write(fastfd, FSMSG, sizeof(FSMSG) - 1); |
539 | (void)close(fastfd); | | 539 | (void)close(fastfd); |
540 | } | | 540 | } |
541 | } | | 541 | } |
542 | | | 542 | |
543 | #define NOMSG "\n\nNO LOGINS: System going down at " | | 543 | #define NOMSG "\n\nNO LOGINS: System going down at " |
544 | void | | 544 | static void |
545 | nolog(void) | | 545 | nolog(void) |
546 | { | | 546 | { |
547 | int logfd; | | 547 | int logfd; |
548 | char *ct; | | 548 | char *ct; |
549 | | | 549 | |
550 | (void)unlink(_PATH_NOLOGIN); /* in case linked to another file */ | | 550 | (void)unlink(_PATH_NOLOGIN); /* in case linked to another file */ |
551 | (void)signal(SIGINT, finish); | | 551 | (void)signal(SIGINT, finish); |
552 | (void)signal(SIGHUP, finish); | | 552 | (void)signal(SIGHUP, finish); |
553 | (void)signal(SIGQUIT, finish); | | 553 | (void)signal(SIGQUIT, finish); |
554 | (void)signal(SIGTERM, finish); | | 554 | (void)signal(SIGTERM, finish); |
555 | if ((logfd = open(_PATH_NOLOGIN, O_WRONLY|O_CREAT|O_TRUNC, | | 555 | if ((logfd = open(_PATH_NOLOGIN, O_WRONLY|O_CREAT|O_TRUNC, |
556 | 0664)) >= 0) { | | 556 | 0664)) >= 0) { |
557 | (void)write(logfd, NOMSG, sizeof(NOMSG) - 1); | | 557 | (void)write(logfd, NOMSG, sizeof(NOMSG) - 1); |