From wollman@khavrinen.lcs.mit.edu  Fri Nov 30 12:25:15 2001
Return-Path: <wollman@khavrinen.lcs.mit.edu>
Received: from khavrinen.lcs.mit.edu (khavrinen.lcs.mit.edu [18.24.4.193])
	by hub.freebsd.org (Postfix) with ESMTP id 2125337B416
	for <FreeBSD-gnats-submit@freebsd.org>; Fri, 30 Nov 2001 12:25:15 -0800 (PST)
Received: (from wollman@localhost)
	by khavrinen.lcs.mit.edu (8.11.4/8.11.4) id fAUKPEn30087;
	Fri, 30 Nov 2001 15:25:14 -0500 (EST)
	(envelope-from wollman)
Message-Id: <200111302025.fAUKPEn30087@khavrinen.lcs.mit.edu>
Date: Fri, 30 Nov 2001 15:25:14 -0500 (EST)
From: Garrett Wollman <wollman@khavrinen.lcs.mit.edu>
Reply-To: Garrett Wollman <wollman@khavrinen.lcs.mit.edu>
To: FreeBSD-gnats-submit@freebsd.org
Cc:
Subject: shutdown's absolute-time handling could be more useful
X-Send-Pr-Version: 3.113
X-GNATS-Notify:

>Number:         32411
>Category:       bin
>Synopsis:       shutdown(8) absolute-time handling could be more useful
>Confidential:   no
>Severity:       non-critical
>Priority:       low
>Responsible:    freebsd-bugs
>State:          analyzed
>Quarter:        
>Keywords:       
>Date-Required:  
>Class:          change-request
>Submitter-Id:   current-users
>Arrival-Date:   Fri Nov 30 12:30:01 PST 2001
>Closed-Date:    
>Last-Modified:  Wed May 21 21:17:32 UTC 2008
>Originator:     Garrett Wollman
>Release:        FreeBSD 5.0-CURRENT i386
>Organization:
MIT Laboratory for Computer Science
>Environment:
System: FreeBSD khavrinen.lcs.mit.edu 5.0-CURRENT FreeBSD 5.0-CURRENT #607: Thu Jul 26 12:27:11 EDT 2001 root@khavrinen.lcs.mit.edu:/usr/src/sys/i386/compile/KHAVRINEN i386


>Description:
	When an absolute time is specified to shutdown, the program's
	behavior depends on whether that time has passed during the
	current calendar day.  POLA would suggest that for shutdown,
	whose time argument is always supposed to be in the future,
	absolute times specified without a specific date should refer
	to the next occurrence of that time, rather than erroring out
	if that time has already passed during the current day.  (We
	have a mechanism that automatically updates the kernel and
	schedules a reboot for 4 AM, which usually fails because we
	don't normally change kernels between midnight and 3.

>How-To-Repeat:
	shutdown -r 0400

>Fix:

	See the patch below for discussion.  There are other bugs
nearby in the code which this patch does not fix.  (There is also a
meta-bug, in that all the utilities which attempt to parse something
vaguely ISO 8601-like should probably use a common parser rather than
rolling their own.)

Index: shutdown.8
===================================================================
RCS file: /home/cvs/src/sbin/shutdown/shutdown.8,v
retrieving revision 1.17
diff -u -r1.17 shutdown.8
--- shutdown.8	2001/08/09 06:27:32	1.17
+++ shutdown.8	2001/11/30 20:16:12
@@ -118,6 +118,13 @@
 to the current system values.  The first form brings the system down in
 .Ar number
 minutes and the second at the absolute time specified.
+If an absolute time is specified, but not a date,
+and that time today has already passed,
+.Nm
+will assume that the same time tomorrow was meant.
+(If a complete date is specified which has already passed,
+.Nm
+will print an error and exit without shutting the system down.)
 .It Ar warning-message
 Any other arguments comprise the warning message that is broadcast
 to users currently logged into the system.
Index: shutdown.c
===================================================================
RCS file: /home/cvs/src/sbin/shutdown/shutdown.c,v
retrieving revision 1.22
diff -u -r1.22 shutdown.c
--- shutdown.c	2001/07/15 05:46:07	1.22
+++ shutdown.c	2001/11/30 20:10:31
@@ -400,8 +400,9 @@
 	struct tm *lt;
 	char *p;
 	time_t now;
-	int this_year;
+	int this_year, maybe_today;
 
+	maybe_today = 1;
 	(void)time(&now);
 
 	if (!strcasecmp(timearg, "now")) {		/* now */
@@ -454,6 +455,7 @@
 			badtime();
 		/* FALLTHROUGH */
 	case 6:
+		maybe_today = 0;
 		lt->tm_mday = ATOI2(timearg);
 		if (lt->tm_mday < 1 || lt->tm_mday > 31)
 			badtime();
@@ -468,8 +470,24 @@
 		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) {
+			if (!maybe_today)
+				errx(1, "that time is already past.");
+
+			/*
+			 * If the user only gave a time, assume that
+			 * any time earlier than the current time
+			 * was intended to be that time tomorrow.
+			 */
+			lt->tm_mday++;
+			if ((shuttime = mktime(lt)) == -1)
+				badtime();
+			if ((offset = shuttime - now) < 0) {
+				warnx("tomorrow is before today?");
+				abort();
+			}
+		}
 		break;
 	default:
 		badtime();



>Release-Note:
>Audit-Trail:
State-Changed-From-To: open->analyzed 
State-Changed-By: asmodai 
State-Changed-When: Sun Apr 7 06:35:57 PDT 2002 
State-Changed-Why:  
This change makes sense to me.  If I would do something like that with 
absolute times I would mean the next occurence of that time. 

How about committing it Garrett? 

http://www.freebsd.org/cgi/query-pr.cgi?pr=32411 
>Unformatted:
