From: Andreas Gustafsson Date: Wed, 5 Sep 2001 00:38:13 +0000 (+0000) Subject: pullup: X-Git-Tag: v9.2.0rc2~18 X-Git-Url: http://git.ipfire.org/gitweb/?a=commitdiff_plain;h=7ee450d5f69663366f24e6ef6b510d2bddf07273;p=thirdparty%2Fbind9.git pullup: 972. [bug] The file modification time code in zone.c was using the wrong epoch. [RT #1667] (This pullup includes not only the changes to zone.c, but all the recent epoch-related fixes) --- diff --git a/CHANGES b/CHANGES index 27a810df8f4..7db360e0762 100644 --- a/CHANGES +++ b/CHANGES @@ -14,6 +14,9 @@ "bad zone transfer request: non-authoritative zone (NOTAUTH)". + 972. [bug] The file modification time code in zone.c was using the + wrong epoch. [RT #1667] + 968. [bug] On win32, the isc_time_now() function was unnecessarily calling strtime(). [RT #1671] diff --git a/lib/dns/zone.c b/lib/dns/zone.c index dcca1bebb3f..f126fe25886 100644 --- a/lib/dns/zone.c +++ b/lib/dns/zone.c @@ -15,7 +15,7 @@ * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: zone.c,v 1.333.2.1 2001/09/04 22:51:38 gson Exp $ */ +/* $Id: zone.c,v 1.333.2.2 2001/09/05 00:38:01 gson Exp $ */ #include @@ -148,9 +148,9 @@ struct dns_zone { unsigned int options; unsigned int db_argc; char **db_argv; - isc_stdtime_t expiretime; - isc_stdtime_t refreshtime; - isc_stdtime_t dumptime; + isc_time_t expiretime; + isc_time_t refreshtime; + isc_time_t dumptime; isc_time_t loadtime; isc_uint32_t serial; isc_uint32_t refresh; @@ -361,7 +361,7 @@ struct dns_io { isc_event_t *event; }; -static void zone_settimer(dns_zone_t *, isc_stdtime_t); +static void zone_settimer(dns_zone_t *, isc_time_t *); static void cancel_refresh(dns_zone_t *); static void zone_debuglog(dns_zone_t *zone, const char *, int debuglevel, const char *msg, ...) ISC_FORMAT_PRINTF(4, 5); @@ -481,9 +481,9 @@ dns_zone_create(dns_zone_t **zonep, isc_mem_t *mctx) { zone->options = 0; zone->db_argc = 0; zone->db_argv = NULL; - zone->expiretime = 0; - zone->refreshtime = 0; - zone->dumptime = 0; + isc_time_settoepoch(&zone->expiretime); + isc_time_settoepoch(&zone->refreshtime); + isc_time_settoepoch(&zone->dumptime); isc_time_settoepoch(&zone->loadtime); zone->serial = 0; zone->refresh = DNS_ZONE_DEFAULTREFRESH; @@ -885,14 +885,14 @@ zone_isdynamic(dns_zone_t *zone) { static isc_result_t zone_load(dns_zone_t *zone, unsigned int flags) { isc_result_t result; - isc_stdtime_t now; + isc_time_t now; isc_time_t loadtime, filetime; dns_db_t *db = NULL; REQUIRE(DNS_ZONE_VALID(zone)); LOCK_ZONE(zone); - isc_stdtime_get(&now); + isc_time_now(&now); INSIST(zone->type != dns_zone_none); @@ -1124,10 +1124,10 @@ zone_postload(dns_zone_t *zone, dns_db_t *db, isc_time_t loadtime, unsigned int soacount = 0; unsigned int nscount = 0; isc_uint32_t serial, refresh, retry, expire, minimum; - isc_stdtime_t now; + isc_time_t now; isc_boolean_t needdump = ISC_FALSE; - isc_stdtime_get(&now); + isc_time_now(&now); /* * Initiate zone transfer? We may need a error code that @@ -1246,17 +1246,20 @@ zone_postload(dns_zone_t *zone, dns_db_t *db, isc_time_t loadtime, if (zone->type == dns_zone_slave || zone->type == dns_zone_stub) { isc_time_t t; + isc_interval_t i; result = isc_file_getmodtime(zone->journal, &t); if (result != ISC_R_SUCCESS) result = isc_file_getmodtime(zone->masterfile, &t); - if (result == ISC_R_SUCCESS) - zone->expiretime = isc_time_seconds(&t) + - zone->expire; - else - zone->expiretime = now + zone->retry; + if (result == ISC_R_SUCCESS) { + isc_interval_set(&i, zone->expire, 0); + isc_time_add(&t, &i, &zone->expiretime); + } else { + isc_interval_set(&i, zone->retry, 0); + isc_time_add(&now, &i, &zone->expiretime); + } zone->refreshtime = now; } break; @@ -1293,7 +1296,7 @@ zone_postload(dns_zone_t *zone, dns_db_t *db, isc_time_t loadtime, if (needdump) zone_needdump(zone, DNS_DUMP_DELAY); if (zone->task != NULL) - zone_settimer(zone, now); + zone_settimer(zone, &now); dns_zone_log(zone, ISC_LOG_INFO, "loaded serial %u", zone->serial); return (result); @@ -1873,14 +1876,14 @@ dns_zone_getdb(dns_zone_t *zone, dns_db_t **dpb) { void dns_zone_maintenance(dns_zone_t *zone) { const char me[] = "dns_zone_maintenance"; - isc_stdtime_t now; + isc_time_t now; REQUIRE(DNS_ZONE_VALID(zone)); ENTER; LOCK_ZONE(zone); - isc_stdtime_get(&now); - zone_settimer(zone, now); + isc_time_now(&now); + zone_settimer(zone, &now); UNLOCK_ZONE(zone); } @@ -1894,7 +1897,7 @@ was_dumping(dns_zone_t *zone) { DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_DUMPING); if (!dumping) { DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NEEDDUMP); - zone->dumptime = 0; + isc_time_settoepoch(&zone->dumptime); } return (dumping); } @@ -1902,7 +1905,7 @@ was_dumping(dns_zone_t *zone) { static void zone_maintenance(dns_zone_t *zone) { const char me[] = "zone_maintenance"; - isc_stdtime_t now; + isc_time_t now; isc_result_t result; isc_boolean_t dumping; @@ -1919,7 +1922,7 @@ zone_maintenance(dns_zone_t *zone) { if (zone->view == NULL || zone->view->adb == NULL) return; - isc_stdtime_get(&now); + isc_time_now(&now); /* * Expire check. @@ -1928,7 +1931,7 @@ zone_maintenance(dns_zone_t *zone) { case dns_zone_slave: case dns_zone_stub: LOCK_ZONE(zone); - if (now >= zone->expiretime && + if (isc_time_compare(&now, &zone->expiretime) >= 0 && DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED)) { zone_expire(zone); zone->refreshtime = now; @@ -1946,7 +1949,7 @@ zone_maintenance(dns_zone_t *zone) { case dns_zone_slave: case dns_zone_stub: if (!DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DIALREFRESH) && - now >= zone->refreshtime) + isc_time_compare(&now, &zone->refreshtime) >= 0) dns_zone_refresh(zone); break; default: @@ -1961,7 +1964,7 @@ zone_maintenance(dns_zone_t *zone) { case dns_zone_slave: LOCK_ZONE(zone); if (zone->masterfile != NULL && - now >= zone->dumptime && + isc_time_compare(&now, &zone->dumptime) >= 0 && DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED) && DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDDUMP)) { dumping = was_dumping(zone); @@ -1992,7 +1995,7 @@ zone_maintenance(dns_zone_t *zone) { default: break; } - zone_settimer(zone, now); + zone_settimer(zone, &now); } void @@ -2032,7 +2035,7 @@ zone_expire(dns_zone_t *zone) { void dns_zone_refresh(dns_zone_t *zone) { - isc_stdtime_t now; + isc_interval_t i; isc_uint32_t oldflags; REQUIRE(DNS_ZONE_VALID(zone)); @@ -2040,8 +2043,6 @@ dns_zone_refresh(dns_zone_t *zone) { if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_EXITING)) return; - isc_stdtime_get(&now); - /* * Set DNS_ZONEFLG_REFRESH so that there is only one refresh operation * in progress at a time. @@ -2065,11 +2066,9 @@ dns_zone_refresh(dns_zone_t *zone) { * Setting this to the retry time will do that. XXXMLG * If we are successful it will be reset using zone->refresh. */ - zone->refreshtime = now + - isc_random_jitter(zone->retry, zone->retry / 4); - zone_debuglog(zone, "dns_zone_refresh", 20, - "refresh time (%u/%u), now %u", - zone->refreshtime, zone->refresh, now); + isc_interval_set(&i, isc_random_jitter(zone->retry, zone->retry / 4), + 0); + isc_time_nowplusinterval(&zone->refreshtime, &i); /* * When lacking user-specified timer values from the SOA, @@ -2124,7 +2123,9 @@ dns_zone_dump(dns_zone_t *zone) { static void zone_needdump(dns_zone_t *zone, unsigned int delay) { - isc_stdtime_t now; + isc_time_t dumptime; + isc_time_t now; + isc_interval_t i; /* * 'zone' locked by caller @@ -2140,16 +2141,18 @@ zone_needdump(dns_zone_t *zone, unsigned int delay) { DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED) == 0) return; - isc_stdtime_get(&now); + isc_interval_set(&i, delay, 0); + isc_time_now(&now); + isc_time_add(&now, &i, &dumptime); /* add some noise */ delay = isc_random_jitter(delay, delay/4); DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NEEDDUMP); - if (zone->dumptime == 0 || - zone->dumptime > now + delay) - zone->dumptime = now + delay; - zone_settimer(zone, now); + if (isc_time_isepoch(&zone->dumptime) || + isc_time_compare(&zone->dumptime, &dumptime) > 0) + zone->dumptime = dumptime; + zone_settimer(zone, &now); } static isc_result_t @@ -2203,7 +2206,7 @@ zone_dump(dns_zone_t *zone) { DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED)) { DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NEEDDUMP); DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_DUMPING); - zone->dumptime = 0; + isc_time_settoepoch(&zone->dumptime); again = ISC_TRUE; } UNLOCK_ZONE(zone); @@ -2584,15 +2587,15 @@ notify_send(dns_notify_t *notify) { void dns_zone_notify(dns_zone_t *zone) { - isc_stdtime_t now; + isc_time_t now; REQUIRE(DNS_ZONE_VALID(zone)); LOCK_ZONE(zone); DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NEEDNOTIFY); - isc_stdtime_get(&now); - zone_settimer(zone, now); + isc_time_now(&now); + zone_settimer(zone, &now); UNLOCK_ZONE(zone); } @@ -2885,8 +2888,9 @@ stub_callback(isc_task_t *task, isc_event_t *event) { char master[ISC_SOCKADDR_FORMATSIZE]; isc_uint32_t nscnt, cnamecnt; isc_result_t result; - isc_stdtime_t now; + isc_time_t now; isc_boolean_t exiting = ISC_FALSE; + isc_interval_t i; stub = revent->ev_arg; INSIST(DNS_STUB_VALID(stub)); @@ -2897,7 +2901,7 @@ stub_callback(isc_task_t *task, isc_event_t *event) { ENTER; - isc_stdtime_get(&now); + isc_time_now(&now); if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_EXITING)) { zone_debuglog(zone, me, 1, "exiting"); @@ -3017,13 +3021,12 @@ stub_callback(isc_task_t *task, isc_event_t *event) { LOCK_ZONE(zone); dns_request_destroy(&zone->request); DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_REFRESH); - zone->refreshtime = now + - isc_random_jitter(zone->refresh, zone->refresh / 4); - zone->expiretime = now + zone->expire; - zone_debuglog(zone, me, 20, - "refresh time (%u/%u), now %u", - zone->refreshtime, zone->refresh, now); - zone_settimer(zone, now); + isc_interval_set(&i, isc_random_jitter(zone->refresh, + zone->refresh / 4), 0); + isc_time_add(&now, &i, &zone->refreshtime); + isc_interval_set(&i, zone->expire, 0); + isc_time_add(&now, &i, &zone->expiretime); + zone_settimer(zone, &now); UNLOCK_ZONE(zone); goto free_stub; @@ -3042,7 +3045,7 @@ stub_callback(isc_task_t *task, isc_event_t *event) { if (exiting || zone->curmaster >= zone->masterscnt) { DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_REFRESH); - zone_settimer(zone, now); + zone_settimer(zone, &now); UNLOCK_ZONE(zone); goto free_stub; } @@ -3082,13 +3085,14 @@ refresh_callback(isc_task_t *task, isc_event_t *event) { dns_zone_t *zone; dns_message_t *msg = NULL; isc_uint32_t soacnt, cnamecnt, soacount, nscount; - isc_stdtime_t now; + isc_time_t now; char master[ISC_SOCKADDR_FORMATSIZE]; dns_rdataset_t *rdataset; dns_rdata_t rdata = DNS_RDATA_INIT; dns_rdata_soa_t soa; isc_result_t result; isc_uint32_t serial; + isc_interval_t i; zone = revent->ev_arg; INSIST(DNS_ZONE_VALID(zone)); @@ -3103,7 +3107,7 @@ refresh_callback(isc_task_t *task, isc_event_t *event) { isc_sockaddr_format(&zone->masteraddr, master, sizeof(master)); - isc_stdtime_get(&now); + isc_time_now(&now); if (revent->result != ISC_R_SUCCESS) { dns_zone_log(zone, ISC_LOG_INFO, @@ -3282,9 +3286,7 @@ refresh_callback(isc_task_t *task, isc_event_t *event) { dns_message_destroy(&msg); } else if (isc_serial_eq(soa.serial, zone->serial)) { if (zone->masterfile != NULL) { - isc_time_t t; - isc_time_set(&t, now, 0); - result = isc_file_settime(zone->masterfile, &t); + result = isc_file_settime(zone->masterfile, &now); if (result != ISC_R_SUCCESS) dns_zone_log(zone, ISC_LOG_ERROR, "refresh: could not set file " @@ -3292,12 +3294,11 @@ refresh_callback(isc_task_t *task, isc_event_t *event) { zone->masterfile, dns_result_totext(result)); } - zone->refreshtime = now + - isc_random_jitter(zone->refresh, zone->refresh / 4); - zone->expiretime = now + zone->expire; - zone_debuglog(zone, me, 20, "refresh time (%u/%u), now %u", - zone->refreshtime, zone->refresh, now); - + isc_interval_set(&i, isc_random_jitter(zone->refresh, + zone->refresh / 4), 0); + isc_time_add(&now, &i, &zone->refreshtime); + isc_interval_set(&i, zone->expire, 0); + isc_time_add(&now, &i, &zone->expiretime); goto next_master; } else { zone_debuglog(zone, me, 1, "ahead"); @@ -3321,7 +3322,7 @@ refresh_callback(isc_task_t *task, isc_event_t *event) { DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NEEDREFRESH); zone->refreshtime = now; } - zone_settimer(zone, now); + zone_settimer(zone, &now); UNLOCK_ZONE(zone); goto detach; } @@ -3761,32 +3762,33 @@ zone_timer(isc_task_t *task, isc_event_t *event) { } static void -zone_settimer(dns_zone_t *zone, isc_stdtime_t now) { +zone_settimer(dns_zone_t *zone, isc_time_t *now) { const char me[] = "zone_settimer"; - isc_stdtime_t next = 0; - isc_time_t expires; - isc_interval_t interval; + isc_time_t next; isc_result_t result; REQUIRE(DNS_ZONE_VALID(zone)); if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_EXITING)) return; + isc_time_settoepoch(&next); + switch (zone->type) { case dns_zone_master: if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDNOTIFY)) - next = now; + next = *now; if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDDUMP) && !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DUMPING)) { - INSIST(zone->dumptime != 0); - if (zone->dumptime < next || next == 0) + INSIST(!isc_time_isepoch(&zone->dumptime)); + if (isc_time_isepoch(&next) || + isc_time_compare(&zone->dumptime, &next) < 0) next = zone->dumptime; } break; case dns_zone_slave: if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDNOTIFY)) - next = now; + next = *now; /*FALLTHROUGH*/ case dns_zone_stub: @@ -3794,13 +3796,15 @@ zone_settimer(dns_zone_t *zone, isc_stdtime_t now) { !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NOMASTERS) && !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NOREFRESH) && !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADING)) { - INSIST(zone->refreshtime != 0); - if (zone->refreshtime < next || next == 0) + INSIST(!isc_time_isepoch(&zone->refreshtime)); + if (isc_time_isepoch(&next) || + isc_time_compare(&zone->refreshtime, &next) < 0) next = zone->refreshtime; } if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED)) { - INSIST(zone->expiretime != 0); - if (zone->expiretime < next || next == 0) + INSIST(!isc_time_isepoch(&zone->expiretime)); + if (isc_time_isepoch(&next) || + isc_time_compare(&zone->expiretime, &next) < 0) next = zone->expiretime; } break; @@ -3809,7 +3813,7 @@ zone_settimer(dns_zone_t *zone, isc_stdtime_t now) { break; } - if (next == 0) { + if (isc_time_isepoch(&next)) { zone_debuglog(zone, me, 10, "settimer inactive"); result = isc_timer_reset(zone->timer, isc_timertype_inactive, NULL, NULL, ISC_TRUE); @@ -3818,18 +3822,10 @@ zone_settimer(dns_zone_t *zone, isc_stdtime_t now) { "could not deactivate zone timer: %s", isc_result_totext(result)); } else { - if (next <= now) { - next = now; - isc_time_now(&expires); - isc_interval_set(&interval, 0, 0); - } else { - isc_time_settoepoch(&expires); - isc_interval_set(&interval, next - now, 0); - } - zone_debuglog(zone, me, 10, "settimer %d %d = %d seconds", - next, now, next - now); + if (isc_time_compare(&next, now) <= 0) + next = *now; result = isc_timer_reset(zone->timer, isc_timertype_once, - &expires, &interval, ISC_TRUE); + &next, NULL, ISC_TRUE); if (result != ISC_R_SUCCESS) dns_zone_log(zone, ISC_LOG_ERROR, "could not reset zone timer: %s", @@ -3840,7 +3836,7 @@ zone_settimer(dns_zone_t *zone, isc_stdtime_t now) { static void cancel_refresh(dns_zone_t *zone) { const char me[] = "cancel_refresh"; - isc_stdtime_t now; + isc_time_t now; /* * 'zone' locked by caller. @@ -3852,8 +3848,8 @@ cancel_refresh(dns_zone_t *zone) { ENTER; DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_REFRESH); - isc_stdtime_get(&now); - zone_settimer(zone, now); + isc_time_now(&now); + zone_settimer(zone, &now); } static isc_result_t @@ -4012,7 +4008,6 @@ dns_zone_notifyreceive(dns_zone_t *zone, isc_sockaddr_t *from, dns_rdataset_t *rdataset = NULL; dns_rdata_t rdata = DNS_RDATA_INIT; isc_result_t result; - isc_stdtime_t now; char fromtext[ISC_SOCKADDR_FORMATSIZE]; int match = 0; isc_netaddr_t netaddr; @@ -4142,7 +4137,6 @@ dns_zone_notifyreceive(dns_zone_t *zone, isc_sockaddr_t *from, fromtext); return (ISC_R_SUCCESS); } - isc_stdtime_get(&now); zone->notifyfrom = *from; UNLOCK_ZONE(zone); dns_zone_refresh(zone); @@ -4683,8 +4677,8 @@ zone_replacedb(dns_zone_t *zone, dns_db_t *db, isc_boolean_t dump) { static void zone_xfrdone(dns_zone_t *zone, isc_result_t result) { - const char me[] = "zone_xfrdone"; - isc_stdtime_t now; + isc_time_t now; + isc_interval_t i; isc_boolean_t again = ISC_FALSE; unsigned int soacount; unsigned int nscount; @@ -4700,7 +4694,7 @@ zone_xfrdone(dns_zone_t *zone, isc_result_t result) { INSIST((zone->flags & DNS_ZONEFLG_REFRESH) != 0); DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_REFRESH); - isc_stdtime_get(&now); + isc_time_now(&now); switch (result) { case ISC_R_SUCCESS: DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NEEDNOTIFY); @@ -4718,15 +4712,13 @@ zone_xfrdone(dns_zone_t *zone, isc_result_t result) { * won't hurt with an AXFR. */ if (zone->masterfile != NULL || zone->journal != NULL) { - isc_time_t t; - isc_time_set(&t, now, 0); - result = ISC_R_FAILURE; if (zone->journal != NULL) - result = isc_file_settime(zone->journal, &t); + result = isc_file_settime(zone->journal, &now); if (result != ISC_R_SUCCESS && zone->masterfile != NULL) - result = isc_file_settime(zone->masterfile, &t); + result = isc_file_settime(zone->masterfile, + &now); if (result != ISC_R_SUCCESS) dns_zone_log(zone, ISC_LOG_ERROR, "transfer: could not set file " @@ -4773,16 +4765,14 @@ zone_xfrdone(dns_zone_t *zone, isc_result_t result) { if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDREFRESH)) { DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NEEDREFRESH); zone->refreshtime = now; - zone->expiretime = now + zone->expire; + isc_interval_set(&i, zone->expire, 0); + isc_time_add(&now, &i, &zone->expiretime); } else { - zone->refreshtime = now + - isc_random_jitter(zone->refresh, - zone->refresh / 4); - zone_debuglog(zone, me, 20, - "refresh time (%u/%u), now %u", - zone->refreshtime, zone->refresh, now); - - zone->expiretime = now + zone->expire; + isc_interval_set(&i, isc_random_jitter(zone->refresh, + zone->refresh / 4), 0); + isc_time_add(&now, &i, &zone->refreshtime); + isc_interval_set(&i, zone->expire, 0); + isc_time_add(&now, &i, &zone->expiretime); } if (result == ISC_R_SUCCESS && xfrresult == ISC_R_SUCCESS) dns_zone_log(zone, ISC_LOG_INFO, @@ -4806,7 +4796,7 @@ zone_xfrdone(dns_zone_t *zone, isc_result_t result) { } break; } - zone_settimer(zone, now); + zone_settimer(zone, &now); /* * If creating the transfer object failed, zone->xfr is NULL. diff --git a/lib/isc/log.c b/lib/isc/log.c index 025dcd85d2c..b96bff6e6ab 100644 --- a/lib/isc/log.c +++ b/lib/isc/log.c @@ -15,7 +15,7 @@ * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: log.c,v 1.70 2001/08/08 22:54:51 gson Exp $ */ +/* $Id: log.c,v 1.70.2.1 2001/09/05 00:38:03 gson Exp $ */ /* Principal Authors: DCL */ @@ -1346,7 +1346,6 @@ isc_log_doit(isc_log_t *lctx, isc_logcategory_t *category, isc_logconfig_t *lcfg; isc_logchannel_t *channel; isc_logchannellist_t *category_channels; - isc_time_t isctime; isc_result_t result; REQUIRE(lctx == NULL || VALID_CONTEXT(lctx)); @@ -1438,37 +1437,13 @@ isc_log_doit(isc_log_t *lctx, isc_logcategory_t *category, if ((channel->flags & ISC_LOG_PRINTTIME) != 0 && time_string[0] == '\0') { - time_t now; + isc_time_t isctime; - result = isc_time_now(&isctime); + result = isc_time_now(&isctime); if (result == ISC_R_SUCCESS) - result = isc_time_secondsastimet(&isctime, - &now); - - if (result == ISC_R_SUCCESS) { - unsigned int len; - struct tm *timeptr; - - timeptr = localtime(&now); - /* - * Emulate syslog's time format, - * with milliseconds. - * - * It would be nice if the format - * were configurable. - */ - strftime(time_string, sizeof(time_string), - "%b %d %X", timeptr); - - len = strlen(time_string); - - snprintf(time_string + len, - sizeof(time_string) - len, - ".%03u ", - isc_time_nanoseconds(&isctime) - / 1000000); - - } else + isc_time_formattimestamp(&isctime, time_string, + sizeof(time_string)); + else /* * "Should never happen." */ @@ -1476,7 +1451,7 @@ isc_log_doit(isc_log_t *lctx, isc_logcategory_t *category, isc_msgcat_get(isc_msgcat, ISC_MSGSET_LOG, ISC_MSG_BADTIME, - "Bad 00 99:99:99.999 ")); + "Bad 00 99:99:99.999")); } @@ -1662,8 +1637,9 @@ isc_log_doit(isc_log_t *lctx, isc_logcategory_t *category, /* FALLTHROUGH */ case ISC_LOG_TOFILEDESC: - fprintf(FILE_STREAM(channel), "%s%s%s%s%s%s%s%s%s\n", + fprintf(FILE_STREAM(channel), "%s%s%s%s%s%s%s%s%s%s\n", printtime ? time_string : "", + printtime ? " " : "", printtag ? lcfg->tag : "", printtag ? ": " : "", printcategory ? category->name : "", diff --git a/lib/isc/unix/include/isc/time.h b/lib/isc/unix/include/isc/time.h index 8494ea93572..7c21817d1dc 100644 --- a/lib/isc/unix/include/isc/time.h +++ b/lib/isc/unix/include/isc/time.h @@ -15,7 +15,7 @@ * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: time.h,v 1.25 2001/01/09 21:58:46 bwelling Exp $ */ +/* $Id: time.h,v 1.25.2.1 2001/09/05 00:38:07 gson Exp $ */ #ifndef ISC_TIME_H #define ISC_TIME_H 1 @@ -279,6 +279,20 @@ isc_time_nanoseconds(isc_time_t *t); * The returned value is less than 1*10^9. */ +void +isc_time_formattimestamp(const isc_time_t *t, char *buf, unsigned int len); +/* + * Format the time 't' into the buffer 'buf' of length 'len', + * using a format like "Aug 30 04:06:47.997" and the local time zone. + * If the text does not fit in the buffer, the result is indeterminate, + * but is always guaranteed to be null terminated. + * + * Requires: + * 'len' > 0 + * 'buf' points to an array of at least len chars + * + */ + ISC_LANG_ENDDECLS #endif /* ISC_TIME_H */ diff --git a/lib/isc/unix/time.c b/lib/isc/unix/time.c index 959cd2c0ab5..fc3ba54b6b2 100644 --- a/lib/isc/unix/time.c +++ b/lib/isc/unix/time.c @@ -15,7 +15,7 @@ * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: time.c,v 1.34.2.1 2001/08/31 18:01:22 gson Exp $ */ +/* $Id: time.c,v 1.34.2.2 2001/09/05 00:38:05 gson Exp $ */ #include @@ -384,3 +384,17 @@ isc_time_nanoseconds(isc_time_t *t) { return ((isc_uint32_t)t->nanoseconds); } + +void +isc_time_formattimestamp(const isc_time_t *t, char *buf, unsigned int len) { + time_t now; + unsigned int flen; + + REQUIRE(len > 0); + + now = (time_t) t->seconds; + strftime(buf, len, "%b %d %X", localtime(&now)); + flen = strlen(buf); + snprintf(buf + flen, len - flen, + ".%03u", t->nanoseconds / 1000000); +} diff --git a/lib/isc/win32/DLLMain.c b/lib/isc/win32/DLLMain.c index 47da0fe4bc2..c38b5f0fd3b 100644 --- a/lib/isc/win32/DLLMain.c +++ b/lib/isc/win32/DLLMain.c @@ -15,13 +15,12 @@ * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: DLLMain.c,v 1.3 2001/07/17 19:16:55 gson Exp $ */ +/* $Id: DLLMain.c,v 1.3.2.1 2001/09/05 00:38:08 gson Exp $ */ #include #include BOOL InitSockets(void); -void isc_time_initepoch(); /* * Called when we enter the DLL @@ -38,7 +37,6 @@ __declspec(dllexport) BOOL WINAPI DllMain(HINSTANCE hinstDLL, case DLL_PROCESS_ATTACH: if (!InitSockets()) return (FALSE); - isc_time_initepoch(); break; /* The attached process creates a new thread. */ diff --git a/lib/isc/win32/file.c b/lib/isc/win32/file.c index 790c3439f85..a70e9925e83 100644 --- a/lib/isc/win32/file.c +++ b/lib/isc/win32/file.c @@ -15,7 +15,7 @@ * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: file.c,v 1.20 2001/07/17 20:29:26 gson Exp $ */ +/* $Id: file.c,v 1.20.2.1 2001/09/05 00:38:09 gson Exp $ */ #include @@ -105,7 +105,7 @@ gettemp(char *path, int *doopen) { /*NOTREACHED*/ } -int +static int mkstemp(char *path) { int fd; @@ -200,53 +200,53 @@ isc_file_safemovefile(const char *oldname, const char *newname) { isc_result_t isc_file_getmodtime(const char *file, isc_time_t *time) { - isc_result_t result; - struct stat stats; + int fh; REQUIRE(file != NULL); REQUIRE(time != NULL); - result = file_stats(file, &stats); - - if (result == ISC_R_SUCCESS) - /* - * XXXDCL some operating systems provide nanoseconds, too, - * such as BSD/OS via st_mtimespec. - */ - isc_time_set(time, stats.st_mtime, 0); + if ((fh = open(file, _O_RDWR | _O_BINARY)) < 0) + return (isc__errno2result(errno)); - return (result); + if (!GetFileTime((HANDLE) _get_osfhandle(fh), + NULL, + NULL, + &time->absolute)) + { + close(fh); + errno = EINVAL; + return (isc__errno2result(errno)); + } + close(fh); + return (ISC_R_SUCCESS); } isc_result_t isc_file_settime(const char *file, isc_time_t *time) { - struct utimbuf timem; + int fh; REQUIRE(file != NULL && time != NULL); - /* - * tv_sec is at least a 32 bit quantity on all platforms we're - * dealing with, but it is signed on most (all?) of them, - * so we need to make sure the high bit isn't set. This unfortunately - * loses when either: - * * tv_sec becomes a signed 64 bit integer but long is 32 bits - * and isc_time_seconds > LONG_MAX, or - * * isc_time_seconds is changed to be > 32 bits but long is 32 bits - * and isc_time_seconds has at least 33 significant bits. - */ - timem.actime = timem.modtime = (long)isc_time_seconds(time); - - /* - * Here is the real check for the high bit being set. - */ - if ((timem.actime & - (1UL << (sizeof(timem.actime) * CHAR_BIT - 1))) != 0) - return (ISC_R_RANGE); - - if (utime(file, &timem) < 0) + if ((fh = open(file, _O_RDWR | _O_BINARY)) < 0) return (isc__errno2result(errno)); - return (ISC_R_SUCCESS); + /* + * Set the date via the filedate system call and return. Failing + * this call implies the new file times are not supported by the + * underlying file system. + */ + if (!SetFileTime((HANDLE) _get_osfhandle(fh), + NULL, + &time->absolute, + &time->absolute)) + { + close(fh); + errno = EINVAL; + return (isc__errno2result(errno)); + } + + close(fh); + return (ISC_R_SUCCESS); } diff --git a/lib/isc/win32/include/isc/time.h b/lib/isc/win32/include/isc/time.h index a14ebfd9370..53cf7dfb5e5 100644 --- a/lib/isc/win32/include/isc/time.h +++ b/lib/isc/win32/include/isc/time.h @@ -15,7 +15,7 @@ * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: time.h,v 1.19 2001/01/09 21:59:09 bwelling Exp $ */ +/* $Id: time.h,v 1.19.2.1 2001/09/05 00:38:13 gson Exp $ */ #ifndef ISC_TIME_H #define ISC_TIME_H 1 @@ -84,23 +84,6 @@ struct isc_time { extern isc_time_t *isc_time_epoch; -void -isc_time_set(isc_time_t *t, unsigned int seconds, unsigned int nanoseconds); -/* - * Set 't' to a particular number of seconds + nanoseconds since the epoch. - * - * Notes: - * This call is equivalent to: - * - * isc_time_settoepoch(t); - * isc_interval_set(i, seconds, nanoseconds); - * isc_time_add(t, i, t); - * - * Requires: - * 't' is a valid pointer. - * nanoseconds < 1000000000. - */ - void isc_time_settoepoch(isc_time_t *t); /* @@ -229,39 +212,6 @@ isc_time_microdiff(isc_time_t *t1, isc_time_t *t2); * The difference of t1 - t2, or 0 if t1 <= t2. */ -isc_uint32_t -isc_time_seconds(isc_time_t *t); -/* - * Return the number of seconds since the epoch stored in a time structure. - * - * Requires: - * - * 't' is a valid pointer. - */ - -isc_result_t -isc_time_secondsastimet(isc_time_t *t, time_t *secondsp); -/* - * Ensure the number of seconds in an isc_time_t is representable by a time_t. - * - * Notes: - * The number of seconds stored in an isc_time_t might be larger - * than the number of seconds a time_t is able to handle. Since - * time_t is mostly opaque according to the ANSI/ISO standard - * (essentially, all you can be sure of is that it is an arithmetic type, - * not even necessarily integral), it can be tricky to ensure that - * the isc_time_t is in the range a time_t can handle. Use this - * function in place of isc_time_seconds() any time you need to set a - * time_t from an isc_time_t. - * - * Requires: - * 't' is a valid pointer. - * - * Returns: - * Success - * Out of range - */ - isc_uint32_t isc_time_nanoseconds(isc_time_t *t); /* @@ -279,6 +229,20 @@ isc_time_nanoseconds(isc_time_t *t); * The returned value is less than 1*10^9. */ +void +isc_time_formattimestamp(const isc_time_t *t, char *buf, unsigned int len); +/* + * Format the time 't' into the buffer 'buf' of length 'len', + * using a format like "Aug 30 04:06:47.997" and the local time zone. + * If the text does not fit in the buffer, the result is indeterminate, + * but is always guaranteed to be null terminated. + * + * Requires: + * 'len' > 0 + * 'buf' points to an array of at least len chars + * + */ + ISC_LANG_ENDDECLS #endif /* ISC_TIME_H */ diff --git a/lib/isc/win32/libisc.def b/lib/isc/win32/libisc.def index 88d9906a0ba..f0bbf5d4811 100644 --- a/lib/isc/win32/libisc.def +++ b/lib/isc/win32/libisc.def @@ -363,7 +363,6 @@ isc_thread_setconcurrency isc_interval_set isc_time_subtract isc_interval_iszero -isc_time_set isc_time_settoepoch isc_time_isepoch isc_time_now @@ -372,8 +371,6 @@ isc_time_compare isc_time_add isc_time_subtract isc_time_microdiff -isc_time_seconds -isc_time_secondsastimet isc_time_nanoseconds isc_keyboard_open isc_keyboard_close diff --git a/lib/isc/win32/time.c b/lib/isc/win32/time.c index 8203106fbb1..166ea4ce531 100644 --- a/lib/isc/win32/time.c +++ b/lib/isc/win32/time.c @@ -15,18 +15,7 @@ * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: time.c,v 1.24 2001/08/29 05:13:42 mayer Exp $ */ - -/* - * Windows has a different epoch than Unix. Therefore this code sets the epoch - * value to the Unix epoch. Care should be used when using these routines to - * ensure that this difference is taken into account. System and File times - * may require adjusting for this when modifying any time value that needs - * to be an absolute Windows time. - * - * Currently only epoch-specific code and the isc_time_seconds - * and isc_time_secondsastimet use the epoch-adjusted code. - */ +/* $Id: time.c,v 1.24.2.1 2001/09/05 00:38:12 gson Exp $ */ #include @@ -58,18 +47,9 @@ *** Absolute Times ***/ -static isc_time_t epoch = { 0, 0 }; +static isc_time_t epoch = { { 0, 0 } }; isc_time_t *isc_time_epoch = &epoch; -void -TimetToFileTime(time_t t, LPFILETIME pft) { - LONGLONG i; - - i = Int32x32To64(t, 10000000) + 116444736000000000; - pft->dwLowDateTime = (DWORD) i; - pft->dwHighDateTime = (DWORD) (i >>32); -} - /*** *** Intervals ***/ @@ -97,41 +77,20 @@ isc_interval_iszero(isc_interval_t *i) { return (ISC_FALSE); } - -void -isc_time_set(isc_time_t *t, unsigned int seconds, unsigned int nanoseconds) { - ULARGE_INTEGER i; - - REQUIRE(t != NULL); - REQUIRE(nanoseconds < NS_PER_S); - - i.QuadPart = (LONGLONG)seconds * INTERVALS_PER_S - + nanoseconds / NS_INTERVAL; - - t->absolute.dwLowDateTime = i.LowPart; - t->absolute.dwHighDateTime = i.HighPart; - -} - -void -isc_time_initepoch() { - TimetToFileTime(0, &epoch.absolute); -} - void isc_time_settoepoch(isc_time_t *t) { REQUIRE(t != NULL); - t->absolute.dwLowDateTime = epoch.absolute.dwLowDateTime; - t->absolute.dwHighDateTime = epoch.absolute.dwHighDateTime; + t->absolute.dwLowDateTime = 0; + t->absolute.dwHighDateTime = 0; } isc_boolean_t isc_time_isepoch(isc_time_t *t) { REQUIRE(t != NULL); - if (t->absolute.dwLowDateTime == epoch.absolute.dwLowDateTime && - t->absolute.dwHighDateTime == epoch.absolute.dwHighDateTime) + if (t->absolute.dwLowDateTime == 0 && + t->absolute.dwHighDateTime == 0) return (ISC_TRUE); return (ISC_FALSE); @@ -139,7 +98,6 @@ isc_time_isepoch(isc_time_t *t) { isc_result_t isc_time_now(isc_time_t *t) { - REQUIRE(t != NULL); GetSystemTimeAsFileTime(&t->absolute); @@ -240,126 +198,6 @@ isc_time_microdiff(isc_time_t *t1, isc_time_t *t2) { return (i3); } -/* - * Note that the value returned is the seconds relative to the Unix - * epoch rather than the seconds since Windows epoch. This is for - * compatibility with the Unix side. - */ -isc_uint32_t -isc_time_seconds(isc_time_t *t) { - ULARGE_INTEGER i; - - REQUIRE(t != NULL); - - i.LowPart = t->absolute.dwLowDateTime - - epoch.absolute.dwLowDateTime; - i.HighPart = t->absolute.dwHighDateTime - - epoch.absolute.dwHighDateTime; - - return ((isc_uint32_t)(i.QuadPart / INTERVALS_PER_S)); -} - -isc_result_t -isc_time_secondsastimet(isc_time_t *t, time_t *secondsp) { - ULARGE_INTEGER i1, i2; - time_t seconds; - - REQUIRE(t != NULL); - - i1.LowPart = t->absolute.dwLowDateTime; - i1.HighPart = t->absolute.dwHighDateTime; - - /* - * Get the time_t zero equivalent in FILETIME - * The zero point for FILETIME is 1 January, 1601 - * while for timet it is 1 January, 1970 - */ - i1.LowPart -= epoch.absolute.dwLowDateTime; - i1.HighPart -= epoch.absolute.dwHighDateTime; - - i1.QuadPart /= INTERVALS_PER_S; - - /* - * Ensure that the number of seconds can be represented by a time_t. - * Since the number seconds is an unsigned int and since time_t is - * mostly opaque, this is trickier than it seems. (This standardized - * opaqueness of time_t is *very* * frustrating; time_t is not even - * limited to being an integral type.) Thought it is known at the - * time of this writing that time_t is a signed long on the Win32 - * platform, the full treatment is given to figuring out if things - * fit to allow for future Windows platforms where time_t is *not* - * a signed long, or where perhaps a signed long is longer than - * it currently is. - */ - seconds = (time_t)i1.QuadPart; - - /* - * First, only do the range tests if the type of size_t is integral. - * Float/double easily include the maximum possible values. - */ - if ((time_t)0.5 != 0.5) { - /* - * Did all the bits make it in? - */ - if ((seconds & i1.QuadPart) != i1.QuadPart) - return (ISC_R_RANGE); - - /* - * Is time_t signed with the high bit set? - * - * The first test (the sizeof comparison) determines - * whether we can even deduce the signedness of time_t - * by using ANSI's rule about integer conversion to - * wider integers. - * - * The second test uses that ANSI rule to see whether - * the value of time_t was sign extended into QuadPart. - * If the test is true, then time_t is signed. - * - * The final test ensures the high bit is not set, or - * the value is negative and hence there is a range error. - */ - if (sizeof(time_t) < sizeof(i2.QuadPart) && - ((i2.QuadPart = (time_t)-1) ^ (time_t)-1) != 0 && - (seconds & (1 << (sizeof(time_t) * 8 - 1))) != 0) - return (ISC_R_RANGE); - - /* - * Last test ... the size of time_t is >= that of i2.QuadPart, - * so we can't determine its signedness. Unconditionally - * declare anything with the high bit set as out of range. - * Since even the maxed signed value is ludicrously far from - * when this is being written, this rule shall not impact - * anything for all intents and purposes. - * - * How far? Well ... if FILETIME is in 100 ns intervals since - * 1600, and a QuadPart can store 9223372036854775808 such - * intervals when interpreted as signed (ie, if sizeof(time_t) - * == sizeof(QuadPart) but time_t is signed), that means - * 9223372036854775808 / INTERVALS_PER_S = 922,337,203,685 - * seconds. That number divided by 60 * 60 * 24 * 365 seconds - * per year means a signed time_t can store at least 29,247 - * years, with only 400 of those years used up since 1600 as I - * write this in May, 2000. - * - * (Real date calculations are of course incredibly more - * complex; I'm only describing the approximate scale of - * the numbers involved here.) - * - * If the Galactic Federation is still running libisc's time - * libray on a Windows platform in the year 27647 A.D., then - * feel free to hunt down my greatgreatgreatgreatgreat(etc) - * grandchildren and whine at them about what I did. - */ - if ((seconds & (1 << (sizeof(time_t) * 8 - 1))) != 0) - return (ISC_R_RANGE); - } - - *secondsp = seconds; - - return (ISC_R_SUCCESS); -} - isc_uint32_t isc_time_nanoseconds(isc_time_t *t) { SYSTEMTIME st; @@ -372,3 +210,25 @@ isc_time_nanoseconds(isc_time_t *t) { return ((isc_uint32_t)(st.wMilliseconds * 1000000)); } + +void +isc_time_formattimestamp(const isc_time_t *t, char *buf, unsigned int len) { + FILETIME localft; + SYSTEMTIME st; + + static const char *months[] = { + "Jan", "Feb", "Mar", "Apr", "May", "Jun", + "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" + }; + + REQUIRE(len > 0); + if (FileTimeToLocalFileTime(&t->absolute, &localft) && + FileTimeToSystemTime(&localft, &st)) + { + snprintf(buf, len, "%s %2u %02u:%02u:%02u.%03u", + months[st.wMonth], st.wDay, st.wHour, st.wMinute, + st.wSecond, st.wMilliseconds); + } else { + snprintf(buf, len, ""); + } +}