+ (void)time(&now);
+ if (*timearg == '+') { /* +minutes */
+ if (!isdigit(*++timearg))
+ goto badtime;
+ min = atoi(timearg);
+ offset = min * 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
+ goto badtime;
+
+ unsetenv("TZ"); /* OUR timezone */
+ lt = localtime(&now); /* [yymmdd]hhmm */
+ year = lt->tm_year;
+ month = lt->tm_mon + 1;
+ day = lt->tm_mday;
+
+ switch(strlen(timearg)) {
+ case 10:
+ year = ATOI2(timearg);
+ /* FALLTHROUGH */
+ case 8:
+ month = ATOI2(timearg);
+ /* FALLTHROUGH */
+ case 6:
+ day = ATOI2(timearg);
+ /* FALLTHROUGH */
+ case 4:
+ hour = ATOI2(timearg);
+ min = ATOI2(timearg);
+ if (month < 1 || month > 12 || day < 1 || day > 31 ||
+ hour < 0 || hour > 23 || min < 0 || min > 59)
+ goto badtime;
+ shuttime = 0;
+ year += TM_YEAR_BASE;
+ if (isleap(year) && month > 2)
+ ++shuttime;
+ for (--year; year >= EPOCH_YEAR; --year)
+ shuttime += isleap(year) ?
+ DAYSPERLYEAR : DAYSPERNYEAR;
+ while (--month)
+ shuttime += dmsize[month];
+ shuttime += day - 1;
+ shuttime = HOURSPERDAY * shuttime + hour;
+ shuttime = MINSPERHOUR * shuttime + min;
+ shuttime *= SECSPERMIN;
+ shuttime -= lt->tm_gmtoff;
+ if ((offset = shuttime - now) >= 0)
+ break;
+ /* FALLTHROUGH */
+ default:
+badtime: fprintf(stderr,
+ "shutdown: bad time format, or already past.\n");
+ exit(1);
+ }