]> git.ipfire.org Git - thirdparty/bind9.git/commitdiff
pullup:
authorAndreas Gustafsson <source@isc.org>
Wed, 5 Sep 2001 00:38:13 +0000 (00:38 +0000)
committerAndreas Gustafsson <source@isc.org>
Wed, 5 Sep 2001 00:38:13 +0000 (00:38 +0000)
 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)

CHANGES
lib/dns/zone.c
lib/isc/log.c
lib/isc/unix/include/isc/time.h
lib/isc/unix/time.c
lib/isc/win32/DLLMain.c
lib/isc/win32/file.c
lib/isc/win32/include/isc/time.h
lib/isc/win32/libisc.def
lib/isc/win32/time.c

diff --git a/CHANGES b/CHANGES
index 27a810df8f46c63e0914aab8468ab7810a4b0792..7db360e0762575e52ef1f2e274db3777f2f43a47 100644 (file)
--- 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]
 
index dcca1bebb3f670ee505c2a08d25228e1595bc4a9..f126fe25886989365ef0e86d8d2859bb32fcfada 100644 (file)
@@ -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 <config.h>
 
@@ -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.
index 025dcd85d2c201914c13a47a96f1dae978757f42..b96bff6e6ab3eeda233650914e5472858d9cc6c5 100644 (file)
@@ -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  : "",
index 8494ea93572ce35ae703fba778e8a3891b7fbbd6..7c21817d1dcd3e52d3005e545bf3df5a71090a98 100644 (file)
@@ -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 */
index 959cd2c0ab5ce394bfdc69ecfbf98a108cab31ca..fc3ba54b6b27f0b268150f7810a0712611752057 100644 (file)
@@ -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 <config.h>
 
@@ -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);
+}
index 47da0fe4bc2473fac6dbbbee2ebac415c810c336..c38b5f0fd3bea896cb298a12c1da17fdeb899d6a 100644 (file)
  * 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 <windows.h>
 #include <stdio.h>
 
 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.  */
index 790c3439f857e99f6ca39def1933f417401df94d..a70e9925e83e03185d66272346bf323b29897a3d 100644 (file)
@@ -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 <config.h>
 
@@ -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);
 
 }
 
index a14ebfd937008ae9f25f85fc7c3b83486f0a55f4..53cf7dfb5e5038f43ca95d643e2441d5cc39f885 100644 (file)
@@ -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 */
index 88d9906a0ba31c4f39666b59a2db3a030f7dac11..f0bbf5d4811bc87514338a9309be0fd2b4e7a36c 100644 (file)
@@ -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
index 8203106fbb134c376ab1afbc819194ca9582c069..166ea4ce5313b988dc72886f8e9f7213e9d00666 100644 (file)
  * 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 <config.h>
 
  *** 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, "<bad time>");
+       }
+}