aboutsummaryrefslogtreecommitdiff
path: root/external/unbound/compat/gmtime_r.c
diff options
context:
space:
mode:
Diffstat (limited to 'external/unbound/compat/gmtime_r.c')
-rw-r--r--external/unbound/compat/gmtime_r.c107
1 files changed, 107 insertions, 0 deletions
diff --git a/external/unbound/compat/gmtime_r.c b/external/unbound/compat/gmtime_r.c
new file mode 100644
index 000000000..19eb637e3
--- /dev/null
+++ b/external/unbound/compat/gmtime_r.c
@@ -0,0 +1,107 @@
+/*
+ * Taken from FreeBSD src / lib / libc / stdtime / localtime.c 1.43 revision.
+ * localtime.c 7.78.
+ * tzfile.h 1.8
+ * adapted to be replacement gmtime_r.
+ */
+#include "config.h"
+
+#ifdef HAVE_TIME_H
+#include <time.h>
+#endif
+
+#define MONSPERYEAR 12
+#define DAYSPERNYEAR 365
+#define DAYSPERLYEAR 366
+#define SECSPERMIN 60
+#define SECSPERHOUR (60*60)
+#define SECSPERDAY (24*60*60)
+#define DAYSPERWEEK 7
+#define TM_SUNDAY 0
+#define TM_MONDAY 1
+#define TM_TUESDAY 2
+#define TM_WEDNESDAY 3
+#define TM_THURSDAY 4
+#define TM_FRIDAY 5
+#define TM_SATURDAY 6
+
+#define TM_YEAR_BASE 1900
+
+#define EPOCH_YEAR 1970
+#define EPOCH_WDAY TM_THURSDAY
+
+#define isleap(y) (((y) % 4) == 0 && (((y) % 100) != 0 || ((y) % 400) == 0))
+
+static const int mon_lengths[2][MONSPERYEAR] = {
+ { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 },
+ { 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }
+};
+
+static const int year_lengths[2] = {
+ DAYSPERNYEAR, DAYSPERLYEAR
+};
+
+static void
+timesub(timep, offset, tmp)
+const time_t * const timep;
+const long offset;
+struct tm * const tmp;
+{
+ long days;
+ long rem;
+ long y;
+ int yleap;
+ const int * ip;
+
+ days = *timep / SECSPERDAY;
+ rem = *timep % SECSPERDAY;
+ rem += (offset);
+ while (rem < 0) {
+ rem += SECSPERDAY;
+ --days;
+ }
+ while (rem >= SECSPERDAY) {
+ rem -= SECSPERDAY;
+ ++days;
+ }
+ tmp->tm_hour = (int) (rem / SECSPERHOUR);
+ rem = rem % SECSPERHOUR;
+ tmp->tm_min = (int) (rem / SECSPERMIN);
+ /*
+ ** A positive leap second requires a special
+ ** representation. This uses "... ??:59:60" et seq.
+ */
+ tmp->tm_sec = (int) (rem % SECSPERMIN) ;
+ tmp->tm_wday = (int) ((EPOCH_WDAY + days) % DAYSPERWEEK);
+ if (tmp->tm_wday < 0)
+ tmp->tm_wday += DAYSPERWEEK;
+ y = EPOCH_YEAR;
+#define LEAPS_THRU_END_OF(y) ((y) / 4 - (y) / 100 + (y) / 400)
+ while (days < 0 || days >= (long) year_lengths[yleap = isleap(y)]) {
+ long newy;
+
+ newy = y + days / DAYSPERNYEAR;
+ if (days < 0)
+ --newy;
+ days -= (newy - y) * DAYSPERNYEAR +
+ LEAPS_THRU_END_OF(newy - 1) -
+ LEAPS_THRU_END_OF(y - 1);
+ y = newy;
+ }
+ tmp->tm_year = y - TM_YEAR_BASE;
+ tmp->tm_yday = (int) days;
+ ip = mon_lengths[yleap];
+ for (tmp->tm_mon = 0; days >= (long) ip[tmp->tm_mon]; ++(tmp->tm_mon))
+ days = days - (long) ip[tmp->tm_mon];
+ tmp->tm_mday = (int) (days + 1);
+ tmp->tm_isdst = 0;
+}
+
+/*
+* Re-entrant version of gmtime.
+*/
+struct tm * gmtime_r(const time_t* timep, struct tm *tm)
+{
+ timesub(timep, 0L, tm);
+ return tm;
+}