diff --git a/sbin/dhclient/parse.c b/sbin/dhclient/parse.c --- a/sbin/dhclient/parse.c +++ b/sbin/dhclient/parse.c @@ -444,9 +444,7 @@ time_t parse_date(FILE *cfile) { - static int months[11] = { 31, 59, 90, 120, 151, 181, - 212, 243, 273, 304, 334 }; - int guess, token; + int token; struct tm tm; char *val; @@ -570,27 +568,5 @@ return (0); } - /* Guess the time value... */ - guess = ((((((365 * (tm.tm_year - 70) + /* Days in years since '70 */ - (tm.tm_year - 69) / 4 + /* Leap days since '70 */ - (tm.tm_mon /* Days in months this year */ - ? months[tm.tm_mon - 1] - : 0) + - (tm.tm_mon > 1 && /* Leap day this year */ - !((tm.tm_year - 72) & 3)) + - tm.tm_mday - 1) * 24) + /* Day of month */ - tm.tm_hour) * 60) + - tm.tm_min) * 60) + tm.tm_sec; - - /* - * This guess could be wrong because of leap seconds or other - * weirdness we don't know about that the system does. For - * now, we're just going to accept the guess, but at some point - * it might be nice to do a successive approximation here to get - * an exact value. Even if the error is small, if the server - * is restarted frequently (and thus the lease database is - * reread), the error could accumulate into something - * significant. - */ - return (guess); + return (timegm(&tm)); } diff --git a/sbin/dhclient/tests/Makefile b/sbin/dhclient/tests/Makefile --- a/sbin/dhclient/tests/Makefile +++ b/sbin/dhclient/tests/Makefile @@ -6,7 +6,8 @@ PLAIN_TESTS_C= option-domain-search_test SRCS.option-domain-search_test= alloc.c convert.c hash.c options.c \ - tables.c fake.c option-domain-search.c + tables.c parse.c conflex.c tree.c fake.c \ + option-domain-search.c CFLAGS.option-domain-search_test+= -I${.CURDIR:H} LIBADD.option-domain-search_test= util diff --git a/sbin/dhclient/tests/fake.c b/sbin/dhclient/tests/fake.c --- a/sbin/dhclient/tests/fake.c +++ b/sbin/dhclient/tests/fake.c @@ -7,6 +7,7 @@ #include "dhcpd.h" extern jmp_buf env; +int warnings_occurred; void error(const char *fmt, ...) @@ -52,6 +53,20 @@ return ret; } +int +parse_warn(const char *fmt, ...) +{ + int ret; + va_list ap; + + va_start(ap, fmt); + ret = vfprintf(stderr, fmt, ap); + va_end(ap); + fprintf(stderr, "\n"); + + return ret; +} + void bootp(struct packet *packet) { diff --git a/sbin/dhclient/tests/option-domain-search.c b/sbin/dhclient/tests/option-domain-search.c --- a/sbin/dhclient/tests/option-domain-search.c +++ b/sbin/dhclient/tests/option-domain-search.c @@ -303,6 +303,49 @@ free(option->data); } +static +void +parse_date_helper(const char *string, time_t timestamp) +{ + int ret = 0; + FILE *file = NULL; + time_t ts; + + file = fopen("/tmp/dhclient.test", "w"); + if (!file) + abort(); + + ret = fwrite(string, strlen(string), 1, file); + if (ret <= 0) + abort(); + + fclose(file); + + file = fopen("/tmp/dhclient.test", "r"); + if (!file) + abort(); + + new_parse("test"); + ts = parse_date(file); + if (ts != timestamp) + abort(); + + fclose(file); +} + +void +parse_date_valid(void) +{ + int ret; + + ret = setjmp(env); + if (ret != 0) + abort(); + + parse_date_helper(" 2 2024/7/2 20:25:50;\n", 1719951950); + parse_date_helper(" 1 2091/7/2 20:25:50;\n", 3834246350); +} + int main(int argc, char *argv[]) { @@ -324,5 +367,7 @@ multiple_domains_valid(); + parse_date_valid(); + return (0); }