void stime_arg2(char *arg, int year, struct timeval *tvp) { time_t now; struct tm *t; /* Start with the current time. */ now = tvp[0].tv_sec; if ((t = localtime(&now)) == NULL) err(1, "localtime"); t->tm_mon = ATOI2(arg); /* MMDDhhmm[yy] */ --t->tm_mon; /* Convert from 01-12 to 00-11 */ t->tm_mday = ATOI2(arg); t->tm_hour = ATOI2(arg); t->tm_min = ATOI2(arg); if (year) { t->tm_year = ATOI2(arg); if (t->tm_year < 39) /* support 2000-2038 not 1902-1969 */ t->tm_year += 100; } t->tm_isdst = -1; /* Figure out DST. */ tvp[0].tv_sec = tvp[1].tv_sec = mktime(t); if (tvp[0].tv_sec == -1) errx(1, "out of range or illegal time specification: MMDDhhmm[yy]"); tvp[0].tv_usec = tvp[1].tv_usec = 0; }
/* Calculate a time offset in seconds, given an arg of the format [-]HHMMSS. */ int timeoffset(char *arg) { int offset; int isneg; offset = 0; isneg = *arg == '-'; if (isneg) arg++; switch (strlen(arg)) { default: /* invalid */ errx(1, "Invalid offset spec, must be [-][[HH]MM]SS"); case 6: /* HHMMSS */ offset = ATOI2(arg); /* FALLTHROUGH */ case 4: /* MMSS */ offset = offset * 60 + ATOI2(arg); /* FALLTHROUGH */ case 2: /* SS */ offset = offset * 60 + ATOI2(arg); } if (isneg) return (-offset); else return (offset); }
static void stime_arg2(char *arg, int year, struct timeval *tvp) { struct tm *t; time_t tmptime; /* Start with the current time. */ tmptime = tvp[0].tv_sec; if ((t = localtime(&tmptime)) == NULL) err(EXIT_FAILURE, "localtime"); t->tm_mon = ATOI2(arg); /* MMDDhhmm[yy] */ --t->tm_mon; /* Convert from 01-12 to 00-11 */ t->tm_mday = ATOI2(arg); t->tm_hour = ATOI2(arg); t->tm_min = ATOI2(arg); if (year) { year = ATOI2(arg); if (year < 69) t->tm_year = year + 2000 - TM_YEAR_BASE; else t->tm_year = year + 1900 - TM_YEAR_BASE; } t->tm_sec = 0; t->tm_isdst = -1; /* Figure out DST. */ tvp[0].tv_sec = tvp[1].tv_sec = mktime(t); if (tvp[0].tv_sec == -1) errx(EXIT_FAILURE, "out of range or illegal time specification: MMDDhhmm[yy]"); tvp[0].tv_usec = tvp[1].tv_usec = 0; }
void stime_arg1(char *arg, struct timeval *tvp) { time_t now; struct tm *t; int yearset; char *p; /* Start with the current time. */ now = tvp[0].tv_sec; if ((t = localtime(&now)) == NULL) err(1, "localtime"); /* [[CC]YY]MMDDhhmm[.SS] */ if ((p = strchr(arg, '.')) == NULL) t->tm_sec = 0; /* Seconds defaults to 0. */ else { if (strlen(p + 1) != 2) goto terr; *p++ = '\0'; t->tm_sec = ATOI2(p); } yearset = 0; switch(strlen(arg)) { case 12: /* CCYYMMDDhhmm */ t->tm_year = ATOI2(arg); t->tm_year *= 100; yearset = 1; /* FALLTHROUGH */ case 10: /* YYMMDDhhmm */ if (yearset) { yearset = ATOI2(arg); t->tm_year += yearset; } else { yearset = ATOI2(arg); if (yearset < 69) t->tm_year = yearset + 2000; else t->tm_year = yearset + 1900; } t->tm_year -= 1900; /* Convert to UNIX time. */ /* FALLTHROUGH */ case 8: /* MMDDhhmm */ t->tm_mon = ATOI2(arg); --t->tm_mon; /* Convert from 01-12 to 00-11 */ t->tm_mday = ATOI2(arg); t->tm_hour = ATOI2(arg); t->tm_min = ATOI2(arg); break; default: goto terr; } t->tm_isdst = -1; /* Figure out DST. */ tvp[0].tv_sec = tvp[1].tv_sec = mktime(t); if (tvp[0].tv_sec == -1) terr: errx(1, "out of range or illegal time specification: [[CC]YY]MMDDhhmm[.SS]"); tvp[0].tv_usec = tvp[1].tv_usec = 0; }
static void getmmdd(struct tm *ptm, char *ds) { bool ok = false; struct tm ttm; ttm = *ptm; ttm.tm_isdst = -1; if (ISDIG2(ds)) { ttm.tm_mon = ATOI2(ds) - 1; ds += 2; } if (ISDIG2(ds)) { ttm.tm_mday = ATOI2(ds); ds += 2; ok = true; } if (ok) { if (ISDIG2(ds) && ISDIG2(ds + 2)) { ttm.tm_year = ATOI2(ds) * 100 - TM_YEAR_BASE; ds += 2; ttm.tm_year += ATOI2(ds); } else if (ISDIG2(ds)) { ttm.tm_year = ATOI2(ds); if (ttm.tm_year < 69) ttm.tm_year += 2000 - TM_YEAR_BASE; else ttm.tm_year += 1900 - TM_YEAR_BASE; } } if (ok && mktime(&ttm) == -1) ok = false; if (ok) *ptm = ttm; else { warnx("Can't convert `%s' to date, ignored.", ds); usage(); } }
void stime_arg2(char *arg, int year, struct timespec *tsp) { struct tm *lt; time_t tmptime; /* Start with the current time. */ tmptime = time(NULL); if ((lt = localtime(&tmptime)) == NULL) err(1, "localtime"); lt->tm_mon = ATOI2(arg); /* MMDDhhmm[YY] */ if (lt->tm_mon > 12 || lt->tm_mon == 0) goto terr; --lt->tm_mon; /* Convert from 01-12 to 00-11 */ lt->tm_mday = ATOI2(arg); if (lt->tm_mday > 31 || lt->tm_mday == 0) goto terr; lt->tm_hour = ATOI2(arg); if (lt->tm_hour > 23) goto terr; lt->tm_min = ATOI2(arg); if (lt->tm_min > 59) goto terr; if (year) { year = ATOI2(arg); /* POSIX logic: [00,68]=>20xx, [69,99]=>19xx */ lt->tm_year = year; if (year < 69) lt->tm_year += 100; } lt->tm_sec = 0; lt->tm_isdst = -1; /* Figure out DST. */ tsp[0].tv_sec = tsp[1].tv_sec = mktime(lt); if (tsp[0].tv_sec == -1) terr: errx(1, "out of range or illegal time specification: MMDDhhmm[YY]"); tsp[0].tv_nsec = tsp[1].tv_nsec = 0; }
static time_t parsetime(char *p) { struct tm *lt; int bigyear; int yearset = 0; time_t tval; char *t; for (t = p; *t; ++t) { if (isdigit((unsigned char) *t)) continue; badformat(); } tval = time(NULL); lt = localtime(&tval); lt->tm_sec = 0; lt->tm_min = 0; switch (strlen(p)) { case 10: /* yyyy */ bigyear = ATOI2(p); lt->tm_year = bigyear * 100 - 1900; yearset = 1; /* FALLTHROUGH */ case 8: /* yy */ if (yearset) { lt->tm_year += ATOI2(p); } else { lt->tm_year = ATOI2(p); if (lt->tm_year < 69) /* hack for 2000 */ lt->tm_year += 100; } /* FALLTHROUGH */ case 6: /* mm */ lt->tm_mon = ATOI2(p); if ((lt->tm_mon > 12) || !lt->tm_mon) badformat(); --lt->tm_mon; /* time struct is 0 - 11 */ /* FALLTHROUGH */ case 4: /* dd */ lt->tm_mday = ATOI2(p); if ((lt->tm_mday > 31) || !lt->tm_mday) badformat(); /* FALLTHROUGH */ case 2: /* HH */ lt->tm_hour = ATOI2(p); if (lt->tm_hour > 23) badformat(); break; default: badformat(); } /* The calling code needs a valid tm_ydays and this is the easiest * way to get one */ if ((tval = mktime(lt)) == -1) errx(1, "specified date is outside allowed range"); return (tval); }
static void getoffset(char *timearg) { struct tm *lt; char *p; time_t now; int this_year; (void)time(&now); if (!strcasecmp(timearg, "now")) { /* now */ offset = 0; shuttime = now; return; } if (*timearg == '+') { /* +minutes */ if (!isdigit(*++timearg)) badtime(); if ((offset = atoi(timearg) * 60) < 0) badtime(); 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: this_year = lt->tm_year; lt->tm_year = ATOI2(timearg); /* * check if the specified year is in the next century. * allow for one year of user error as many people will * enter n - 1 at the start of year n. */ if (lt->tm_year < (this_year % 100) - 1) lt->tm_year += 100; /* adjust for the year 2000 and beyond */ lt->tm_year += (this_year - (this_year % 100)); /* 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) errx(1, "that time is already past."); break; default: badtime(); } }
static void setthetime(const char *fmt, const char *p, int jflag, int nflag) { struct utmpx utx; struct tm *lt; struct timeval tv; const char *dot, *t; int century; lt = localtime(&tval); lt->tm_isdst = -1; /* divine correct DST */ if (fmt != NULL) { t = strptime(p, fmt, lt); if (t == NULL) { fprintf(stderr, "Failed conversion of ``%s''" " using format ``%s''\n", p, fmt); badformat(); } else if (*t != '\0') fprintf(stderr, "Warning: Ignoring %ld extraneous" " characters in date string (%s)\n", (long) strlen(t), t); } else { for (t = p, dot = NULL; *t; ++t) { if (isdigit(*t)) continue; if (*t == '.' && dot == NULL) { dot = t; continue; } badformat(); } if (dot != NULL) { /* .ss */ dot++; /* *dot++ = '\0'; */ if (strlen(dot) != 2) badformat(); lt->tm_sec = ATOI2(dot); if (lt->tm_sec > 61) badformat(); } else lt->tm_sec = 0; century = 0; /* if p has a ".ss" field then let's pretend it's not there */ switch (strlen(p) - ((dot != NULL) ? 3 : 0)) { case 12: /* cc */ lt->tm_year = ATOI2(p) * 100 - TM_YEAR_BASE; century = 1; /* FALLTHROUGH */ case 10: /* yy */ if (century) lt->tm_year += ATOI2(p); else { lt->tm_year = ATOI2(p); if (lt->tm_year < 69) /* hack for 2000 ;-} */ lt->tm_year += 2000 - TM_YEAR_BASE; else lt->tm_year += 1900 - TM_YEAR_BASE; } /* FALLTHROUGH */ case 8: /* mm */ lt->tm_mon = ATOI2(p); if (lt->tm_mon > 12) badformat(); --lt->tm_mon; /* time struct is 0 - 11 */ /* FALLTHROUGH */ case 6: /* dd */ lt->tm_mday = ATOI2(p); if (lt->tm_mday > 31) badformat(); /* FALLTHROUGH */ case 4: /* HH */ lt->tm_hour = ATOI2(p); if (lt->tm_hour > 23) badformat(); /* FALLTHROUGH */ case 2: /* MM */ lt->tm_min = ATOI2(p); if (lt->tm_min > 59) badformat(); break; default: badformat(); } } /* convert broken-down time to GMT clock time */ if ((tval = mktime(lt)) == -1) errx(1, "nonexistent time"); if (!jflag) { /* set the time */ if (nflag || netsettime(tval)) { utx.ut_type = OLD_TIME; gettimeofday(&utx.ut_tv, NULL); pututxline(&utx); tv.tv_sec = tval; tv.tv_usec = 0; if (settimeofday(&tv, (struct timezone *)NULL)) err(1, "settimeofday (timeval)"); utx.ut_type = NEW_TIME; gettimeofday(&utx.ut_tv, NULL); pututxline(&utx); } if ((p = getlogin()) == NULL) p = "???"; syslog(LOG_AUTH | LOG_NOTICE, "date set by %s", p); } }
int asn1_time_parse(const char *bytes, size_t len, struct tm *tm, int mode) { size_t i; int type = 0; struct tm ltm; struct tm *lt; const char *p; if (bytes == NULL) return (-1); /* Constrain to valid lengths. */ if (len != UTCTIME_LENGTH && len != GENTIME_LENGTH) return (-1); lt = tm; if (lt == NULL) { memset(<m, 0, sizeof(ltm)); lt = <m; } /* Timezone is required and must be GMT (Zulu). */ if (bytes[len - 1] != 'Z') return (-1); /* Make sure everything else is digits. */ for (i = 0; i < len - 1; i++) { if (isdigit((unsigned char)bytes[i])) continue; return (-1); } /* * Validate and convert the time */ p = bytes; switch (len) { case GENTIME_LENGTH: if (mode == V_ASN1_UTCTIME) return (-1); lt->tm_year = (ATOI2(p) * 100) - 1900; /* cc */ type = V_ASN1_GENERALIZEDTIME; /* FALLTHROUGH */ case UTCTIME_LENGTH: if (type == 0) { if (mode == V_ASN1_GENERALIZEDTIME) return (-1); type = V_ASN1_UTCTIME; } lt->tm_year += ATOI2(p); /* yy */ if (type == V_ASN1_UTCTIME) { if (lt->tm_year < 50) lt->tm_year += 100; } lt->tm_mon = ATOI2(p) - 1; /* mm */ if (lt->tm_mon < 0 || lt->tm_mon > 11) return (-1); lt->tm_mday = ATOI2(p); /* dd */ if (lt->tm_mday < 1 || lt->tm_mday > 31) return (-1); lt->tm_hour = ATOI2(p); /* HH */ if (lt->tm_hour < 0 || lt->tm_hour > 23) return (-1); lt->tm_min = ATOI2(p); /* MM */ if (lt->tm_min < 0 || lt->tm_min > 59) return (-1); lt->tm_sec = ATOI2(p); /* SS */ /* Leap second 60 is not accepted. Reconsider later? */ if (lt->tm_sec < 0 || lt->tm_sec > 59) return (-1); break; default: return (-1); } return (type); }
static void setthetime(const char *p) { struct timeval tv; time_t new_time; struct tm *lt; const char *dot, *t; size_t len; int yearset; for (t = p, dot = NULL; *t; ++t) { if (isdigit((unsigned char)*t)) continue; if (*t == '.' && dot == NULL) { dot = t; continue; } badformat(); } lt = localtime(&tval); lt->tm_isdst = -1; /* Divine correct DST */ if (dot != NULL) { /* .ss */ len = strlen(dot); if (len != 3) badformat(); ++dot; lt->tm_sec = ATOI2(dot); if (lt->tm_sec > 61) badvalue("seconds"); } else { len = 0; lt->tm_sec = 0; } yearset = 0; switch (strlen(p) - len) { case 12: /* cc */ lt->tm_year = ATOI2(p) * 100 - TM_YEAR_BASE; if (lt->tm_year < 0) badtime(); yearset = 1; /* FALLTHROUGH */ case 10: /* yy */ if (yearset) { lt->tm_year += ATOI2(p); } else { yearset = ATOI2(p); if (yearset < 69) lt->tm_year = yearset + 2000 - TM_YEAR_BASE; else lt->tm_year = yearset + 1900 - TM_YEAR_BASE; } /* FALLTHROUGH */ case 8: /* mm */ lt->tm_mon = ATOI2(p); if (lt->tm_mon > 12 || lt->tm_mon == 0) badvalue("month"); --lt->tm_mon; /* time struct is 0 - 11 */ /* FALLTHROUGH */ case 6: /* dd */ lt->tm_mday = ATOI2(p); switch (lt->tm_mon) { case 0: case 2: case 4: case 6: case 7: case 9: case 11: if (lt->tm_mday > 31 || lt->tm_mday == 0) badvalue("day of month"); break; case 3: case 5: case 8: case 10: if (lt->tm_mday > 30 || lt->tm_mday == 0) badvalue("day of month"); break; case 1: if (lt->tm_mday > 29 || lt->tm_mday == 0 || (lt->tm_mday == 29 && !isleap(lt->tm_year + TM_YEAR_BASE))) badvalue("day of month"); break; default: badvalue("month"); break; } /* FALLTHROUGH */ case 4: /* hh */ lt->tm_hour = ATOI2(p); if (lt->tm_hour > 23) badvalue("hour"); /* FALLTHROUGH */ case 2: /* mm */ lt->tm_min = ATOI2(p); if (lt->tm_min > 59) badvalue("minute"); break; case 0: /* was just .sss */ if (len != 0) break; /* FALLTHROUGH */ default: badformat(); } /* convert broken-down time to UTC clock time */ if ((new_time = mktime(lt)) == -1) badtime(); /* if jflag is set, don't actually change the time, just return */ if (jflag) { tval = new_time; return; } /* set the time */ if (nflag || netsettime(new_time)) { logwtmp("|", "date", ""); if (aflag) { tv.tv_sec = new_time - tval; tv.tv_usec = 0; if (adjtime(&tv, NULL)) err(EXIT_FAILURE, "adjtime"); } else { tval = new_time; tv.tv_sec = tval; tv.tv_usec = 0; if (settimeofday(&tv, NULL)) err(EXIT_FAILURE, "settimeofday"); } logwtmp("{", "date", ""); } if ((p = getlogin()) == NULL) p = "???"; syslog(LOG_AUTH | LOG_NOTICE, "date set by %s", p); }
static int str_sec(const char *p, time_t *tval) { struct tm *lt; const char *dot, *t; int yearset, len; for (t = p, dot = NULL; *t; ++t) { if (isdigit((unsigned char)*t)) continue; if (*t == '.' && dot == NULL) { dot = t; continue; } return -1; } lt = localtime(tval); if (dot != NULL) { len = strlen(dot); if (len != 3) return -1; ++dot; lt->tm_sec = ATOI2(dot); } else { len = 0; lt->tm_sec = 0; } yearset = 0; switch (strlen(p) - len) { case 12: lt->tm_year = ATOI2(p) * 100 - TM_YEAR_BASE; yearset = 1; /* FALLTHROUGH */ case 10: if (yearset) { lt->tm_year += ATOI2(p); } else { yearset = ATOI2(p); if (yearset < 69) lt->tm_year = yearset + 2000 - TM_YEAR_BASE; else lt->tm_year = yearset + 1900 - TM_YEAR_BASE; } /* FALLTHROUGH */ case 8: lt->tm_mon = ATOI2(p); --lt->tm_mon; /* FALLTHROUGH */ case 6: lt->tm_mday = ATOI2(p); /* FALLTHROUGH */ case 4: lt->tm_hour = ATOI2(p); /* FALLTHROUGH */ case 2: lt->tm_min = ATOI2(p); break; default: return -1; } /* * convert broken-down time to GMT clock time seconds */ if ((*tval = mktime(lt)) == -1) return -1; return 0; }
void setthetime(char *p) { struct tm *lt; struct timeval tv; char *dot, *t; const char *pc; int bigyear; int yearset = 0; for (t = p, dot = NULL; *t; ++t) { if (isdigit(*t)) continue; if (*t == '.' && dot == NULL) { dot = t; continue; } badformat(); } lt = localtime(&tval); lt->tm_isdst = -1; /* correct for DST */ if (dot != NULL) { /* .SS */ *dot++ = '\0'; if (strlen(dot) != 2) badformat(); lt->tm_sec = ATOI2(dot); if (lt->tm_sec > 61) badformat(); } else lt->tm_sec = 0; switch (strlen(p)) { case 12: /* cc */ bigyear = ATOI2(p); lt->tm_year = bigyear * 100 - TM_YEAR_BASE; yearset = 1; /* FALLTHROUGH */ case 10: /* yy */ if (yearset) { lt->tm_year += ATOI2(p); } else { lt->tm_year = ATOI2(p); if (lt->tm_year < 69) /* hack for 2000 ;-} */ lt->tm_year += (2000 - TM_YEAR_BASE); else lt->tm_year += (1900 - TM_YEAR_BASE); } /* FALLTHROUGH */ case 8: /* mm */ lt->tm_mon = ATOI2(p); if ((lt->tm_mon > 12) || !lt->tm_mon) badformat(); --lt->tm_mon; /* time struct is 0 - 11 */ /* FALLTHROUGH */ case 6: /* dd */ lt->tm_mday = ATOI2(p); if ((lt->tm_mday > 31) || !lt->tm_mday) badformat(); /* FALLTHROUGH */ case 4: /* HH */ lt->tm_hour = ATOI2(p); if (lt->tm_hour > 23) badformat(); /* FALLTHROUGH */ case 2: /* MM */ lt->tm_min = ATOI2(p); if (lt->tm_min > 59) badformat(); break; default: badformat(); } /* convert broken-down time to UTC clock time */ if ((tval = mktime(lt)) < 0) errx(1, "specified date is outside allowed range"); /* set the time */ if (slidetime) { struct timeval tv_current; if (gettimeofday(&tv_current, NULL) == -1) err(1, "Could not get local time of day"); tv.tv_sec = tval - tv_current.tv_sec; tv.tv_usec = 0; if (adjtime(&tv, NULL) == -1) errx(1, "adjtime"); } else { tv.tv_sec = tval; tv.tv_usec = 0; if (settimeofday(&tv, NULL)) err(1, "settimeofday"); } if ((pc = getlogin()) == NULL) pc = "???"; syslog(LOG_AUTH | LOG_NOTICE, "date set by %s", pc); }
void stime_arg1(char *arg, struct timespec *tsp) { struct tm *lt; time_t tmptime; int yearset; char *dot, *p; /* Start with the current time. */ tmptime = time(NULL); if ((lt = localtime(&tmptime)) == NULL) err(1, "localtime"); /* [[CC]YY]MMDDhhmm[.SS] */ for (p = arg, dot = NULL; *p != '\0'; p++) { if (*p == '.' && dot == NULL) dot = p; else if (!isdigit((unsigned char)*p)) goto terr; } if (dot == NULL) lt->tm_sec = 0; /* Seconds defaults to 0. */ else { *dot++ = '\0'; if (strlen(dot) != 2) goto terr; lt->tm_sec = ATOI2(dot); if (lt->tm_sec > 61) /* Could be leap second. */ goto terr; } yearset = 0; switch (strlen(arg)) { case 12: /* CCYYMMDDhhmm */ lt->tm_year = (ATOI2(arg) * 100) - 1900; yearset = 1; /* FALLTHROUGH */ case 10: /* YYMMDDhhmm */ if (yearset) { yearset = ATOI2(arg); lt->tm_year += yearset; } else { yearset = ATOI2(arg); /* POSIX logic: [00,68]=>20xx, [69,99]=>19xx */ lt->tm_year = yearset; if (yearset < 69) lt->tm_year += 100; } /* FALLTHROUGH */ case 8: /* MMDDhhmm */ lt->tm_mon = ATOI2(arg); if (lt->tm_mon > 12 || lt->tm_mon == 0) goto terr; --lt->tm_mon; /* Convert from 01-12 to 00-11 */ lt->tm_mday = ATOI2(arg); if (lt->tm_mday > 31 || lt->tm_mday == 0) goto terr; lt->tm_hour = ATOI2(arg); if (lt->tm_hour > 23) goto terr; lt->tm_min = ATOI2(arg); if (lt->tm_min > 59) goto terr; break; default: goto terr; } lt->tm_isdst = -1; /* Figure out DST. */ tsp[0].tv_sec = tsp[1].tv_sec = mktime(lt); if (tsp[0].tv_sec == -1) terr: errx(1, "out of range or illegal time specification: [[CC]YY]MMDDhhmm[.SS]"); tsp[0].tv_nsec = tsp[1].tv_nsec = 0; }
static void stime_darg(const char *arg, struct timespec *tvp) { struct tm t = { .tm_sec = 0 }; const char *fmt, *colon; char *p; int val, isutc = 0; tvp[0].tv_nsec = 0; t.tm_isdst = -1; colon = strchr(arg, ':'); if (colon == NULL || strchr(colon + 1, ':') == NULL) goto bad; fmt = strchr(arg, 'T') != NULL ? "%Y-%m-%dT%H:%M:%S" : "%Y-%m-%d %H:%M:%S"; p = strptime(arg, fmt, &t); if (p == NULL) goto bad; /* POSIX: must have at least one digit after dot */ if ((*p == '.' || *p == ',') && isdigit((unsigned char)p[1])) { p++; val = 100000000; while (isdigit((unsigned char)*p)) { tvp[0].tv_nsec += val * (*p - '0'); p++; val /= 10; } } if (*p == 'Z') { isutc = 1; p++; } if (*p != '\0') goto bad; tvp[0].tv_sec = isutc ? timegm(&t) : mktime(&t); tvp[1] = tvp[0]; return; bad: errx(1, "out of range or illegal time specification: YYYY-MM-DDThh:mm:SS[.frac][tz]"); } /* Calculate a time offset in seconds, given an arg of the format [-]HHMMSS. */ int timeoffset(const char *arg) { int offset; int isneg; offset = 0; isneg = *arg == '-'; if (isneg) arg++; switch (strlen(arg)) { default: /* invalid */ errx(1, "Invalid offset spec, must be [-][[HH]MM]SS"); case 6: /* HHMMSS */ offset = ATOI2(arg); /* FALLTHROUGH */ case 4: /* MMSS */ offset = offset * 60 + ATOI2(arg); /* FALLTHROUGH */ case 2: /* SS */ offset = offset * 60 + ATOI2(arg); } if (isneg) return (-offset); else return (offset); }
void setthetime(char *p) { struct tm *lt; struct timeval tv; char *dot, *t; int yearset = 0; for (t = p, dot = NULL; *t; ++t) { if (isdigit((unsigned char)*t)) continue; if (*t == '.' && dot == NULL) { dot = t; continue; } badformat(); } lt = localtime(&tval); lt->tm_isdst = -1; /* correct for DST */ if (dot != NULL) { /* .SS */ *dot++ = '\0'; if (strlen(dot) != 2) badformat(); lt->tm_sec = ATOI2(dot); if (lt->tm_sec > 61) badformat(); } else lt->tm_sec = 0; switch (strlen(p)) { case 12: /* cc */ lt->tm_year = ATOI2(p) * 100 - TM_YEAR_BASE; yearset = 1; /* FALLTHROUGH */ case 10: /* yy */ if (!yearset) { /* mask out current year, leaving only century */ lt->tm_year = ((lt->tm_year / 100) * 100); } lt->tm_year += ATOI2(p); /* FALLTHROUGH */ case 8: /* mm */ lt->tm_mon = ATOI2(p); if ((lt->tm_mon > 12) || !lt->tm_mon) badformat(); --lt->tm_mon; /* time struct is 0 - 11 */ /* FALLTHROUGH */ case 6: /* dd */ lt->tm_mday = ATOI2(p); if ((lt->tm_mday > 31) || !lt->tm_mday) badformat(); /* FALLTHROUGH */ case 4: /* HH */ lt->tm_hour = ATOI2(p); if (lt->tm_hour > 23) badformat(); /* FALLTHROUGH */ case 2: /* MM */ lt->tm_min = ATOI2(p); if (lt->tm_min > 59) badformat(); break; default: badformat(); } /* convert broken-down time to UTC clock time */ if ((tval = mktime(lt)) < 0) errx(1, "specified date is outside allowed range"); if (jflag) return; /* set the time */ if (slidetime) { struct timeval tv_current; if (gettimeofday(&tv_current, NULL) == -1) err(1, "Could not get local time of day"); tv.tv_sec = tval - tv_current.tv_sec; tv.tv_usec = 0; if (adjtime(&tv, NULL) == -1) errx(1, "adjtime"); } else { #ifndef SMALL logwtmp("|", "date", ""); #endif tv.tv_sec = tval; tv.tv_usec = 0; if (settimeofday(&tv, NULL)) err(1, "settimeofday"); #ifndef SMALL logwtmp("{", "date", ""); #endif } if ((p = getlogin()) == NULL) p = "???"; syslog(LOG_AUTH | LOG_NOTICE, "date set by %s", p); }
static int str_sec(char *str, time_t *tval) { struct tm *lt; char *dot = NULL; lt = localtime(tval); if ((dot = strchr(str, '.')) != NULL) { /* * seconds (.ss) */ *dot++ = '\0'; if (strlen(dot) != 2) return(-1); if ((lt->tm_sec = ATOI2(dot)) > 61) return(-1); } else lt->tm_sec = 0; switch (strlen(str)) { case 10: /* * year (yy) * watch out for year 2000 */ if ((lt->tm_year = ATOI2(str)) < 69) lt->tm_year += 100; str += 2; /* FALLTHROUGH */ case 8: /* * month (mm) * watch out months are from 0 - 11 internally */ if ((lt->tm_mon = ATOI2(str)) > 12) return(-1); --lt->tm_mon; str += 2; /* FALLTHROUGH */ case 6: /* * day (dd) */ if ((lt->tm_mday = ATOI2(str)) > 31) return(-1); str += 2; /* FALLTHROUGH */ case 4: /* * hour (hh) */ if ((lt->tm_hour = ATOI2(str)) > 23) return(-1); str += 2; /* FALLTHROUGH */ case 2: /* * minute (mm) */ if ((lt->tm_min = ATOI2(str)) > 59) return(-1); break; default: return(-1); } /* * convert broken-down time to GMT clock time seconds */ if ((*tval = mktime(lt)) == -1) return(-1); return(0); }
static int str_sec(const char *p, time_t *tval) { struct tm *lt; const char *dot, *t; size_t len; int bigyear; int yearset; yearset = 0; len = strlen(p); for (t = p, dot = NULL; *t; ++t) { if (isdigit(*t)) continue; if (*t == '.' && dot == NULL) { dot = t; continue; } return(-1); } lt = localtime(tval); if (dot != NULL) { /* .SS */ if (strlen(++dot) != 2) return(-1); lt->tm_sec = ATOI2(dot); if (lt->tm_sec > 61) return(-1); len -= 3; } else lt->tm_sec = 0; switch (len) { case 12: /* cc */ bigyear = ATOI2(p); lt->tm_year = (bigyear * 100) - TM_YEAR_BASE; yearset = 1; /* FALLTHROUGH */ case 10: /* yy */ if (yearset) { lt->tm_year += ATOI2(p); } else { lt->tm_year = ATOI2(p); if (lt->tm_year < 69) /* hack for 2000 ;-} */ lt->tm_year += (2000 - TM_YEAR_BASE); else lt->tm_year += (1900 - TM_YEAR_BASE); } /* FALLTHROUGH */ case 8: /* mm */ lt->tm_mon = ATOI2(p); if ((lt->tm_mon > 12) || !lt->tm_mon) return(-1); --lt->tm_mon; /* time struct is 0 - 11 */ /* FALLTHROUGH */ case 6: /* dd */ lt->tm_mday = ATOI2(p); if ((lt->tm_mday > 31) || !lt->tm_mday) return(-1); /* FALLTHROUGH */ case 4: /* HH */ lt->tm_hour = ATOI2(p); if (lt->tm_hour > 23) return(-1); /* FALLTHROUGH */ case 2: /* MM */ lt->tm_min = ATOI2(p); if (lt->tm_min > 59) return(-1); break; default: return(-1); } /* convert broken-down time to UTC clock time seconds */ if ((*tval = mktime(lt)) == -1) return(-1); return(0); }