+ register struct tm *lt;
+ register char *p;
+ time_t now, time();
+
+ if (!strcasecmp(timearg, "now")) { /* now */
+ offset = 0;
+ return;
+ }
+
+ (void)time(&now);
+ if (*timearg == '+') { /* +minutes */
+ if (!isdigit(*++timearg))
+ badtime();
+ offset = atoi(timearg) * 60;
+ shuttime = now + offset;
+ return;
+ }
+
+ /* handle hh:mm by getting rid of the colon */
+ for (p = timearg; *p; ++p)
+ if (!isascii(*p) || !isdigit(*p))
+ if (*p == ':' && strlen(p) == 3) {
+ p[0] = p[1];
+ p[1] = p[2];
+ p[2] = '\0';
+ }
+ else
+ badtime();
+
+ unsetenv("TZ"); /* OUR timezone */
+ lt = localtime(&now); /* current time val */
+
+ switch(strlen(timearg)) {
+ case 10:
+ lt->tm_year = ATOI2(timearg);
+ /* FALLTHROUGH */
+ case 8:
+ lt->tm_mon = ATOI2(timearg);
+ if (--lt->tm_mon < 0 || lt->tm_mon > 11)
+ badtime();
+ /* FALLTHROUGH */
+ case 6:
+ lt->tm_mday = ATOI2(timearg);
+ if (lt->tm_mday < 1 || lt->tm_mday > 31)
+ badtime();
+ /* FALLTHROUGH */
+ case 4:
+ lt->tm_hour = ATOI2(timearg);
+ if (lt->tm_hour < 0 || lt->tm_hour > 23)
+ badtime();
+ lt->tm_min = ATOI2(timearg);
+ if (lt->tm_min < 0 || lt->tm_min > 59)
+ badtime();
+ lt->tm_sec = 0;
+ if ((shuttime = mktime(lt)) == -1)
+ badtime();
+ if ((offset = shuttime - now) < 0) {
+ (void)fprintf(stderr,
+ "shutdown: that time is already past.\n");
+ exit(1);
+ }
+ break;
+ default:
+ badtime();
+ }