From: Willem Toorop Date: Mon, 14 Mar 2011 12:49:50 +0000 (+0000) Subject: Interpret wireformat inception and expiration time as serial-arithmetic numbers,... X-Git-Tag: release-1.6.10rc1~41 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=ab1ce4bf892fe01647a6c90fd72d4038321fcd80;p=thirdparty%2Fldns.git Interpret wireformat inception and expiration time as serial-arithmetic numbers, and convert those to str in a 32bit proof way. --- diff --git a/configure.ac b/configure.ac index 05cef907..12f88b37 100644 --- a/configure.ac +++ b/configure.ac @@ -283,6 +283,20 @@ include_unistd_h='' ]) AC_SUBST(include_unistd_h) +AC_CHECK_SIZEOF(time_t,,[ +AC_INCLUDES_DEFAULT +#ifdef TIME_WITH_SYS_TIME +# include +# include +#else +# ifdef HAVE_SYS_TIME_H +# include +# else +# include +# endif +#endif +]) + ACX_TYPE_SOCKLEN_T AC_CHECK_TYPE(ssize_t, int) AC_CHECK_TYPE(in_addr_t, [], [AC_DEFINE([in_addr_t], [uint32_t], [in_addr_t])], [ diff --git a/examples/ldns-rrsig.c b/examples/ldns-rrsig.c index 5c565b1d..33376260 100644 --- a/examples/ldns-rrsig.c +++ b/examples/ldns-rrsig.c @@ -34,10 +34,11 @@ main(int argc, char *argv[]) uint8_t i, j; ldns_rr_type t; char * type_name; - time_t incep, expir; + struct tm incep, expir; char incep_buf[26]; char expir_buf[26]; ldns_status s; + time_t now = time(NULL); p = NULL; rrsig = NULL; @@ -178,19 +179,30 @@ main(int argc, char *argv[]) } for(i = 0; i < ldns_rr_list_rr_count(rrsig_type); i++) { - incep = ldns_rdf2native_time_t( - ldns_rr_rrsig_inception( - ldns_rr_list_rr(rrsig_type, i))); - expir = ldns_rdf2native_time_t( - ldns_rr_rrsig_expiration( - ldns_rr_list_rr(rrsig_type, i))); - - /* convert to human readable */ - ctime_r(&incep, incep_buf); - ctime_r(&expir, expir_buf); - /* kill the newline */ - incep_buf[24] = '\0'; - expir_buf[24] = '\0'; + memset(&incep, 0, sizeof(incep)); + if (serial_arithmitics_gmtime_r( + ldns_rdf2native_time_t( + ldns_rr_rrsig_inception( + ldns_rr_list_rr(rrsig_type, i))), + now, &incep + ) + && asctime_r(&incep, incep_buf)) { + incep_buf[24] = '\0'; + } else { + incep_buf[0] = '\0'; + } + memset(&expir, 0, sizeof(expir)); + if (serial_arithmitics_gmtime_r( + ldns_rdf2native_time_t( + ldns_rr_rrsig_expiration( + ldns_rr_list_rr(rrsig_type, i))), + now, &expir + ) + && asctime_r(&expir, expir_buf)) { + expir_buf[24] = '\0'; + } else { + expir_buf[0] = '\0'; + } fprintf(stdout, "%s RRSIG(%s): %s - %s\n", argv[1], type_name, incep_buf, expir_buf); diff --git a/host2str.c b/host2str.c index 6942f6aa..e2d9c6ee 100644 --- a/host2str.c +++ b/host2str.c @@ -330,13 +330,12 @@ ldns_status ldns_rdf2buffer_str_time(ldns_buffer *output, const ldns_rdf *rdf) { /* create a YYYYMMDDHHMMSS string if possible */ - time_t data_time = (time_t) ldns_read_uint32(ldns_rdf_data(rdf)); struct tm tm; char date_buf[16]; memset(&tm, 0, sizeof(tm)); - - if (gmtime_r(&data_time, &tm) && strftime(date_buf, 15, "%Y%m%d%H%M%S", &tm)) { + if (serial_arithmitics_gmtime_r(ldns_rdf2native_int32(rdf), time(NULL), &tm) + && strftime(date_buf, 15, "%Y%m%d%H%M%S", &tm)) { ldns_buffer_printf(output, "%s", date_buf); } return ldns_buffer_status(output); diff --git a/test/08-zonereader.tpkg b/test/08-zonereader.tpkg index d7c07b30..fe879cdc 100644 Binary files a/test/08-zonereader.tpkg and b/test/08-zonereader.tpkg differ diff --git a/util.c b/util.c index eb24f81d..ff342e6d 100644 --- a/util.c +++ b/util.c @@ -241,6 +241,99 @@ mktime_from_utc(const struct tm *tm) return seconds; } +#if SIZEOF_TIME_T <= 4 + +void +year_and_yday_from_days_since_epoch(int days, struct tm *result) +{ + int year = 1970; + int new_year; + + while (days < 0 || days >= (is_leap_year(year) ? 366 : 365)) { + new_year = year + (days / 366); + if (year == new_year) { + year += days < 0 ? -1 : 1; + } + days -= (new_year - year) * 365; + days -= leap_days(year, new_year); + year = new_year; + } + result->tm_year = year; + result->tm_yday = days; +} + +/* Number of days per month in a leap year. */ +static const int leap_year_mdays[] = { + 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 +}; + +void +mon_and_mday_from_year_and_yday(struct tm *result) +{ + int idays = result->tm_yday; + const int *mon_lengths = is_leap_year(result->tm_year) ? + leap_year_mdays : mdays; + + result->tm_mon = 0; + while (idays >= mon_lengths[result->tm_mon]) { + idays -= mon_lengths[result->tm_mon++]; + } + result->tm_mday = idays + 1; +} + +void +wday_from_year_and_yday(struct tm *result) +{ + result->tm_wday = 4 /* 1-1-1970 was a thursday */ + + ((result->tm_year - 1970) % 7) * (365 % 7) + + leap_days(1970, result->tm_year) + + result->tm_yday; + result->tm_wday %= 7; + if (result->tm_wday < 0) { + result->tm_wday += 7; + } +} + +struct tm * +ldns_gmtime64_r(int64_t clock, struct tm *result) +{ + result->tm_isdst = 0; + result->tm_sec = clock % 60; + clock /= 60; + result->tm_min = clock % 60; + clock /= 60; + result->tm_hour = clock % 24; + clock /= 24; + + year_and_yday_from_days_since_epoch(clock, result); + mon_and_mday_from_year_and_yday(result); + wday_from_year_and_yday(result); + result->tm_year -= 1900; + + return result; +} + +#endif /* SIZEOF_TIME_T <= 4 */ + +int64_t +serial_arithmitics_time(int32_t time, time_t now) +{ + int32_t offset = time - (int32_t) now; + return (int64_t) now + offset; +} + + +struct tm * +serial_arithmitics_gmtime_r(int32_t time, time_t now, struct tm *result) +{ + int64_t secs_since_epoch = serial_arithmitics_time(time, now); +#if SIZEOF_TIME_T <= 4 + return ldns_gmtime64_r(secs_since_epoch, result); +#else + return gmtime_r(& (time_t) secs_since_epoch, result); +#endif +} + /** * Init the random source * applications should call this if they need entropy data within ldns