diff options
author | cheloha <cheloha@cvs.openbsd.org> | 2018-04-07 19:08:14 +0000 |
---|---|---|
committer | cheloha <cheloha@cvs.openbsd.org> | 2018-04-07 19:08:14 +0000 |
commit | 6832dd9bb97f2bc13d6b87e4920081de4ebb8c42 (patch) | |
tree | 7684a73a80cf1fed7d482244d409294e2223f6ca | |
parent | 556b2de36e47a2161bf8c211e92a7adca0b31d7d (diff) |
Display local timezone in all deadline estimates.
Admins don't necessarily reside in the same timezone as the
machine. If an admin mistakenly schedules downtime for a
machine at the wrong time this could be quite bad.
Users, too, don't necessarily reside in the same timezone as the
machine. Saying the box is going down at "15:40" is potentially
ambiguous.
So, display the local timezone in all logs, broadcasts, printouts,
messages, etc. Give the admin a chance to correct the mistake; give
the user a better idea of when the box is actually going down.
This also updates the process' understanding of the present time
before printing estimates. The system's wall clock could have
changed after the shutdown was scheduled, making subsequent
broadcasts potentially misleading for users.
ok deraadt@
-rw-r--r-- | sbin/shutdown/shutdown.c | 60 |
1 files changed, 34 insertions, 26 deletions
diff --git a/sbin/shutdown/shutdown.c b/sbin/shutdown/shutdown.c index 2d6636182e6..28cf8ff9d77 100644 --- a/sbin/shutdown/shutdown.c +++ b/sbin/shutdown/shutdown.c @@ -1,4 +1,4 @@ -/* $OpenBSD: shutdown.c,v 1.50 2018/03/19 14:51:45 cheloha Exp $ */ +/* $OpenBSD: shutdown.c,v 1.51 2018/04/07 19:08:13 cheloha Exp $ */ /* $NetBSD: shutdown.c,v 1.9 1995/03/18 15:01:09 cgd Exp $ */ /* @@ -98,7 +98,7 @@ void doitfast(void); void __dead finish(int); void getoffset(char *); void __dead loop(void); -void nolog(void); +void nolog(time_t); void timeout(int); void timewarn(time_t); void usage(void); @@ -106,9 +106,11 @@ void usage(void); int main(int argc, char *argv[]) { - int arglen, ch, len, readstdin = 0; - struct passwd *pw; + char when[64]; char *p, *endp; + struct passwd *pw; + struct tm *lt; + int arglen, ch, len, readstdin = 0; pid_t forkpid; if (pledge("stdio rpath wpath cpath getpw tty id proc exec", NULL) == -1) @@ -198,15 +200,16 @@ main(int argc, char *argv[]) } mbuflen = strlen(mbuf); - if (offset) { - char *ct = ctime(&shuttime); - - if (ct) - printf("Shutdown at %.24s.\n", ct); - else + if (offset > 0) { + shuttime = time(NULL) + offset; + lt = localtime(&shuttime); + if (lt != NULL) { + strftime(when, sizeof(when), "%a %b %e %T %Z %Y", lt); + printf("Shutdown at %s.\n", when); + } else printf("Shutdown soon.\n"); } else - (void)printf("Shutdown NOW!\n"); + printf("Shutdown NOW!\n"); if (!(whom = getlogin())) whom = (pw = getpwuid(getuid())) ? pw->pw_name : "???"; @@ -261,7 +264,7 @@ loop(void) broadcast = 1; if (!logged && tlist[i].timeleft <= NOLOG_TIME) { logged = 1; - nolog(); + nolog(tlist[i].timeleft); } timeout.tv_sec = tlist[i].timetowait; timeout.tv_nsec = 0; @@ -279,6 +282,8 @@ void timewarn(time_t timeleft) { static char hostname[HOST_NAME_MAX+1]; + char when[64]; + struct tm *lt; static int first; int fd[2]; pid_t pid, wpid; @@ -317,11 +322,11 @@ timewarn(time_t timeleft) "\007*** %sSystem shutdown message from %s@%s ***\007\n", timeleft ? "": "FINAL ", whom, hostname); - if (timeleft > 10*60) { - struct tm *tm = localtime(&shuttime); - - dprintf(fd[1], "System going down at %d:%02d\n\n", - tm->tm_hour, tm->tm_min); + if (timeleft > 10 * 60) { + shuttime = time(NULL) + timeleft; + lt = localtime(&shuttime); + strftime(when, sizeof(when), "%H:%M %Z", lt); + dprintf(fd[1], "System going down at %s\n\n", when); } else if (timeleft > 59) { dprintf(fd[1], "System going down in %lld minute%s\n\n", (long long)(timeleft / 60), (timeleft > 60) ? "s" : ""); @@ -464,6 +469,7 @@ die_you_gravy_sucking_pig_dog(void) void getoffset(char *timearg) { + char when[64]; const char *errstr; struct tm *lt; int this_year; @@ -475,13 +481,11 @@ getoffset(char *timearg) return; } - (void)time(&now); if (timearg[0] == '+') { /* +minutes */ minutes = strtonum(timearg, 0, INT_MAX, &errstr); if (errstr) errx(1, "relative offset is %s: %s", errstr, timearg); offset = minutes * 60; - shuttime = now + offset; return; } @@ -498,6 +502,7 @@ getoffset(char *timearg) } unsetenv("TZ"); /* OUR timezone */ + time(&now); lt = localtime(&now); /* current time val */ switch (strlen(timearg)) { @@ -534,8 +539,10 @@ getoffset(char *timearg) lt->tm_sec = 0; if ((shuttime = mktime(lt)) == -1) badtime(); - if ((offset = shuttime - now) < 0) - errx(1, "that time is already past."); + if ((offset = shuttime - now) < 0) { + strftime(when, sizeof(when), "%a %b %e %T %Z %Y", lt); + errx(1, "time is already past: %s", when); + } break; default: badtime(); @@ -555,22 +562,23 @@ doitfast(void) } void -nolog(void) +nolog(time_t timeleft) { - int logfd; + char when[64]; struct tm *tm; + int logfd; (void)unlink(_PATH_NOLOGIN); /* in case linked to another file */ (void)signal(SIGINT, finish); (void)signal(SIGHUP, finish); (void)signal(SIGQUIT, finish); (void)signal(SIGTERM, finish); + shuttime = time(NULL) + timeleft; tm = localtime(&shuttime); if (tm && (logfd = open(_PATH_NOLOGIN, O_WRONLY|O_CREAT|O_TRUNC, 0664)) >= 0) { - dprintf(logfd, - "\n\nNO LOGINS: System going down at %d:%02d\n\n", - tm->tm_hour, tm->tm_min); + strftime(when, sizeof(when), "at %H:%M %Z", tm); + dprintf(logfd, "\n\nNO LOGINS: System going down %s\n\n", when); close(logfd); } } |