* 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>
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;
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);
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;
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);
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
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;
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);
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);
}
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);
}
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;
if (zone->view == NULL || zone->view->adb == NULL)
return;
- isc_stdtime_get(&now);
+ isc_time_now(&now);
/*
* Expire check.
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;
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:
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);
default:
break;
}
- zone_settimer(zone, now);
+ zone_settimer(zone, &now);
}
void
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));
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.
* 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,
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
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
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);
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);
}
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));
ENTER;
- isc_stdtime_get(&now);
+ isc_time_now(&now);
if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_EXITING)) {
zone_debuglog(zone, me, 1, "exiting");
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;
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;
}
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));
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,
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 "
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");
DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NEEDREFRESH);
zone->refreshtime = now;
}
- zone_settimer(zone, now);
+ zone_settimer(zone, &now);
UNLOCK_ZONE(zone);
goto detach;
}
}
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:
!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;
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);
"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",
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.
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
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;
fromtext);
return (ISC_R_SUCCESS);
}
- isc_stdtime_get(&now);
zone->notifyfrom = *from;
UNLOCK_ZONE(zone);
dns_zone_refresh(zone);
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;
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);
* 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 "
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,
}
break;
}
- zone_settimer(zone, now);
+ zone_settimer(zone, &now);
/*
* If creating the transfer object failed, zone->xfr is NULL.
* 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
***/
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);
isc_result_t
isc_time_now(isc_time_t *t) {
-
REQUIRE(t != NULL);
GetSystemTimeAsFileTime(&t->absolute);
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;
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>");
+ }
+}