]> git.ipfire.org Git - thirdparty/bind9.git/commitdiff
[master] portable strptime/timegm
authorEvan Hunt <each@isc.org>
Wed, 15 Jan 2014 07:12:17 +0000 (23:12 -0800)
committerEvan Hunt <each@isc.org>
Wed, 15 Jan 2014 07:17:47 +0000 (23:17 -0800)
3709. [port] Use built-in versions of strptime() and timegm()
on all platforms to avoid portability issues.
[RT #35183]

12 files changed:
CHANGES
lib/isc/Makefile.in
lib/isc/include/isc/Makefile.in
lib/isc/include/isc/tm.h [new file with mode: 0644]
lib/isc/tm.c [moved from lib/isc/win32/strptime.c with 80% similarity]
lib/isc/unix/time.c
lib/isc/win32/libisc.def.in
lib/isc/win32/libisc.dsp.in
lib/isc/win32/libisc.mak.in
lib/isc/win32/libisc.vcxproj.filters.in
lib/isc/win32/libisc.vcxproj.in
lib/isc/win32/time.c

diff --git a/CHANGES b/CHANGES
index b5600676d5b91d9a16cfa2a604b429e53387636f..a7de036e47fd7981b22383a6cc9242e11cf975a4 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -1,3 +1,7 @@
+3709.  [port]          Use built-in versions of strptime() and timegm()
+                       on all platforms to avoid portability issues.
+                       [RT #35183]
+
 3708.  [bug]           Address a portentry locking issue in dispatch.c.
                        [RT #35128]
 
index 1d5fc4dd0a8693d7c7de19eeff03d0ef4ab41a37..6da9e3c11252b11f7691118f61053bdea6c8ea4f 100644 (file)
@@ -66,7 +66,8 @@ OBJS =                @ISC_EXTRA_OBJS@ \
                rwlock.@O@ \
                safe.@O@ serial.@O@ sha1.@O@ sha2.@O@ sockaddr.@O@ stats.@O@ \
                string.@O@ strtoul.@O@ symtab.@O@ task.@O@ taskpool.@O@ \
-               timer.@O@ version.@O@ ${UNIXOBJS} ${NLSOBJS} ${THREADOBJS}
+               tm.@O@ timer.@O@ version.@O@ \
+               ${UNIXOBJS} ${NLSOBJS} ${THREADOBJS}
 SYMTBLOBJS =   backtrace-emptytbl.@O@
 
 # Alphabetically
@@ -82,7 +83,7 @@ SRCS =                @ISC_EXTRA_SRCS@ \
                ratelimiter.c refcount.c region.c regex.c result.c rwlock.c \
                safe.c serial.c sha1.c sha2.c sockaddr.c stats.c string.c \
                strtoul.c symtab.c symtbl-empty.c task.c taskpool.c timer.c \
-               version.c
+               tm.c version.c
 
 LIBS =         @LIBS@
 
index 2da5845cd69bdbe0eed62a26152865eb3506f3d4..e01e10302124bd96935d229c18a1e8411eee608d 100644 (file)
@@ -31,16 +31,15 @@ HEADERS =   app.h assertions.h base64.h bind9.h bitstring.h boolean.h \
                eventclass.h file.h formatcheck.h fsaccess.h \
                hash.h heap.h hex.h hmacmd5.h hmacsha.h \
                httpd.h \
-               interfaceiter.h @ISC_IPV6_H@ iterated_hash.h json.h lang.h lex.h \
-               lfsr.h lib.h list.h log.h \
+               interfaceiter.h @ISC_IPV6_H@ iterated_hash.h json.h \
+               lang.h lex.h lfsr.h lib.h list.h log.h \
                magic.h md5.h mem.h msgcat.h msgs.h mutexblock.h \
                netaddr.h ondestroy.h os.h parseint.h \
                print.h quota.h radix.h random.h ratelimiter.h \
                refcount.h regex.h region.h resource.h \
                result.h resultclass.h rwlock.h safe.h serial.h sha1.h sha2.h \
-               sockaddr.h socket.h stdio.h stdlib.h string.h \
-               symtab.h \
-               task.h taskpool.h timer.h types.h util.h version.h \
+               sockaddr.h socket.h stdio.h stdlib.h string.h symtab.h \
+               task.h taskpool.h timer.h tm.h types.h util.h version.h \
                xml.h
 
 SUBDIRS =
diff --git a/lib/isc/include/isc/tm.h b/lib/isc/include/isc/tm.h
new file mode 100644 (file)
index 0000000..43e2aa3
--- /dev/null
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2014  Internet Systems Consortium, Inc. ("ISC")
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+ * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+ * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#ifndef ISC_TM_H
+#define ISC_TM_H 1
+
+/*! \file isc/tm.h
+ * Provides portable conversion routines for struct tm.
+ */
+
+#include <time.h>
+
+ISC_LANG_BEGINDECLS
+
+time_t
+isc_tm_timegm(struct tm *tm);
+/*
+ * Convert a tm structure to time_t, using UTC rather than the local
+ * time zone.
+ */
+
+char *
+isc_tm_strptime(const char *buf, const char *fmt, struct tm *tm);
+/*
+ * Parse a formatted date string into struct tm.
+ */
+
+ISC_LANG_ENDDECLS
+
+#endif /* ISC_TIMER_H */
similarity index 80%
rename from lib/isc/win32/strptime.c
rename to lib/isc/tm.c
index 10dcec1ec1749c401c237fb8b8d0e52e7d8bc81c..4f058a6c7c86d42c21e2839294cab7a100eb7449 100644 (file)
@@ -1,3 +1,19 @@
+/*
+ * Copyright (C) 2014  Internet Systems Consortium, Inc. ("ISC")
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+ * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+ * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
 /*-
  * Copyright (c) 1997, 1998 The NetBSD Foundation, Inc.
  * All rights reserved.
  * POSSIBILITY OF SUCH DAMAGE.
  */
 
+#include <config.h>
+
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
 #include <time.h>
 
+/*
+ * Portable conversion routines for struct tm, replacing
+ * timegm() and strptime(), which are not available on all
+ * platforms and don't always behave the same way when they
+ * are.
+ */
+
 /*
  * We do not implement alternate representations. However, we always
  * check whether a given modifier is allowed for a certain conversion.
@@ -50,8 +75,6 @@
 #define TM_YEAR_BASE 1900
 #endif
 
-static int conv_num(const char **, int *, int, int);
-
 static const char *day[7] = {
        "Sunday", "Monday", "Tuesday", "Wednesday", "Thursday",
        "Friday", "Saturday"
@@ -71,8 +94,57 @@ static const char *am_pm[2] = {
        "AM", "PM"
 };
 
-static char *
-strptime(const char *buf, const char *fmt, struct tm *tm) {
+static int
+conv_num(const char **buf, int *dest, int llim, int ulim) {
+       int result = 0;
+
+       /* The limit also determines the number of valid digits. */
+       int rulim = ulim;
+
+       if (**buf < '0' || **buf > '9')
+               return (0);
+
+       do {
+               result *= 10;
+               result += *(*buf)++ - '0';
+               rulim /= 10;
+       } while ((result * 10 <= ulim) &&
+                rulim && **buf >= '0' && **buf <= '9');
+
+       if (result < llim || result > ulim)
+               return (0);
+
+       *dest = result;
+       return (1);
+}
+
+time_t
+isc_tm_timegm(struct tm *tm) {
+       time_t ret;
+       int i, yday = 0, leapday;
+       int mdays[] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30 };
+
+       leapday = ((((tm->tm_year + 1900 ) % 4) == 0 &&
+                   ((tm->tm_year + 1900 ) % 100) != 0) ||
+                  ((tm->tm_year + 1900 ) % 400) == 0) ? 1 : 0;
+       mdays[1] += leapday;
+
+       yday = tm->tm_mday - 1;
+       for (i = 1; i <= tm->tm_mon; i++)
+               yday += mdays[i - 1];
+       ret = tm->tm_sec +
+             (60 * tm->tm_min) +
+             (3600 * tm->tm_hour) +
+             (86400 * (yday +
+                      ((tm->tm_year - 70) * 365) +
+                      ((tm->tm_year - 69) / 4) -
+                      ((tm->tm_year - 1) / 100) +
+                      ((tm->tm_year + 299) / 400)));
+       return (ret);
+}
+
+char *
+isc_tm_strptime(const char *buf, const char *fmt, struct tm *tm) {
        char c;
        const char *bp;
        size_t len = 0;
@@ -123,43 +195,43 @@ literal:
                 */
                case 'c':       /* Date and time, using the locale's format. */
                        LEGAL_ALT(ALT_E);
-                       if (!(bp = strptime(bp, "%x %X", tm)))
+                       if (!(bp = isc_tm_strptime(bp, "%x %X", tm)))
                                return (0);
                        break;
 
                case 'D':       /* The date as "%m/%d/%y". */
                        LEGAL_ALT(0);
-                       if (!(bp = strptime(bp, "%m/%d/%y", tm)))
+                       if (!(bp = isc_tm_strptime(bp, "%m/%d/%y", tm)))
                                return (0);
                        break;
 
                case 'R':       /* The time as "%H:%M". */
                        LEGAL_ALT(0);
-                       if (!(bp = strptime(bp, "%H:%M", tm)))
+                       if (!(bp = isc_tm_strptime(bp, "%H:%M", tm)))
                                return (0);
                        break;
 
                case 'r':       /* The time in 12-hour clock representation. */
                        LEGAL_ALT(0);
-                       if (!(bp = strptime(bp, "%I:%M:%S %p", tm)))
+                       if (!(bp = isc_tm_strptime(bp, "%I:%M:%S %p", tm)))
                                return (0);
                        break;
 
                case 'T':       /* The time as "%H:%M:%S". */
                        LEGAL_ALT(0);
-                       if (!(bp = strptime(bp, "%H:%M:%S", tm)))
+                       if (!(bp = isc_tm_strptime(bp, "%H:%M:%S", tm)))
                                return (0);
                        break;
 
                case 'X':       /* The time, using the locale's format. */
                        LEGAL_ALT(ALT_E);
-                       if (!(bp = strptime(bp, "%H:%M:%S", tm)))
+                       if (!(bp = isc_tm_strptime(bp, "%H:%M:%S", tm)))
                                return (0);
                        break;
 
                case 'x':       /* The date, using the locale's format. */
                        LEGAL_ALT(ALT_E);
-                       if (!(bp = strptime(bp, "%m/%d/%y", tm)))
+                       if (!(bp = isc_tm_strptime(bp, "%m/%d/%y", tm)))
                                return (0);
                        break;
 
@@ -366,27 +438,3 @@ literal:
        /* LINTED functional specification */
        return ((char *)bp);
 }
-
-static int
-conv_num(const char **buf, int *dest, int llim, int ulim) {
-       int result = 0;
-
-       /* The limit also determines the number of valid digits. */
-       int rulim = ulim;
-
-       if (**buf < '0' || **buf > '9')
-               return (0);
-
-       do {
-               result *= 10;
-               result += *(*buf)++ - '0';
-               rulim /= 10;
-       } while ((result * 10 <= ulim) &&
-                rulim && **buf >= '0' && **buf <= '9');
-
-       if (result < llim || result > ulim)
-               return (0);
-
-       *dest = result;
-       return (1);
-}
index 9039b06a880e890e202332385c989fb0a2736835..890b9192ba5add55dad81d641d883c57c7788e5e 100644 (file)
@@ -34,6 +34,7 @@
 #include <isc/strerror.h>
 #include <isc/string.h>
 #include <isc/time.h>
+#include <isc/tm.h>
 #include <isc/util.h>
 
 #define NS_PER_S       1000000000      /*%< Nanoseconds per second. */
@@ -408,31 +409,6 @@ isc_time_formathttptimestamp(const isc_time_t *t, char *buf, unsigned int len) {
        INSIST(flen < len);
 }
 
-static time_t
-timetfromtm(struct tm *tm) {
-       time_t ret;
-       int i, yday = 0, leapday;
-       int mdays[] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30 };
-
-       leapday = ((((tm->tm_year + 1900 ) % 4) == 0 &&
-                   ((tm->tm_year + 1900 ) % 100) != 0) ||
-                  ((tm->tm_year + 1900 ) % 400) == 0) ? 1 : 0;
-       mdays[1] += leapday;
-
-       yday = tm->tm_mday - 1;
-       for (i = 1; i <= tm->tm_mon; i++)
-               yday += mdays[i - 1];
-       ret = tm->tm_sec +
-             (60 * tm->tm_min) +
-             (3600 * tm->tm_hour) +
-             (86400 * (yday +
-                      ((tm->tm_year - 70) * 365) +
-                      ((tm->tm_year - 69) / 4) -
-                      ((tm->tm_year - 1) / 100) +
-                      ((tm->tm_year + 299) / 400)));
-       return (ret);
-}
-
 isc_result_t
 isc_time_parsehttptimestamp(char *buf, isc_time_t *t) {
        struct tm t_tm;
@@ -441,10 +417,10 @@ isc_time_parsehttptimestamp(char *buf, isc_time_t *t) {
 
        REQUIRE(buf != NULL);
        REQUIRE(t != NULL);
-       p = strptime(buf, "%a, %d %b %Y %H:%M:%S", &t_tm);
+       p = isc_tm_strptime(buf, "%a, %d %b %Y %H:%M:%S", &t_tm);
        if (p == NULL)
                return (ISC_R_UNEXPECTED);
-       when = timetfromtm(&t_tm);
+       when = isc_tm_timegm(&t_tm);
        if (when == -1)
                return (ISC_R_UNEXPECTED);
        isc_time_set(t, when, 0);
index de504c39261ed4ab6fa6ac5e6d1fc61f5bdaade1..d236307e61b245684c9430b3bfb64ab322a19e07 100644 (file)
@@ -605,6 +605,8 @@ isc_timer_touch
 isc_timermgr_create
 isc_timermgr_destroy
 isc_timermgr_poke
+isc_tm_timegm
+isc_tm_strptime
 isc_win32os_majorversion
 isc_win32os_minorversion
 isc_win32os_servicepackmajor
index f6ea61721dae3c5cd881813dd2f991993e4d1163..08fe918c4c0d1acc3515886ec59ff22b02f5722b 100644 (file)
@@ -597,6 +597,10 @@ SOURCE=..\include\isc\timer.h
 # End Source File
 # Begin Source File
 
+SOURCE=..\include\isc\tm.h
+# End Source File
+# Begin Source File
+
 SOURCE=.\include\isc\win32os.h
 # End Source File
 # Begin Source File
@@ -855,6 +859,10 @@ SOURCE=..\taskpool.c
 
 SOURCE=..\timer.c
 # End Source File
+# Begin Source File
+
+SOURCE=..\tm.c
+# End Source File
 # End Group
 @IF ATOMIC
 # Begin Source File
index 8ea2bd749174ee6344bb855fe71e30c76e3a111f..554429a34361169e3a0ef22025f393243341c0de 100644 (file)
@@ -194,6 +194,7 @@ CLEAN :
        -@erase "$(INTDIR)\thread.obj"
        -@erase "$(INTDIR)\time.obj"
        -@erase "$(INTDIR)\timer.obj"
+       -@erase "$(INTDIR)\tm.obj"
        -@erase "$(INTDIR)\vc60.idb"
        -@erase "$(INTDIR)\version.obj"
        -@erase "$(INTDIR)\win32os.obj"
@@ -301,6 +302,7 @@ LINK32_OBJS= \
        "$(INTDIR)\task.obj" \
        "$(INTDIR)\taskpool.obj" \
        "$(INTDIR)\timer.obj" \
+       "$(INTDIR)\tm.obj" \
        "$(INTDIR)\parseint.obj" \
        "$(INTDIR)\pool.obj" \
        "$(INTDIR)\portset.obj" \
@@ -485,6 +487,8 @@ CLEAN :
        -@erase "$(INTDIR)\time.sbr"
        -@erase "$(INTDIR)\timer.obj"
        -@erase "$(INTDIR)\timer.sbr"
+       -@erase "$(INTDIR)\tm.obj"
+       -@erase "$(INTDIR)\tm.sbr"
        -@erase "$(INTDIR)\vc60.idb"
        -@erase "$(INTDIR)\vc60.pdb"
        -@erase "$(INTDIR)\version.obj"
@@ -589,6 +593,7 @@ BSC32_SBRS= \
        "$(INTDIR)\task.sbr" \
        "$(INTDIR)\taskpool.sbr" \
        "$(INTDIR)\timer.sbr" \
+       "$(INTDIR)\tm.sbr" \
        "$(INTDIR)\parseint.sbr" \
        "$(INTDIR)\pool.sbr" \
        "$(INTDIR)\portset.sbr" \
@@ -686,6 +691,7 @@ LINK32_OBJS= \
        "$(INTDIR)\task.obj" \
        "$(INTDIR)\taskpool.obj" \
        "$(INTDIR)\timer.obj" \
+       "$(INTDIR)\tm.obj" \
        "$(INTDIR)\parseint.obj" \
        "$(INTDIR)\pool.obj" \
        "$(INTDIR)\portset.obj" \
@@ -2167,6 +2173,24 @@ SOURCE=..\timer.c
        $(CPP) $(CPP_PROJ) $(SOURCE)
 
 
+!ENDIF 
+
+SOURCE=..\tm.c
+
+!IF  "$(CFG)" == "libisc - @PLATFORM@ Release"
+
+
+"$(INTDIR)\tm.obj" : $(SOURCE) "$(INTDIR)"
+       $(CPP) $(CPP_PROJ) $(SOURCE)
+
+
+!ELSEIF  "$(CFG)" == "libisc - @PLATFORM@ Debug"
+
+
+"$(INTDIR)\tm.obj"     "$(INTDIR)\tm.sbr" : $(SOURCE) "$(INTDIR)"
+       $(CPP) $(CPP_PROJ) $(SOURCE)
+
+
 !ENDIF 
 
 
index 281b0df975e9e17d9f6d50730133a170d52c977e..8b25ec4534ef1ae8c694fd6ea27f28576b221608 100644 (file)
     <ClInclude Include="..\include\isc\timer.h">\r
       <Filter>Library Header Files</Filter>\r
     </ClInclude>\r
+    <ClInclude Include="..\include\isc\tm.h">\r
+      <Filter>Library Header Files</Filter>\r
+    </ClInclude>\r
     <ClInclude Include="..\include\isc\types.h">\r
       <Filter>Library Header Files</Filter>\r
     </ClInclude>\r
     <ClCompile Include="..\timer.c">\r
       <Filter>Library Source Files</Filter>\r
     </ClCompile>\r
+    <ClCompile Include="..\tm.c">\r
+      <Filter>Library Source Files</Filter>\r
+    </ClCompile>\r
   </ItemGroup>\r
-</Project>
\ No newline at end of file
+</Project>\r
index 09fcaddc2742b37fb1c1af47667c6cb0bc7f0b95..84f0db1236c147801727af76a2ad5be9185097ef 100644 (file)
@@ -332,6 +332,7 @@ copy /Y @VCREDIST_PATH@ ..\Build\Release\
     <ClInclude Include="..\include\isc\task.h" />\r
     <ClInclude Include="..\include\isc\taskpool.h" />\r
     <ClInclude Include="..\include\isc\timer.h" />\r
+    <ClInclude Include="..\include\isc\tm.h" />\r
     <ClInclude Include="..\include\isc\types.h" />\r
     <ClInclude Include="..\include\isc\util.h" />\r
     <ClInclude Include="..\include\isc\version.h" />\r
@@ -426,6 +427,7 @@ copy /Y @VCREDIST_PATH@ ..\Build\Release\
     <ClCompile Include="..\task.c" />\r
     <ClCompile Include="..\taskpool.c" />\r
     <ClCompile Include="..\timer.c" />\r
+    <ClCompile Include="..\tm.c" />\r
     <ClCompile Include="app.c" />\r
     <ClCompile Include="condition.c" />\r
     <ClCompile Include="dir.c" />\r
@@ -455,4 +457,4 @@ copy /Y @VCREDIST_PATH@ ..\Build\Release\
   <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />\r
   <ImportGroup Label="ExtensionTargets">\r
   </ImportGroup>\r
-</Project>
\ No newline at end of file
+</Project>\r
index 6c38e25a55539949f9c54d5203a7c7d13c245d0d..d6993f937e4acaa2f1958270a7dd45c95cb9433b 100644 (file)
@@ -30,6 +30,7 @@
 
 #include <isc/assertions.h>
 #include <isc/time.h>
+#include <isc/tm.h>
 #include <isc/util.h>
 
 /*
@@ -318,32 +319,6 @@ isc_time_formathttptimestamp(const isc_time_t *t, char *buf, unsigned int len) {
        }
 }
 
-static time_t
-timetfromtm(struct tm *tm) {
-       time_t ret;
-       int i, yday = 0, leapday;
-       int mdays[] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30 };
-
-       leapday = ((((tm->tm_year + 1900 ) % 4) == 0 &&
-                   ((tm->tm_year + 1900 ) % 100) != 0) ||
-                  ((tm->tm_year + 1900 ) % 400) == 0) ? 1 : 0;
-       mdays[1] += leapday;
-
-       yday = tm->tm_mday - 1;
-       for (i = 1; i <= tm->tm_mon; i++)
-               yday += mdays[i - 1];
-       ret = tm->tm_sec +
-             (60 * tm->tm_min) +
-             (3600 * tm->tm_hour) +
-             (86400 * (yday +
-                      ((tm->tm_year - 70) * 365) +
-                      ((tm->tm_year - 69) / 4) -
-                      ((tm->tm_year - 1) / 100) +
-                      ((tm->tm_year + 299) / 400)));
-       return (ret);
-}
-
-#include "strptime.c"
 isc_result_t
 isc_time_parsehttptimestamp(char *buf, isc_time_t *t) {
        struct tm t_tm;
@@ -352,10 +327,10 @@ isc_time_parsehttptimestamp(char *buf, isc_time_t *t) {
 
        REQUIRE(buf != NULL);
        REQUIRE(t != NULL);
-       p = strptime(buf, "%a, %d %b %Y %H:%M:%S", &t_tm);
+       p = isc_tm_strptime(buf, "%a, %d %b %Y %H:%M:%S", &t_tm);
        if (p == NULL)
                return (ISC_R_UNEXPECTED);
-       when = timetfromtm(&t_tm);
+       when = isc_tm_timegm(&t_tm);
        if (when == -1)
                return (ISC_R_UNEXPECTED);
        isc_time_set(t, when, 0);