summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorcheloha <cheloha@cvs.openbsd.org>2018-04-07 19:08:14 +0000
committercheloha <cheloha@cvs.openbsd.org>2018-04-07 19:08:14 +0000
commit6832dd9bb97f2bc13d6b87e4920081de4ebb8c42 (patch)
tree7684a73a80cf1fed7d482244d409294e2223f6ca
parent556b2de36e47a2161bf8c211e92a7adca0b31d7d (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.c60
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);
}
}