1633838b8255282d10af15c5c84cee5a51466712Bob Halley/*
09b9db3c91786130fc095df5055098964e7cdb83Tinderbox User * Copyright (C) 1998-2001, 2003-2008, 2011, 2012, 2014-2018 Internet Systems Consortium, Inc. ("ISC")
40f53fa8d9c6a4fc38c0014495e7a42b08f52481David Lawrence *
0c27b3fe77ac1d5094ba3521e8142d9e7973133fMark Andrews * This Source Code Form is subject to the terms of the Mozilla Public
0c27b3fe77ac1d5094ba3521e8142d9e7973133fMark Andrews * License, v. 2.0. If a copy of the MPL was not distributed with this
0c27b3fe77ac1d5094ba3521e8142d9e7973133fMark Andrews * file, You can obtain one at http://mozilla.org/MPL/2.0/.
1633838b8255282d10af15c5c84cee5a51466712Bob Halley */
94e25967cda41b886e33ec254b917d21df21a187Bob Halley
28a8f5b0de57d269cf2845c69cb6abe18cbd3b3aMark Andrews/* $Id$ */
ab023a65562e62b85a824509d829b6fad87e00b1Rob Austein
ab023a65562e62b85a824509d829b6fad87e00b1Rob Austein/*! \file */
9c3531d72aeaad6c5f01efe6a1c82023e1379e4dDavid Lawrence
d25afd60ee2286cb171c4960a790f3d7041b6f85Bob Halley#include <config.h>
d25afd60ee2286cb171c4960a790f3d7041b6f85Bob Halley
94e25967cda41b886e33ec254b917d21df21a187Bob Halley#include <errno.h>
6fa1cb5754695d550a58c6e8978fda65f5146af7David Lawrence#include <limits.h>
903247531a10d699ef239a7351554ba0a1e3cd22Evan Hunt#include <stdlib.h>
70ec7dd74103fa9e92a6d56a0e3b0fc30e17af0dMark Andrews#include <syslog.h>
1a69a1a78cfaa86f3b68bbc965232b7876d4da2aDavid Lawrence#include <time.h>
94e25967cda41b886e33ec254b917d21df21a187Bob Halley
6e3a8256eed85f6704861d269ccfb35bdaeed5ffDavid Lawrence#include <sys/time.h> /* Required for struct timeval on some platforms. */
6e3a8256eed85f6704861d269ccfb35bdaeed5ffDavid Lawrence
df0f58959ed82a2a43ca8d816ce9592541df9f2fMark Andrews#include <isc/log.h>
4162d3b36d1a3c25724c7e37ce839f67b2352bbbMark Andrews#include <isc/platform.h>
33f87146a856eb6c3dfd55a8ee9c173c94f82150Andreas Gustafsson#include <isc/print.h>
4b87939256ede703385e9cab92d3c58d03c31098Mark Andrews#include <isc/strerror.h>
1a69a1a78cfaa86f3b68bbc965232b7876d4da2aDavid Lawrence#include <isc/string.h>
94e25967cda41b886e33ec254b917d21df21a187Bob Halley#include <isc/time.h>
a147de10fe5e19e593d42152ffd6879eca69860dEvan Hunt#include <isc/tm.h>
364a82f7c25b62967678027043425201a5e5171aBob Halley#include <isc/util.h>
94e25967cda41b886e33ec254b917d21df21a187Bob Halley
ab023a65562e62b85a824509d829b6fad87e00b1Rob Austein#define NS_PER_S 1000000000 /*%< Nanoseconds per second. */
ab023a65562e62b85a824509d829b6fad87e00b1Rob Austein#define NS_PER_US 1000 /*%< Nanoseconds per microsecond. */
bb5d14d7243d71e03d262ff175b355b52873e195Evan Hunt#define NS_PER_MS 1000000 /*%< Nanoseconds per millisecond. */
ab023a65562e62b85a824509d829b6fad87e00b1Rob Austein#define US_PER_S 1000000 /*%< Microseconds per second. */
6fa1cb5754695d550a58c6e8978fda65f5146af7David Lawrence
6fa1cb5754695d550a58c6e8978fda65f5146af7David Lawrence/*
40f53fa8d9c6a4fc38c0014495e7a42b08f52481David Lawrence * All of the INSIST()s checks of nanoseconds < NS_PER_S are for
6fa1cb5754695d550a58c6e8978fda65f5146af7David Lawrence * consistency checking of the type. In lieu of magic numbers, it
6fa1cb5754695d550a58c6e8978fda65f5146af7David Lawrence * is the best we've got. The check is only performed on functions which
6fa1cb5754695d550a58c6e8978fda65f5146af7David Lawrence * need an initialized type.
6fa1cb5754695d550a58c6e8978fda65f5146af7David Lawrence */
6fa1cb5754695d550a58c6e8978fda65f5146af7David Lawrence
df0f58959ed82a2a43ca8d816ce9592541df9f2fMark Andrews#ifndef ISC_FIX_TV_USEC
df0f58959ed82a2a43ca8d816ce9592541df9f2fMark Andrews#define ISC_FIX_TV_USEC 1
df0f58959ed82a2a43ca8d816ce9592541df9f2fMark Andrews#endif
df0f58959ed82a2a43ca8d816ce9592541df9f2fMark Andrews
ab023a65562e62b85a824509d829b6fad87e00b1Rob Austein/*%
4bed2e84a34b37259b85e5c092d51c122ef58c3cBob Halley *** Intervals
4bed2e84a34b37259b85e5c092d51c122ef58c3cBob Halley ***/
4bed2e84a34b37259b85e5c092d51c122ef58c3cBob Halley
27809a2ee5db141b684e53bf1d94da26e9f92d3aMark Andrewsstatic const isc_interval_t zero_interval = { 0, 0 };
27809a2ee5db141b684e53bf1d94da26e9f92d3aMark Andrewsconst isc_interval_t * const isc_interval_zero = &zero_interval;
afdb3abb9b06ed4070ac9021f1f4427b4cb3a286Bob Halley
70ec7dd74103fa9e92a6d56a0e3b0fc30e17af0dMark Andrews#if ISC_FIX_TV_USEC
70ec7dd74103fa9e92a6d56a0e3b0fc30e17af0dMark Andrewsstatic inline void
70ec7dd74103fa9e92a6d56a0e3b0fc30e17af0dMark Andrewsfix_tv_usec(struct timeval *tv) {
70ec7dd74103fa9e92a6d56a0e3b0fc30e17af0dMark Andrews isc_boolean_t fixed = ISC_FALSE;
70ec7dd74103fa9e92a6d56a0e3b0fc30e17af0dMark Andrews
70ec7dd74103fa9e92a6d56a0e3b0fc30e17af0dMark Andrews if (tv->tv_usec < 0) {
70ec7dd74103fa9e92a6d56a0e3b0fc30e17af0dMark Andrews fixed = ISC_TRUE;
70ec7dd74103fa9e92a6d56a0e3b0fc30e17af0dMark Andrews do {
70ec7dd74103fa9e92a6d56a0e3b0fc30e17af0dMark Andrews tv->tv_sec -= 1;
70ec7dd74103fa9e92a6d56a0e3b0fc30e17af0dMark Andrews tv->tv_usec += US_PER_S;
70ec7dd74103fa9e92a6d56a0e3b0fc30e17af0dMark Andrews } while (tv->tv_usec < 0);
70ec7dd74103fa9e92a6d56a0e3b0fc30e17af0dMark Andrews } else if (tv->tv_usec >= US_PER_S) {
70ec7dd74103fa9e92a6d56a0e3b0fc30e17af0dMark Andrews fixed = ISC_TRUE;
70ec7dd74103fa9e92a6d56a0e3b0fc30e17af0dMark Andrews do {
70ec7dd74103fa9e92a6d56a0e3b0fc30e17af0dMark Andrews tv->tv_sec += 1;
70ec7dd74103fa9e92a6d56a0e3b0fc30e17af0dMark Andrews tv->tv_usec -= US_PER_S;
70ec7dd74103fa9e92a6d56a0e3b0fc30e17af0dMark Andrews } while (tv->tv_usec >=US_PER_S);
70ec7dd74103fa9e92a6d56a0e3b0fc30e17af0dMark Andrews }
70ec7dd74103fa9e92a6d56a0e3b0fc30e17af0dMark Andrews /*
70ec7dd74103fa9e92a6d56a0e3b0fc30e17af0dMark Andrews * Call syslog directly as was are called from the logging functions.
70ec7dd74103fa9e92a6d56a0e3b0fc30e17af0dMark Andrews */
70ec7dd74103fa9e92a6d56a0e3b0fc30e17af0dMark Andrews if (fixed)
1f1d36a87b65186d9f89aac7f456ab1fd2a39ef6Andreas Gustafsson (void)syslog(LOG_ERR, "gettimeofday returned bad tv_usec: corrected");
70ec7dd74103fa9e92a6d56a0e3b0fc30e17af0dMark Andrews}
70ec7dd74103fa9e92a6d56a0e3b0fc30e17af0dMark Andrews#endif
70ec7dd74103fa9e92a6d56a0e3b0fc30e17af0dMark Andrews
4bed2e84a34b37259b85e5c092d51c122ef58c3cBob Halleyvoid
3740b569ae76295b941d57a724a43beb75b533baBob Halleyisc_interval_set(isc_interval_t *i,
6fa1cb5754695d550a58c6e8978fda65f5146af7David Lawrence unsigned int seconds, unsigned int nanoseconds)
6fa1cb5754695d550a58c6e8978fda65f5146af7David Lawrence{
4bed2e84a34b37259b85e5c092d51c122ef58c3cBob Halley REQUIRE(i != NULL);
6fa1cb5754695d550a58c6e8978fda65f5146af7David Lawrence REQUIRE(nanoseconds < NS_PER_S);
4bed2e84a34b37259b85e5c092d51c122ef58c3cBob Halley
4bed2e84a34b37259b85e5c092d51c122ef58c3cBob Halley i->seconds = seconds;
4bed2e84a34b37259b85e5c092d51c122ef58c3cBob Halley i->nanoseconds = nanoseconds;
4bed2e84a34b37259b85e5c092d51c122ef58c3cBob Halley}
4bed2e84a34b37259b85e5c092d51c122ef58c3cBob Halley
4bed2e84a34b37259b85e5c092d51c122ef58c3cBob Halleyisc_boolean_t
26f327f1f53afdb8256affa1c197ed138bf3cb2fAndreas Gustafssonisc_interval_iszero(const isc_interval_t *i) {
4bed2e84a34b37259b85e5c092d51c122ef58c3cBob Halley REQUIRE(i != NULL);
6fa1cb5754695d550a58c6e8978fda65f5146af7David Lawrence INSIST(i->nanoseconds < NS_PER_S);
4bed2e84a34b37259b85e5c092d51c122ef58c3cBob Halley
4bed2e84a34b37259b85e5c092d51c122ef58c3cBob Halley if (i->seconds == 0 && i->nanoseconds == 0)
4bed2e84a34b37259b85e5c092d51c122ef58c3cBob Halley return (ISC_TRUE);
4bed2e84a34b37259b85e5c092d51c122ef58c3cBob Halley
4bed2e84a34b37259b85e5c092d51c122ef58c3cBob Halley return (ISC_FALSE);
4bed2e84a34b37259b85e5c092d51c122ef58c3cBob Halley}
4bed2e84a34b37259b85e5c092d51c122ef58c3cBob Halley
4bed2e84a34b37259b85e5c092d51c122ef58c3cBob Halley
4bed2e84a34b37259b85e5c092d51c122ef58c3cBob Halley/***
4bed2e84a34b37259b85e5c092d51c122ef58c3cBob Halley *** Absolute Times
4bed2e84a34b37259b85e5c092d51c122ef58c3cBob Halley ***/
4bed2e84a34b37259b85e5c092d51c122ef58c3cBob Halley
27809a2ee5db141b684e53bf1d94da26e9f92d3aMark Andrewsstatic const isc_time_t epoch = { 0, 0 };
27809a2ee5db141b684e53bf1d94da26e9f92d3aMark Andrewsconst isc_time_t * const isc_time_epoch = &epoch;
afdb3abb9b06ed4070ac9021f1f4427b4cb3a286Bob Halley
585529aaeb95a71cd3d95df2602a4688fc7c3292David Lawrencevoid
585529aaeb95a71cd3d95df2602a4688fc7c3292David Lawrenceisc_time_set(isc_time_t *t, unsigned int seconds, unsigned int nanoseconds) {
585529aaeb95a71cd3d95df2602a4688fc7c3292David Lawrence REQUIRE(t != NULL);
232fd751edcb5dd2b1fd2666e039efe83d2e2b55Michael Sawyer REQUIRE(nanoseconds < NS_PER_S);
585529aaeb95a71cd3d95df2602a4688fc7c3292David Lawrence
585529aaeb95a71cd3d95df2602a4688fc7c3292David Lawrence t->seconds = seconds;
585529aaeb95a71cd3d95df2602a4688fc7c3292David Lawrence t->nanoseconds = nanoseconds;
585529aaeb95a71cd3d95df2602a4688fc7c3292David Lawrence}
585529aaeb95a71cd3d95df2602a4688fc7c3292David Lawrence
4bed2e84a34b37259b85e5c092d51c122ef58c3cBob Halleyvoid
3740b569ae76295b941d57a724a43beb75b533baBob Halleyisc_time_settoepoch(isc_time_t *t) {
4bed2e84a34b37259b85e5c092d51c122ef58c3cBob Halley REQUIRE(t != NULL);
4bed2e84a34b37259b85e5c092d51c122ef58c3cBob Halley
4bed2e84a34b37259b85e5c092d51c122ef58c3cBob Halley t->seconds = 0;
4bed2e84a34b37259b85e5c092d51c122ef58c3cBob Halley t->nanoseconds = 0;
4bed2e84a34b37259b85e5c092d51c122ef58c3cBob Halley}
4bed2e84a34b37259b85e5c092d51c122ef58c3cBob Halley
4bed2e84a34b37259b85e5c092d51c122ef58c3cBob Halleyisc_boolean_t
26f327f1f53afdb8256affa1c197ed138bf3cb2fAndreas Gustafssonisc_time_isepoch(const isc_time_t *t) {
4bed2e84a34b37259b85e5c092d51c122ef58c3cBob Halley REQUIRE(t != NULL);
6fa1cb5754695d550a58c6e8978fda65f5146af7David Lawrence INSIST(t->nanoseconds < NS_PER_S);
4bed2e84a34b37259b85e5c092d51c122ef58c3cBob Halley
4bed2e84a34b37259b85e5c092d51c122ef58c3cBob Halley if (t->seconds == 0 && t->nanoseconds == 0)
4bed2e84a34b37259b85e5c092d51c122ef58c3cBob Halley return (ISC_TRUE);
4bed2e84a34b37259b85e5c092d51c122ef58c3cBob Halley
4bed2e84a34b37259b85e5c092d51c122ef58c3cBob Halley return (ISC_FALSE);
4bed2e84a34b37259b85e5c092d51c122ef58c3cBob Halley}
4bed2e84a34b37259b85e5c092d51c122ef58c3cBob Halley
df0f58959ed82a2a43ca8d816ce9592541df9f2fMark Andrews
4d6964d70a114b53a11a3bd778d9b8f5179a7934Bob Halleyisc_result_t
afdb3abb9b06ed4070ac9021f1f4427b4cb3a286Bob Halleyisc_time_now(isc_time_t *t) {
94e25967cda41b886e33ec254b917d21df21a187Bob Halley struct timeval tv;
4b87939256ede703385e9cab92d3c58d03c31098Mark Andrews char strbuf[ISC_STRERRORSIZE];
94e25967cda41b886e33ec254b917d21df21a187Bob Halley
4bed2e84a34b37259b85e5c092d51c122ef58c3cBob Halley REQUIRE(t != NULL);
40f53fa8d9c6a4fc38c0014495e7a42b08f52481David Lawrence
94e25967cda41b886e33ec254b917d21df21a187Bob Halley if (gettimeofday(&tv, NULL) == -1) {
4b87939256ede703385e9cab92d3c58d03c31098Mark Andrews isc__strerror(errno, strbuf, sizeof(strbuf));
4b87939256ede703385e9cab92d3c58d03c31098Mark Andrews UNEXPECTED_ERROR(__FILE__, __LINE__, "%s", strbuf);
94e25967cda41b886e33ec254b917d21df21a187Bob Halley return (ISC_R_UNEXPECTED);
94e25967cda41b886e33ec254b917d21df21a187Bob Halley }
94e25967cda41b886e33ec254b917d21df21a187Bob Halley
6fa1cb5754695d550a58c6e8978fda65f5146af7David Lawrence /*
6fa1cb5754695d550a58c6e8978fda65f5146af7David Lawrence * Does POSIX guarantee the signedness of tv_sec and tv_usec? If not,
6fa1cb5754695d550a58c6e8978fda65f5146af7David Lawrence * then this test will generate warnings for platforms on which it is
6fa1cb5754695d550a58c6e8978fda65f5146af7David Lawrence * unsigned. In any event, the chances of any of these problems
6fa1cb5754695d550a58c6e8978fda65f5146af7David Lawrence * happening are pretty much zero, but since the libisc library ensures
6fa1cb5754695d550a58c6e8978fda65f5146af7David Lawrence * certain things to be true ...
6fa1cb5754695d550a58c6e8978fda65f5146af7David Lawrence */
df0f58959ed82a2a43ca8d816ce9592541df9f2fMark Andrews#if ISC_FIX_TV_USEC
70ec7dd74103fa9e92a6d56a0e3b0fc30e17af0dMark Andrews fix_tv_usec(&tv);
70ec7dd74103fa9e92a6d56a0e3b0fc30e17af0dMark Andrews if (tv.tv_sec < 0)
df0f58959ed82a2a43ca8d816ce9592541df9f2fMark Andrews return (ISC_R_UNEXPECTED);
df0f58959ed82a2a43ca8d816ce9592541df9f2fMark Andrews#else
6fa1cb5754695d550a58c6e8978fda65f5146af7David Lawrence if (tv.tv_sec < 0 || tv.tv_usec < 0 || tv.tv_usec >= US_PER_S)
6fa1cb5754695d550a58c6e8978fda65f5146af7David Lawrence return (ISC_R_UNEXPECTED);
df0f58959ed82a2a43ca8d816ce9592541df9f2fMark Andrews#endif
6fa1cb5754695d550a58c6e8978fda65f5146af7David Lawrence
6fa1cb5754695d550a58c6e8978fda65f5146af7David Lawrence /*
40f53fa8d9c6a4fc38c0014495e7a42b08f52481David Lawrence * Ensure the tv_sec value fits in t->seconds.
6fa1cb5754695d550a58c6e8978fda65f5146af7David Lawrence */
6fa1cb5754695d550a58c6e8978fda65f5146af7David Lawrence if (sizeof(tv.tv_sec) > sizeof(t->seconds) &&
5eb91bd90e3ad3426e5e3213031556a737cf3809Mark Andrews ((tv.tv_sec | (unsigned int)-1) ^ (unsigned int)-1) != 0U)
6fa1cb5754695d550a58c6e8978fda65f5146af7David Lawrence return (ISC_R_RANGE);
6fa1cb5754695d550a58c6e8978fda65f5146af7David Lawrence
4bed2e84a34b37259b85e5c092d51c122ef58c3cBob Halley t->seconds = tv.tv_sec;
6fa1cb5754695d550a58c6e8978fda65f5146af7David Lawrence t->nanoseconds = tv.tv_usec * NS_PER_US;
94e25967cda41b886e33ec254b917d21df21a187Bob Halley
94e25967cda41b886e33ec254b917d21df21a187Bob Halley return (ISC_R_SUCCESS);
94e25967cda41b886e33ec254b917d21df21a187Bob Halley}
94e25967cda41b886e33ec254b917d21df21a187Bob Halley
afdb3abb9b06ed4070ac9021f1f4427b4cb3a286Bob Halleyisc_result_t
26f327f1f53afdb8256affa1c197ed138bf3cb2fAndreas Gustafssonisc_time_nowplusinterval(isc_time_t *t, const isc_interval_t *i) {
afdb3abb9b06ed4070ac9021f1f4427b4cb3a286Bob Halley struct timeval tv;
4b87939256ede703385e9cab92d3c58d03c31098Mark Andrews char strbuf[ISC_STRERRORSIZE];
afdb3abb9b06ed4070ac9021f1f4427b4cb3a286Bob Halley
afdb3abb9b06ed4070ac9021f1f4427b4cb3a286Bob Halley REQUIRE(t != NULL);
afdb3abb9b06ed4070ac9021f1f4427b4cb3a286Bob Halley REQUIRE(i != NULL);
6fa1cb5754695d550a58c6e8978fda65f5146af7David Lawrence INSIST(i->nanoseconds < NS_PER_S);
6fa1cb5754695d550a58c6e8978fda65f5146af7David Lawrence
afdb3abb9b06ed4070ac9021f1f4427b4cb3a286Bob Halley if (gettimeofday(&tv, NULL) == -1) {
4b87939256ede703385e9cab92d3c58d03c31098Mark Andrews isc__strerror(errno, strbuf, sizeof(strbuf));
4b87939256ede703385e9cab92d3c58d03c31098Mark Andrews UNEXPECTED_ERROR(__FILE__, __LINE__, "%s", strbuf);
afdb3abb9b06ed4070ac9021f1f4427b4cb3a286Bob Halley return (ISC_R_UNEXPECTED);
afdb3abb9b06ed4070ac9021f1f4427b4cb3a286Bob Halley }
afdb3abb9b06ed4070ac9021f1f4427b4cb3a286Bob Halley
6fa1cb5754695d550a58c6e8978fda65f5146af7David Lawrence /*
6fa1cb5754695d550a58c6e8978fda65f5146af7David Lawrence * Does POSIX guarantee the signedness of tv_sec and tv_usec? If not,
6fa1cb5754695d550a58c6e8978fda65f5146af7David Lawrence * then this test will generate warnings for platforms on which it is
6fa1cb5754695d550a58c6e8978fda65f5146af7David Lawrence * unsigned. In any event, the chances of any of these problems
6fa1cb5754695d550a58c6e8978fda65f5146af7David Lawrence * happening are pretty much zero, but since the libisc library ensures
6fa1cb5754695d550a58c6e8978fda65f5146af7David Lawrence * certain things to be true ...
6fa1cb5754695d550a58c6e8978fda65f5146af7David Lawrence */
70ec7dd74103fa9e92a6d56a0e3b0fc30e17af0dMark Andrews#if ISC_FIX_TV_USEC
70ec7dd74103fa9e92a6d56a0e3b0fc30e17af0dMark Andrews fix_tv_usec(&tv);
70ec7dd74103fa9e92a6d56a0e3b0fc30e17af0dMark Andrews if (tv.tv_sec < 0)
70ec7dd74103fa9e92a6d56a0e3b0fc30e17af0dMark Andrews return (ISC_R_UNEXPECTED);
70ec7dd74103fa9e92a6d56a0e3b0fc30e17af0dMark Andrews#else
6fa1cb5754695d550a58c6e8978fda65f5146af7David Lawrence if (tv.tv_sec < 0 || tv.tv_usec < 0 || tv.tv_usec >= US_PER_S)
6fa1cb5754695d550a58c6e8978fda65f5146af7David Lawrence return (ISC_R_UNEXPECTED);
70ec7dd74103fa9e92a6d56a0e3b0fc30e17af0dMark Andrews#endif
6fa1cb5754695d550a58c6e8978fda65f5146af7David Lawrence
6fa1cb5754695d550a58c6e8978fda65f5146af7David Lawrence /*
6fa1cb5754695d550a58c6e8978fda65f5146af7David Lawrence * Ensure the resulting seconds value fits in the size of an
6fa1cb5754695d550a58c6e8978fda65f5146af7David Lawrence * unsigned int. (It is written this way as a slight optimization;
6fa1cb5754695d550a58c6e8978fda65f5146af7David Lawrence * note that even if both values == INT_MAX, then when added
6fa1cb5754695d550a58c6e8978fda65f5146af7David Lawrence * and getting another 1 added below the result is UINT_MAX.)
6fa1cb5754695d550a58c6e8978fda65f5146af7David Lawrence */
6fa1cb5754695d550a58c6e8978fda65f5146af7David Lawrence if ((tv.tv_sec > INT_MAX || i->seconds > INT_MAX) &&
6fa1cb5754695d550a58c6e8978fda65f5146af7David Lawrence ((long long)tv.tv_sec + i->seconds > UINT_MAX))
6fa1cb5754695d550a58c6e8978fda65f5146af7David Lawrence return (ISC_R_RANGE);
6fa1cb5754695d550a58c6e8978fda65f5146af7David Lawrence
afdb3abb9b06ed4070ac9021f1f4427b4cb3a286Bob Halley t->seconds = tv.tv_sec + i->seconds;
6fa1cb5754695d550a58c6e8978fda65f5146af7David Lawrence t->nanoseconds = tv.tv_usec * NS_PER_US + i->nanoseconds;
9e8947d9e606b967d0792d0ab1ee7afac5e5f39dMark Andrews if (t->nanoseconds >= NS_PER_S) {
afdb3abb9b06ed4070ac9021f1f4427b4cb3a286Bob Halley t->seconds++;
6fa1cb5754695d550a58c6e8978fda65f5146af7David Lawrence t->nanoseconds -= NS_PER_S;
afdb3abb9b06ed4070ac9021f1f4427b4cb3a286Bob Halley }
afdb3abb9b06ed4070ac9021f1f4427b4cb3a286Bob Halley
afdb3abb9b06ed4070ac9021f1f4427b4cb3a286Bob Halley return (ISC_R_SUCCESS);
afdb3abb9b06ed4070ac9021f1f4427b4cb3a286Bob Halley}
afdb3abb9b06ed4070ac9021f1f4427b4cb3a286Bob Halley
94e25967cda41b886e33ec254b917d21df21a187Bob Halleyint
26f327f1f53afdb8256affa1c197ed138bf3cb2fAndreas Gustafssonisc_time_compare(const isc_time_t *t1, const isc_time_t *t2) {
bf6d2e39124ab3d51c253f7acad9a4abef059be6Bob Halley REQUIRE(t1 != NULL && t2 != NULL);
6fa1cb5754695d550a58c6e8978fda65f5146af7David Lawrence INSIST(t1->nanoseconds < NS_PER_S && t2->nanoseconds < NS_PER_S);
94e25967cda41b886e33ec254b917d21df21a187Bob Halley
bf6d2e39124ab3d51c253f7acad9a4abef059be6Bob Halley if (t1->seconds < t2->seconds)
94e25967cda41b886e33ec254b917d21df21a187Bob Halley return (-1);
bf6d2e39124ab3d51c253f7acad9a4abef059be6Bob Halley if (t1->seconds > t2->seconds)
94e25967cda41b886e33ec254b917d21df21a187Bob Halley return (1);
bf6d2e39124ab3d51c253f7acad9a4abef059be6Bob Halley if (t1->nanoseconds < t2->nanoseconds)
94e25967cda41b886e33ec254b917d21df21a187Bob Halley return (-1);
bf6d2e39124ab3d51c253f7acad9a4abef059be6Bob Halley if (t1->nanoseconds > t2->nanoseconds)
94e25967cda41b886e33ec254b917d21df21a187Bob Halley return (1);
94e25967cda41b886e33ec254b917d21df21a187Bob Halley return (0);
94e25967cda41b886e33ec254b917d21df21a187Bob Halley}
94e25967cda41b886e33ec254b917d21df21a187Bob Halley
6fa1cb5754695d550a58c6e8978fda65f5146af7David Lawrenceisc_result_t
26f327f1f53afdb8256affa1c197ed138bf3cb2fAndreas Gustafssonisc_time_add(const isc_time_t *t, const isc_interval_t *i, isc_time_t *result)
26f327f1f53afdb8256affa1c197ed138bf3cb2fAndreas Gustafsson{
4bed2e84a34b37259b85e5c092d51c122ef58c3cBob Halley REQUIRE(t != NULL && i != NULL && result != NULL);
6fa1cb5754695d550a58c6e8978fda65f5146af7David Lawrence INSIST(t->nanoseconds < NS_PER_S && i->nanoseconds < NS_PER_S);
6fa1cb5754695d550a58c6e8978fda65f5146af7David Lawrence
6fa1cb5754695d550a58c6e8978fda65f5146af7David Lawrence /*
6fa1cb5754695d550a58c6e8978fda65f5146af7David Lawrence * Ensure the resulting seconds value fits in the size of an
6fa1cb5754695d550a58c6e8978fda65f5146af7David Lawrence * unsigned int. (It is written this way as a slight optimization;
6fa1cb5754695d550a58c6e8978fda65f5146af7David Lawrence * note that even if both values == INT_MAX, then when added
6fa1cb5754695d550a58c6e8978fda65f5146af7David Lawrence * and getting another 1 added below the result is UINT_MAX.)
6fa1cb5754695d550a58c6e8978fda65f5146af7David Lawrence */
6fa1cb5754695d550a58c6e8978fda65f5146af7David Lawrence if ((t->seconds > INT_MAX || i->seconds > INT_MAX) &&
6fa1cb5754695d550a58c6e8978fda65f5146af7David Lawrence ((long long)t->seconds + i->seconds > UINT_MAX))
6fa1cb5754695d550a58c6e8978fda65f5146af7David Lawrence return (ISC_R_RANGE);
94e25967cda41b886e33ec254b917d21df21a187Bob Halley
4bed2e84a34b37259b85e5c092d51c122ef58c3cBob Halley result->seconds = t->seconds + i->seconds;
4bed2e84a34b37259b85e5c092d51c122ef58c3cBob Halley result->nanoseconds = t->nanoseconds + i->nanoseconds;
c89ac488df58cf6a37918cd00236eedf015830f8Andreas Gustafsson if (result->nanoseconds >= NS_PER_S) {
4bed2e84a34b37259b85e5c092d51c122ef58c3cBob Halley result->seconds++;
6fa1cb5754695d550a58c6e8978fda65f5146af7David Lawrence result->nanoseconds -= NS_PER_S;
94e25967cda41b886e33ec254b917d21df21a187Bob Halley }
6fa1cb5754695d550a58c6e8978fda65f5146af7David Lawrence
6fa1cb5754695d550a58c6e8978fda65f5146af7David Lawrence return (ISC_R_SUCCESS);
94e25967cda41b886e33ec254b917d21df21a187Bob Halley}
94e25967cda41b886e33ec254b917d21df21a187Bob Halley
6fa1cb5754695d550a58c6e8978fda65f5146af7David Lawrenceisc_result_t
26f327f1f53afdb8256affa1c197ed138bf3cb2fAndreas Gustafssonisc_time_subtract(const isc_time_t *t, const isc_interval_t *i,
26f327f1f53afdb8256affa1c197ed138bf3cb2fAndreas Gustafsson isc_time_t *result)
26f327f1f53afdb8256affa1c197ed138bf3cb2fAndreas Gustafsson{
4bed2e84a34b37259b85e5c092d51c122ef58c3cBob Halley REQUIRE(t != NULL && i != NULL && result != NULL);
6fa1cb5754695d550a58c6e8978fda65f5146af7David Lawrence INSIST(t->nanoseconds < NS_PER_S && i->nanoseconds < NS_PER_S);
6fa1cb5754695d550a58c6e8978fda65f5146af7David Lawrence
6fa1cb5754695d550a58c6e8978fda65f5146af7David Lawrence if ((unsigned int)t->seconds < i->seconds ||
6fa1cb5754695d550a58c6e8978fda65f5146af7David Lawrence ((unsigned int)t->seconds == i->seconds &&
6fa1cb5754695d550a58c6e8978fda65f5146af7David Lawrence t->nanoseconds < i->nanoseconds))
6fa1cb5754695d550a58c6e8978fda65f5146af7David Lawrence return (ISC_R_RANGE);
6fa1cb5754695d550a58c6e8978fda65f5146af7David Lawrence
4bed2e84a34b37259b85e5c092d51c122ef58c3cBob Halley result->seconds = t->seconds - i->seconds;
4bed2e84a34b37259b85e5c092d51c122ef58c3cBob Halley if (t->nanoseconds >= i->nanoseconds)
4bed2e84a34b37259b85e5c092d51c122ef58c3cBob Halley result->nanoseconds = t->nanoseconds - i->nanoseconds;
94e25967cda41b886e33ec254b917d21df21a187Bob Halley else {
6fa1cb5754695d550a58c6e8978fda65f5146af7David Lawrence result->nanoseconds = NS_PER_S - i->nanoseconds +
4bed2e84a34b37259b85e5c092d51c122ef58c3cBob Halley t->nanoseconds;
4bed2e84a34b37259b85e5c092d51c122ef58c3cBob Halley result->seconds--;
94e25967cda41b886e33ec254b917d21df21a187Bob Halley }
6fa1cb5754695d550a58c6e8978fda65f5146af7David Lawrence
6fa1cb5754695d550a58c6e8978fda65f5146af7David Lawrence return (ISC_R_SUCCESS);
94e25967cda41b886e33ec254b917d21df21a187Bob Halley}
4ad9b25e6ddf948ffb3b8198c5540d251f26c52eDavid Lawrence
4ad9b25e6ddf948ffb3b8198c5540d251f26c52eDavid Lawrenceisc_uint64_t
26f327f1f53afdb8256affa1c197ed138bf3cb2fAndreas Gustafssonisc_time_microdiff(const isc_time_t *t1, const isc_time_t *t2) {
4ad9b25e6ddf948ffb3b8198c5540d251f26c52eDavid Lawrence isc_uint64_t i1, i2, i3;
4ad9b25e6ddf948ffb3b8198c5540d251f26c52eDavid Lawrence
4ad9b25e6ddf948ffb3b8198c5540d251f26c52eDavid Lawrence REQUIRE(t1 != NULL && t2 != NULL);
6fa1cb5754695d550a58c6e8978fda65f5146af7David Lawrence INSIST(t1->nanoseconds < NS_PER_S && t2->nanoseconds < NS_PER_S);
4ad9b25e6ddf948ffb3b8198c5540d251f26c52eDavid Lawrence
6fa1cb5754695d550a58c6e8978fda65f5146af7David Lawrence i1 = (isc_uint64_t)t1->seconds * NS_PER_S + t1->nanoseconds;
6fa1cb5754695d550a58c6e8978fda65f5146af7David Lawrence i2 = (isc_uint64_t)t2->seconds * NS_PER_S + t2->nanoseconds;
4ad9b25e6ddf948ffb3b8198c5540d251f26c52eDavid Lawrence
4ad9b25e6ddf948ffb3b8198c5540d251f26c52eDavid Lawrence if (i1 <= i2)
4ad9b25e6ddf948ffb3b8198c5540d251f26c52eDavid Lawrence return (0);
4ad9b25e6ddf948ffb3b8198c5540d251f26c52eDavid Lawrence
4ad9b25e6ddf948ffb3b8198c5540d251f26c52eDavid Lawrence i3 = i1 - i2;
4ad9b25e6ddf948ffb3b8198c5540d251f26c52eDavid Lawrence
4ad9b25e6ddf948ffb3b8198c5540d251f26c52eDavid Lawrence /*
4ad9b25e6ddf948ffb3b8198c5540d251f26c52eDavid Lawrence * Convert to microseconds.
4ad9b25e6ddf948ffb3b8198c5540d251f26c52eDavid Lawrence */
0874abad14e3e9ecfc3dc1a1a2b9969f2f027724Mark Andrews i3 /= NS_PER_US;
4ad9b25e6ddf948ffb3b8198c5540d251f26c52eDavid Lawrence
4ad9b25e6ddf948ffb3b8198c5540d251f26c52eDavid Lawrence return (i3);
4ad9b25e6ddf948ffb3b8198c5540d251f26c52eDavid Lawrence}
114d0d1642b5ede0ab154532159fe38c30762d82David Lawrence
114d0d1642b5ede0ab154532159fe38c30762d82David Lawrenceisc_uint32_t
ae5df22719a9e2c252ea1fcccd2cadb44c8bd8d4Mark Andrewsisc_time_seconds(const isc_time_t *t) {
585529aaeb95a71cd3d95df2602a4688fc7c3292David Lawrence REQUIRE(t != NULL);
6fa1cb5754695d550a58c6e8978fda65f5146af7David Lawrence INSIST(t->nanoseconds < NS_PER_S);
585529aaeb95a71cd3d95df2602a4688fc7c3292David Lawrence
114d0d1642b5ede0ab154532159fe38c30762d82David Lawrence return ((isc_uint32_t)t->seconds);
114d0d1642b5ede0ab154532159fe38c30762d82David Lawrence}
114d0d1642b5ede0ab154532159fe38c30762d82David Lawrence
6fa1cb5754695d550a58c6e8978fda65f5146af7David Lawrenceisc_result_t
26f327f1f53afdb8256affa1c197ed138bf3cb2fAndreas Gustafssonisc_time_secondsastimet(const isc_time_t *t, time_t *secondsp) {
6fa1cb5754695d550a58c6e8978fda65f5146af7David Lawrence time_t seconds;
6fa1cb5754695d550a58c6e8978fda65f5146af7David Lawrence
6fa1cb5754695d550a58c6e8978fda65f5146af7David Lawrence REQUIRE(t != NULL);
6fa1cb5754695d550a58c6e8978fda65f5146af7David Lawrence INSIST(t->nanoseconds < NS_PER_S);
6fa1cb5754695d550a58c6e8978fda65f5146af7David Lawrence
6fa1cb5754695d550a58c6e8978fda65f5146af7David Lawrence /*
6fa1cb5754695d550a58c6e8978fda65f5146af7David Lawrence * Ensure that the number of seconds represented by t->seconds
6fa1cb5754695d550a58c6e8978fda65f5146af7David Lawrence * can be represented by a time_t. Since t->seconds is an unsigned
6fa1cb5754695d550a58c6e8978fda65f5146af7David Lawrence * int and since time_t is mostly opaque, this is trickier than
6fa1cb5754695d550a58c6e8978fda65f5146af7David Lawrence * it seems. (This standardized opaqueness of time_t is *very*
6fa1cb5754695d550a58c6e8978fda65f5146af7David Lawrence * frustrating; time_t is not even limited to being an integral
6fa1cb5754695d550a58c6e8978fda65f5146af7David Lawrence * type.)
6fa1cb5754695d550a58c6e8978fda65f5146af7David Lawrence *
6fa1cb5754695d550a58c6e8978fda65f5146af7David Lawrence * The mission, then, is to avoid generating any kind of warning
6fa1cb5754695d550a58c6e8978fda65f5146af7David Lawrence * about "signed versus unsigned" while trying to determine if the
6fa1cb5754695d550a58c6e8978fda65f5146af7David Lawrence * the unsigned int t->seconds is out range for tv_sec, which is
6fa1cb5754695d550a58c6e8978fda65f5146af7David Lawrence * pretty much only true if time_t is a signed integer of the same
40f53fa8d9c6a4fc38c0014495e7a42b08f52481David Lawrence * size as the return value of isc_time_seconds.
6fa1cb5754695d550a58c6e8978fda65f5146af7David Lawrence *
269c07173e24d7811e2fd09304023e3104fcbe0bMark Andrews * If the paradox in the if clause below is true, t->seconds is out
269c07173e24d7811e2fd09304023e3104fcbe0bMark Andrews * of range for time_t.
6fa1cb5754695d550a58c6e8978fda65f5146af7David Lawrence */
6fa1cb5754695d550a58c6e8978fda65f5146af7David Lawrence seconds = (time_t)t->seconds;
6fa1cb5754695d550a58c6e8978fda65f5146af7David Lawrence
6fa1cb5754695d550a58c6e8978fda65f5146af7David Lawrence INSIST(sizeof(unsigned int) == sizeof(isc_uint32_t));
6fa1cb5754695d550a58c6e8978fda65f5146af7David Lawrence INSIST(sizeof(time_t) >= sizeof(isc_uint32_t));
6fa1cb5754695d550a58c6e8978fda65f5146af7David Lawrence
5fa46bc91672ef5737aee6f99763161511566c24Tinderbox User if (t->seconds > (~0U>>1) && seconds <= (time_t)(~0U>>1))
6fa1cb5754695d550a58c6e8978fda65f5146af7David Lawrence return (ISC_R_RANGE);
6fa1cb5754695d550a58c6e8978fda65f5146af7David Lawrence
6fa1cb5754695d550a58c6e8978fda65f5146af7David Lawrence *secondsp = seconds;
6fa1cb5754695d550a58c6e8978fda65f5146af7David Lawrence
6fa1cb5754695d550a58c6e8978fda65f5146af7David Lawrence return (ISC_R_SUCCESS);
6fa1cb5754695d550a58c6e8978fda65f5146af7David Lawrence}
6fa1cb5754695d550a58c6e8978fda65f5146af7David Lawrence
114d0d1642b5ede0ab154532159fe38c30762d82David Lawrenceisc_uint32_t
26f327f1f53afdb8256affa1c197ed138bf3cb2fAndreas Gustafssonisc_time_nanoseconds(const isc_time_t *t) {
585529aaeb95a71cd3d95df2602a4688fc7c3292David Lawrence REQUIRE(t != NULL);
585529aaeb95a71cd3d95df2602a4688fc7c3292David Lawrence
6fa1cb5754695d550a58c6e8978fda65f5146af7David Lawrence ENSURE(t->nanoseconds < NS_PER_S);
114d0d1642b5ede0ab154532159fe38c30762d82David Lawrence
114d0d1642b5ede0ab154532159fe38c30762d82David Lawrence return ((isc_uint32_t)t->nanoseconds);
114d0d1642b5ede0ab154532159fe38c30762d82David Lawrence}
c8563aaf86c04f0e2284bcc8e444a0651c157ea0Andreas Gustafsson
c8563aaf86c04f0e2284bcc8e444a0651c157ea0Andreas Gustafssonvoid
c8563aaf86c04f0e2284bcc8e444a0651c157ea0Andreas Gustafssonisc_time_formattimestamp(const isc_time_t *t, char *buf, unsigned int len) {
c8563aaf86c04f0e2284bcc8e444a0651c157ea0Andreas Gustafsson time_t now;
c8563aaf86c04f0e2284bcc8e444a0651c157ea0Andreas Gustafsson unsigned int flen;
4162d3b36d1a3c25724c7e37ce839f67b2352bbbMark Andrews#ifdef ISC_PLATFORM_USETHREADS
4162d3b36d1a3c25724c7e37ce839f67b2352bbbMark Andrews struct tm tm;
4162d3b36d1a3c25724c7e37ce839f67b2352bbbMark Andrews#endif
c8563aaf86c04f0e2284bcc8e444a0651c157ea0Andreas Gustafsson
c3237dec879f82855403ff7e3ba87b298172efd5Mark Andrews REQUIRE(t != NULL);
c3237dec879f82855403ff7e3ba87b298172efd5Mark Andrews INSIST(t->nanoseconds < NS_PER_S);
c3237dec879f82855403ff7e3ba87b298172efd5Mark Andrews REQUIRE(buf != NULL);
6184f9fc1e65ef131ea308a1a92882595bb1aeeaAndreas Gustafsson REQUIRE(len > 0);
6184f9fc1e65ef131ea308a1a92882595bb1aeeaAndreas Gustafsson
c8563aaf86c04f0e2284bcc8e444a0651c157ea0Andreas Gustafsson now = (time_t) t->seconds;
4162d3b36d1a3c25724c7e37ce839f67b2352bbbMark Andrews#ifdef ISC_PLATFORM_USETHREADS
4162d3b36d1a3c25724c7e37ce839f67b2352bbbMark Andrews flen = strftime(buf, len, "%d-%b-%Y %X", localtime_r(&now, &tm));
4162d3b36d1a3c25724c7e37ce839f67b2352bbbMark Andrews#else
c36f45e354c0d5b6ab9f821bfe315d0ce9d95a29Mark Andrews flen = strftime(buf, len, "%d-%b-%Y %X", localtime(&now));
4162d3b36d1a3c25724c7e37ce839f67b2352bbbMark Andrews#endif
ff6e834f7d48d4b116627ecf8cafa0fbacc25bd4Andreas Gustafsson INSIST(flen < len);
ff6e834f7d48d4b116627ecf8cafa0fbacc25bd4Andreas Gustafsson if (flen != 0)
ff6e834f7d48d4b116627ecf8cafa0fbacc25bd4Andreas Gustafsson snprintf(buf + flen, len - flen,
bb5d14d7243d71e03d262ff175b355b52873e195Evan Hunt ".%03u", t->nanoseconds / NS_PER_MS);
a6f0e9c985220f0e4509777e6528afb64e0ad576Mukund Sivaraman else {
5a93d3be4e0c652f455066bb764416173a00c951Mark Andrews strlcpy(buf, "99-Bad-9999 99:99:99.999", len);
a6f0e9c985220f0e4509777e6528afb64e0ad576Mukund Sivaraman }
c8563aaf86c04f0e2284bcc8e444a0651c157ea0Andreas Gustafsson}
186e7f37c9fc985a7a7264cc8170e48a25bed434Mark Andrews
186e7f37c9fc985a7a7264cc8170e48a25bed434Mark Andrewsvoid
186e7f37c9fc985a7a7264cc8170e48a25bed434Mark Andrewsisc_time_formathttptimestamp(const isc_time_t *t, char *buf, unsigned int len) {
186e7f37c9fc985a7a7264cc8170e48a25bed434Mark Andrews time_t now;
186e7f37c9fc985a7a7264cc8170e48a25bed434Mark Andrews unsigned int flen;
4162d3b36d1a3c25724c7e37ce839f67b2352bbbMark Andrews#ifdef ISC_PLATFORM_USETHREADS
4162d3b36d1a3c25724c7e37ce839f67b2352bbbMark Andrews struct tm tm;
4162d3b36d1a3c25724c7e37ce839f67b2352bbbMark Andrews#endif
186e7f37c9fc985a7a7264cc8170e48a25bed434Mark Andrews
c3237dec879f82855403ff7e3ba87b298172efd5Mark Andrews REQUIRE(t != NULL);
c3237dec879f82855403ff7e3ba87b298172efd5Mark Andrews INSIST(t->nanoseconds < NS_PER_S);
c3237dec879f82855403ff7e3ba87b298172efd5Mark Andrews REQUIRE(buf != NULL);
186e7f37c9fc985a7a7264cc8170e48a25bed434Mark Andrews REQUIRE(len > 0);
186e7f37c9fc985a7a7264cc8170e48a25bed434Mark Andrews
591389c7d44e5ca20c357627dd179772cfefaaccEvan Hunt /*
591389c7d44e5ca20c357627dd179772cfefaaccEvan Hunt * 5 spaces, 1 comma, 3 GMT, 2 %d, 4 %Y, 8 %H:%M:%S, 3+ %a, 3+ %b (29+)
591389c7d44e5ca20c357627dd179772cfefaaccEvan Hunt */
186e7f37c9fc985a7a7264cc8170e48a25bed434Mark Andrews now = (time_t)t->seconds;
4162d3b36d1a3c25724c7e37ce839f67b2352bbbMark Andrews#ifdef ISC_PLATFORM_USETHREADS
4162d3b36d1a3c25724c7e37ce839f67b2352bbbMark Andrews flen = strftime(buf, len, "%a, %d %b %Y %H:%M:%S GMT",
4162d3b36d1a3c25724c7e37ce839f67b2352bbbMark Andrews gmtime_r(&now, &tm));
4162d3b36d1a3c25724c7e37ce839f67b2352bbbMark Andrews#else
186e7f37c9fc985a7a7264cc8170e48a25bed434Mark Andrews flen = strftime(buf, len, "%a, %d %b %Y %H:%M:%S GMT", gmtime(&now));
4162d3b36d1a3c25724c7e37ce839f67b2352bbbMark Andrews#endif
186e7f37c9fc985a7a7264cc8170e48a25bed434Mark Andrews INSIST(flen < len);
186e7f37c9fc985a7a7264cc8170e48a25bed434Mark Andrews}
186e7f37c9fc985a7a7264cc8170e48a25bed434Mark Andrews
789252d55f025db52ee02aa933c9f09a4aadfa97Evan Huntisc_result_t
789252d55f025db52ee02aa933c9f09a4aadfa97Evan Huntisc_time_parsehttptimestamp(char *buf, isc_time_t *t) {
789252d55f025db52ee02aa933c9f09a4aadfa97Evan Hunt struct tm t_tm;
789252d55f025db52ee02aa933c9f09a4aadfa97Evan Hunt time_t when;
789252d55f025db52ee02aa933c9f09a4aadfa97Evan Hunt char *p;
789252d55f025db52ee02aa933c9f09a4aadfa97Evan Hunt
789252d55f025db52ee02aa933c9f09a4aadfa97Evan Hunt REQUIRE(buf != NULL);
789252d55f025db52ee02aa933c9f09a4aadfa97Evan Hunt REQUIRE(t != NULL);
c3237dec879f82855403ff7e3ba87b298172efd5Mark Andrews
a147de10fe5e19e593d42152ffd6879eca69860dEvan Hunt p = isc_tm_strptime(buf, "%a, %d %b %Y %H:%M:%S", &t_tm);
789252d55f025db52ee02aa933c9f09a4aadfa97Evan Hunt if (p == NULL)
789252d55f025db52ee02aa933c9f09a4aadfa97Evan Hunt return (ISC_R_UNEXPECTED);
a147de10fe5e19e593d42152ffd6879eca69860dEvan Hunt when = isc_tm_timegm(&t_tm);
789252d55f025db52ee02aa933c9f09a4aadfa97Evan Hunt if (when == -1)
789252d55f025db52ee02aa933c9f09a4aadfa97Evan Hunt return (ISC_R_UNEXPECTED);
789252d55f025db52ee02aa933c9f09a4aadfa97Evan Hunt isc_time_set(t, when, 0);
789252d55f025db52ee02aa933c9f09a4aadfa97Evan Hunt return (ISC_R_SUCCESS);
789252d55f025db52ee02aa933c9f09a4aadfa97Evan Hunt}
789252d55f025db52ee02aa933c9f09a4aadfa97Evan Hunt
186e7f37c9fc985a7a7264cc8170e48a25bed434Mark Andrewsvoid
186e7f37c9fc985a7a7264cc8170e48a25bed434Mark Andrewsisc_time_formatISO8601(const isc_time_t *t, char *buf, unsigned int len) {
186e7f37c9fc985a7a7264cc8170e48a25bed434Mark Andrews time_t now;
186e7f37c9fc985a7a7264cc8170e48a25bed434Mark Andrews unsigned int flen;
4162d3b36d1a3c25724c7e37ce839f67b2352bbbMark Andrews#ifdef ISC_PLATFORM_USETHREADS
4162d3b36d1a3c25724c7e37ce839f67b2352bbbMark Andrews struct tm tm;
4162d3b36d1a3c25724c7e37ce839f67b2352bbbMark Andrews#endif
186e7f37c9fc985a7a7264cc8170e48a25bed434Mark Andrews
c3237dec879f82855403ff7e3ba87b298172efd5Mark Andrews REQUIRE(t != NULL);
c3237dec879f82855403ff7e3ba87b298172efd5Mark Andrews INSIST(t->nanoseconds < NS_PER_S);
c3237dec879f82855403ff7e3ba87b298172efd5Mark Andrews REQUIRE(buf != NULL);
186e7f37c9fc985a7a7264cc8170e48a25bed434Mark Andrews REQUIRE(len > 0);
186e7f37c9fc985a7a7264cc8170e48a25bed434Mark Andrews
186e7f37c9fc985a7a7264cc8170e48a25bed434Mark Andrews now = (time_t)t->seconds;
4162d3b36d1a3c25724c7e37ce839f67b2352bbbMark Andrews#ifdef ISC_PLATFORM_USETHREADS
4162d3b36d1a3c25724c7e37ce839f67b2352bbbMark Andrews flen = strftime(buf, len, "%Y-%m-%dT%H:%M:%SZ", gmtime_r(&now, &tm));
4162d3b36d1a3c25724c7e37ce839f67b2352bbbMark Andrews#else
96ea71632887c58a9d00f47eb318bf76b35903c3Mark Andrews flen = strftime(buf, len, "%Y-%m-%dT%H:%M:%SZ", gmtime(&now));
4162d3b36d1a3c25724c7e37ce839f67b2352bbbMark Andrews#endif
186e7f37c9fc985a7a7264cc8170e48a25bed434Mark Andrews INSIST(flen < len);
186e7f37c9fc985a7a7264cc8170e48a25bed434Mark Andrews}
bb5d14d7243d71e03d262ff175b355b52873e195Evan Hunt
bb5d14d7243d71e03d262ff175b355b52873e195Evan Huntvoid
bb5d14d7243d71e03d262ff175b355b52873e195Evan Huntisc_time_formatISO8601ms(const isc_time_t *t, char *buf, unsigned int len) {
bb5d14d7243d71e03d262ff175b355b52873e195Evan Hunt time_t now;
bb5d14d7243d71e03d262ff175b355b52873e195Evan Hunt unsigned int flen;
4162d3b36d1a3c25724c7e37ce839f67b2352bbbMark Andrews#ifdef ISC_PLATFORM_USETHREADS
4162d3b36d1a3c25724c7e37ce839f67b2352bbbMark Andrews struct tm tm;
4162d3b36d1a3c25724c7e37ce839f67b2352bbbMark Andrews#endif
bb5d14d7243d71e03d262ff175b355b52873e195Evan Hunt
c3237dec879f82855403ff7e3ba87b298172efd5Mark Andrews REQUIRE(t != NULL);
c3237dec879f82855403ff7e3ba87b298172efd5Mark Andrews INSIST(t->nanoseconds < NS_PER_S);
c3237dec879f82855403ff7e3ba87b298172efd5Mark Andrews REQUIRE(buf != NULL);
bb5d14d7243d71e03d262ff175b355b52873e195Evan Hunt REQUIRE(len > 0);
bb5d14d7243d71e03d262ff175b355b52873e195Evan Hunt
bb5d14d7243d71e03d262ff175b355b52873e195Evan Hunt now = (time_t)t->seconds;
4162d3b36d1a3c25724c7e37ce839f67b2352bbbMark Andrews#ifdef ISC_PLATFORM_USETHREADS
4162d3b36d1a3c25724c7e37ce839f67b2352bbbMark Andrews flen = strftime(buf, len, "%Y-%m-%dT%H:%M:%SZ", gmtime_r(&now, &tm));
4162d3b36d1a3c25724c7e37ce839f67b2352bbbMark Andrews#else
bb5d14d7243d71e03d262ff175b355b52873e195Evan Hunt flen = strftime(buf, len, "%Y-%m-%dT%H:%M:%SZ", gmtime(&now));
4162d3b36d1a3c25724c7e37ce839f67b2352bbbMark Andrews#endif
bb5d14d7243d71e03d262ff175b355b52873e195Evan Hunt INSIST(flen < len);
c3237dec879f82855403ff7e3ba87b298172efd5Mark Andrews if (flen > 0U && len - flen >= 5) {
c3237dec879f82855403ff7e3ba87b298172efd5Mark Andrews flen -= 1; /* rewind one character (Z) */
bb5d14d7243d71e03d262ff175b355b52873e195Evan Hunt snprintf(buf + flen, len - flen, ".%03uZ",
bb5d14d7243d71e03d262ff175b355b52873e195Evan Hunt t->nanoseconds / NS_PER_MS);
bb5d14d7243d71e03d262ff175b355b52873e195Evan Hunt }
bb5d14d7243d71e03d262ff175b355b52873e195Evan Hunt}