nrelease - fix/improve livecd
[dragonfly.git] / lib / libc / stdtime / localtime.c
1 /*
2 ** This file is in the public domain, so clarified as of
3 ** 1996-06-05 by Arthur David Olson.
4 **
5 ** $FreeBSD: head/contrib/tzcode/stdtime/localtime.c 226828 2011-10-27 08:44:07Z trociny $
6 */
7
8 /*
9 ** Leap second handling from Bradley White.
10 ** POSIX-style TZ environment variable handling from Guy Harris.
11 */
12
13 /*LINTLIBRARY*/
14
15 #include "namespace.h"
16 #include <sys/types.h>
17 #include <sys/stat.h>
18
19 #include <errno.h>
20 #include <fcntl.h>
21 #include <time.h>
22 #include <pthread.h>
23 #include "private.h"
24 #include "libc_private.h"
25 #include "un-namespace.h"
26
27 #include "tzfile.h"
28
29 #ifndef TZ_ABBR_MAX_LEN
30 #define TZ_ABBR_MAX_LEN 16
31 #endif /* !defined TZ_ABBR_MAX_LEN */
32
33 #ifndef TZ_ABBR_CHAR_SET
34 #define TZ_ABBR_CHAR_SET \
35         "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789 :+-._"
36 #endif /* !defined TZ_ABBR_CHAR_SET */
37
38 #ifndef TZ_ABBR_ERR_CHAR
39 #define TZ_ABBR_ERR_CHAR        '_'
40 #endif /* !defined TZ_ABBR_ERR_CHAR */
41
42 #define _MUTEX_LOCK(x)          if (__isthreaded) _pthread_mutex_lock(x)
43 #define _MUTEX_UNLOCK(x)        if (__isthreaded) _pthread_mutex_unlock(x)
44
45 #define _RWLOCK_RDLOCK(x)                                               \
46                 do {                                                    \
47                         if (__isthreaded) _pthread_rwlock_rdlock(x);    \
48                 } while (0)
49
50 #define _RWLOCK_WRLOCK(x)                                               \
51                 do {                                                    \
52                         if (__isthreaded) _pthread_rwlock_wrlock(x);    \
53                 } while (0)
54
55 #define _RWLOCK_UNLOCK(x)                                               \
56                 do {                                                    \
57                         if (__isthreaded) _pthread_rwlock_unlock(x);    \
58                 } while (0)
59
60 /*
61 ** Someone might make incorrect use of a time zone abbreviation:
62 **      1.      They might reference tzname[0] before calling tzset (explicitly
63 **              or implicitly).
64 **      2.      They might reference tzname[1] before calling tzset (explicitly
65 **              or implicitly).
66 **      3.      They might reference tzname[1] after setting to a time zone
67 **              in which Daylight Saving Time is never observed.
68 **      4.      They might reference tzname[0] after setting to a time zone
69 **              in which Standard Time is never observed.
70 **      5.      They might reference tm.TM_ZONE after calling offtime.
71 ** What's best to do in the above cases is open to debate;
72 ** for now, we just set things up so that in any of the five cases
73 ** WILDABBR is used. Another possibility: initialize tzname[0] to the
74 ** string "tzname[0] used before set", and similarly for the other cases.
75 ** And another: initialize tzname[0] to "ERA", with an explanation in the
76 ** manual page of what this "time zone abbreviation" means (doing this so
77 ** that tzname[0] has the "normal" length of three characters).
78 */
79 #define WILDABBR        "   "
80
81 static char             wildabbr[] = WILDABBR;
82
83 static const char       gmt[] = "UTC";
84
85 /*
86 ** The DST rules to use if TZ has no rules and we can't load TZDEFRULES.
87 ** We default to US rules as of 1999-08-17.
88 ** POSIX 1003.1 section 8.1.1 says that the default DST rules are
89 ** implementation dependent; for historical reasons, US rules are a
90 ** common default.
91 */
92 #ifndef TZDEFRULESTRING
93 #define TZDEFRULESTRING ",M4.1.0,M10.5.0"
94 #endif /* !defined TZDEFDST */
95
96 struct ttinfo {                         /* time type information */
97         int_fast32_t    tt_gmtoff;      /* UT offset in seconds */
98         int             tt_isdst;       /* used to set tm_isdst */
99         int             tt_abbrind;     /* abbreviation list index */
100         int             tt_ttisstd;     /* TRUE if transition is std time */
101         int             tt_ttisgmt;     /* TRUE if transition is UT */
102 };
103
104 struct lsinfo {                         /* leap second information */
105         time_t          ls_trans;       /* transition time */
106         int_fast64_t    ls_corr;        /* correction to apply */
107 };
108
109 #define BIGGEST(a, b)   (((a) > (b)) ? (a) : (b))
110
111 #ifdef TZNAME_MAX
112 #define MY_TZNAME_MAX   TZNAME_MAX
113 #endif /* defined TZNAME_MAX */
114 #ifndef TZNAME_MAX
115 #define MY_TZNAME_MAX   255
116 #endif /* !defined TZNAME_MAX */
117
118 struct state {
119         int             leapcnt;
120         int             timecnt;
121         int             typecnt;
122         int             charcnt;
123         int             goback;
124         int             goahead;
125         time_t          ats[TZ_MAX_TIMES];
126         unsigned char   types[TZ_MAX_TIMES];
127         struct ttinfo   ttis[TZ_MAX_TYPES];
128         char            chars[BIGGEST(BIGGEST(TZ_MAX_CHARS + 1, sizeof gmt),
129                                 (2 * (MY_TZNAME_MAX + 1)))];
130         struct lsinfo   lsis[TZ_MAX_LEAPS];
131         int             defaulttype; /* for early times or if no transitions */
132 };
133
134 struct rule {
135         int             r_type;         /* type of rule--see below */
136         int             r_day;          /* day number of rule */
137         int             r_week;         /* week number of rule */
138         int             r_mon;          /* month number of rule */
139         int_fast32_t    r_time;         /* transition time of rule */
140 };
141
142 #define JULIAN_DAY              0       /* Jn - Julian day */
143 #define DAY_OF_YEAR             1       /* n - day of year */
144 #define MONTH_NTH_DAY_OF_WEEK   2       /* Mm.n.d - month, week, day of week */
145
146 /*
147 ** Prototypes for static functions.
148 */
149
150 static int_fast32_t     detzcode(const char * codep);
151 static int_fast64_t     detzcode64(const char * codep);
152 static int              differ_by_repeat(time_t t1, time_t t0);
153 static const char *     getzname(const char * strp) __pure;
154 static const char *     getqzname(const char * strp, const int delim) __pure;
155 static const char *     getnum(const char * strp, int * nump, int min,
156                                 int max);
157 static const char *     getsecs(const char * strp, int_fast32_t * secsp);
158 static const char *     getoffset(const char * strp, int_fast32_t * offsetp);
159 static const char *     getrule(const char * strp, struct rule * rulep);
160 static void             gmtload(struct state * sp);
161 static struct tm *      gmtsub(const time_t * timep, int_fast32_t offset,
162                                 struct tm * tmp);
163 static struct tm *      localsub(const time_t * timep, int_fast32_t offset,
164                                 struct tm * tmp);
165 static int              increment_overflow(int * number, int delta);
166 static int              leaps_thru_end_of(int y) __pure;
167 static int              increment_overflow32(int_fast32_t * number, int delta);
168 static int              increment_overflow_time(time_t *t, int_fast32_t delta);
169 static int              normalize_overflow32(int_fast32_t * tensptr,
170                                 int * unitsptr, int base);
171 static int              normalize_overflow(int * tensptr, int * unitsptr,
172                                 int base);
173 static void             settzname(void);
174 static time_t           time1(struct tm * tmp,
175                                 struct tm * (*funcp)(const time_t *,
176                                 int_fast32_t, struct tm *),
177                                 int_fast32_t offset);
178 static time_t           time2(struct tm *tmp,
179                                 struct tm * (*funcp)(const time_t *,
180                                 int_fast32_t, struct tm*),
181                                 int_fast32_t offset, int * okayp);
182 static time_t           time2sub(struct tm *tmp,
183                                 struct tm * (*funcp)(const time_t *,
184                                 int_fast32_t, struct tm*),
185                                 int_fast32_t offset, int * okayp, int do_norm_secs);
186 static struct tm *      timesub(const time_t * timep, int_fast32_t offset,
187                                 const struct state * sp, struct tm * tmp);
188 static int              tmcomp(const struct tm * atmp,
189                                 const struct tm * btmp);
190 static int_fast32_t     transtime(int year, const struct rule * rulep,
191                                   int_fast32_t offset) __pure;
192 static int              typesequiv(const struct state * sp, int a, int b);
193 static int              tzload(const char * name, struct state * sp,
194                                 int doextend);
195 static int              tzparse(const char * name, struct state * sp,
196                                 int lastditch);
197
198 static struct state     lclmem;
199 static struct state     gmtmem;
200 #define lclptr          (&lclmem)
201 #define gmtptr          (&gmtmem)
202
203 #ifndef TZ_STRLEN_MAX
204 #define TZ_STRLEN_MAX 255
205 #endif /* !defined TZ_STRLEN_MAX */
206
207 static char             lcl_TZname[TZ_STRLEN_MAX + 1];
208 static int              lcl_is_set;
209 static pthread_once_t   gmt_once = PTHREAD_ONCE_INIT;
210 static pthread_rwlock_t lcl_rwlock = PTHREAD_RWLOCK_INITIALIZER;
211 static pthread_once_t   gmtime_once = PTHREAD_ONCE_INIT;
212 static pthread_key_t    gmtime_key;
213 static int              gmtime_key_error;
214 static pthread_once_t   localtime_once = PTHREAD_ONCE_INIT;
215 static pthread_key_t    localtime_key;
216 static int              localtime_key_error;
217
218 char *                  tzname[2] = {
219         wildabbr,
220         wildabbr
221 };
222
223 /*
224 ** Section 4.12.3 of X3.159-1989 requires that
225 **      Except for the strftime function, these functions [asctime,
226 **      ctime, gmtime, localtime] return values in one of two static
227 **      objects: a broken-down time structure and an array of char.
228 ** Thanks to Paul Eggert for noting this.
229 */
230
231 static struct tm        tm;
232
233 long                    timezone = 0;
234 int                     daylight = 0;
235
236 static int_fast32_t
237 detzcode(const char * const codep)
238 {
239         int_fast32_t    result;
240         int             i;
241
242         result = (codep[0] & 0x80) ? -1 : 0;
243         for (i = 0; i < 4; ++i)
244                 result = (result << 8) | (codep[i] & 0xff);
245         return result;
246 }
247
248 static int_fast64_t
249 detzcode64(const char * const codep)
250 {
251         int_fast64_t result;
252         int     i;
253
254         result = (codep[0] & 0x80) ? -1 : 0;
255         for (i = 0; i < 8; ++i)
256                 result = (result << 8) | (codep[i] & 0xff);
257         return result;
258 }
259
260 static void
261 settzname(void)
262 {
263         struct state * const    sp = lclptr;
264         int                     i;
265
266         tzname[0] = wildabbr;
267         tzname[1] = wildabbr;
268         daylight = 0;
269         timezone = 0;
270
271         /*
272         ** And to get the latest zone names into tzname. . .
273         */
274         for (i = 0; i < sp->typecnt; ++i) {
275                 const struct ttinfo * const ttisp = &sp->ttis[i];
276
277                 tzname[ttisp->tt_isdst] = &sp->chars[ttisp->tt_abbrind];
278         }
279         for (i = 0; i < sp->timecnt; ++i) {
280                 const struct ttinfo * const ttisp = &sp->ttis[sp->types[i]];
281
282                 tzname[ttisp->tt_isdst] =
283                         &sp->chars[ttisp->tt_abbrind];
284                 if (ttisp->tt_isdst)
285                         daylight = 1;
286                 if (!ttisp->tt_isdst)
287                         timezone = -(ttisp->tt_gmtoff);
288         }
289         /*
290         ** Finally, scrub the abbreviations.
291         ** First, replace bogus characters.
292         */
293         for (i = 0; i < sp->charcnt; ++i)
294                 if (strchr(TZ_ABBR_CHAR_SET, sp->chars[i]) == NULL)
295                         sp->chars[i] = TZ_ABBR_ERR_CHAR;
296         /*
297         ** Second, truncate long abbreviations.
298         */
299         for (i = 0; i < sp->typecnt; ++i) {
300                 const struct ttinfo * const     ttisp = &sp->ttis[i];
301                 char *                          cp = &sp->chars[ttisp->tt_abbrind];
302
303                 if (strlen(cp) > TZ_ABBR_MAX_LEN &&
304                         strcmp(cp, GRANDPARENTED) != 0)
305                                 *(cp + TZ_ABBR_MAX_LEN) = '\0';
306         }
307 }
308
309 static int
310 differ_by_repeat(const time_t t1, const time_t t0)
311 {
312         if (TYPE_BIT(time_t) - TYPE_SIGNED(time_t) < SECSPERREPEAT_BITS)
313                 return 0;
314         return t1 - t0 == SECSPERREPEAT;
315 }
316
317 static int
318 tzload(const char *name, struct state * const sp, const int doextend)
319 {
320         const char *    p;
321         int             i;
322         int             fid;
323         int             stored;
324         int             nread;
325         int             res;
326         typedef union {
327                 struct tzhead   tzhead;
328                 char            buf[2 * sizeof(struct tzhead) +
329                                         2 * sizeof *sp +
330                                         4 * TZ_MAX_TIMES];
331         } u_t;
332         u_t             *u;
333
334         u = NULL;
335         res = -1;
336         sp->goback = sp->goahead = FALSE;
337
338         /* XXX The following is from OpenBSD, and I'm not sure it is correct */
339         if (name != NULL && issetugid() != 0)
340                 if ((name[0] == ':' && name[1] == '/') || 
341                     name[0] == '/' || strchr(name, '.'))
342                         name = NULL;
343         if (name == NULL && (name = TZDEFAULT) == NULL)
344                 goto out;
345         {
346                 int     doaccess;
347                 struct stat     stab;
348                 /*
349                 ** Section 4.9.1 of the C standard says that
350                 ** "FILENAME_MAX expands to an integral constant expression
351                 ** that is the size needed for an array of char large enough
352                 ** to hold the longest file name string that the implementation
353                 ** guarantees can be opened."
354                 */
355                 char            *fullname;
356
357                 fullname = malloc(FILENAME_MAX + 1);
358                 if (fullname == NULL)
359                         goto out;
360
361                 if (name[0] == ':')
362                         ++name;
363                 doaccess = name[0] == '/';
364                 if (!doaccess) {
365                         if ((p = TZDIR) == NULL) {
366                                 free(fullname);
367                                 goto out;
368                         }
369                         if (strlen(p) + 1 + strlen(name) >= FILENAME_MAX) {
370                                 free(fullname);
371                                 goto out;
372                         }
373                         strcpy(fullname, p);
374                         strcat(fullname, "/");
375                         strcat(fullname, name);
376                         /*
377                         ** Set doaccess if '.' (as in "../") shows up in name.
378                         */
379                         if (strchr(name, '.') != NULL)
380                                 doaccess = TRUE;
381                         name = fullname;
382                 }
383                 if (doaccess && access(name, R_OK) != 0) {
384                         free(fullname);
385                         goto out;
386                 }
387                 if ((fid = _open(name, O_RDONLY)) == -1) {
388                         free(fullname);
389                         goto out;
390                 }
391                 if ((_fstat(fid, &stab) < 0) || !S_ISREG(stab.st_mode)) {
392                         free(fullname);
393                         _close(fid);
394                         goto out;
395                 }
396                 free(fullname);
397         }
398         u = malloc(sizeof(*u));
399         if (u == NULL)
400                 goto out;
401         nread = _read(fid, u->buf, sizeof u->buf);
402         if (_close(fid) < 0 || nread <= 0)
403                 goto out;
404         for (stored = 4; stored <= 8; stored *= 2) {
405                 int             ttisstdcnt;
406                 int             ttisgmtcnt;
407                 int             timecnt;
408
409                 ttisstdcnt = (int) detzcode(u->tzhead.tzh_ttisstdcnt);
410                 ttisgmtcnt = (int) detzcode(u->tzhead.tzh_ttisgmtcnt);
411                 sp->leapcnt = (int) detzcode(u->tzhead.tzh_leapcnt);
412                 sp->timecnt = (int) detzcode(u->tzhead.tzh_timecnt);
413                 sp->typecnt = (int) detzcode(u->tzhead.tzh_typecnt);
414                 sp->charcnt = (int) detzcode(u->tzhead.tzh_charcnt);
415                 p = u->tzhead.tzh_charcnt + sizeof u->tzhead.tzh_charcnt;
416                 if (sp->leapcnt < 0 || sp->leapcnt > TZ_MAX_LEAPS ||
417                         sp->typecnt <= 0 || sp->typecnt > TZ_MAX_TYPES ||
418                         sp->timecnt < 0 || sp->timecnt > TZ_MAX_TIMES ||
419                         sp->charcnt < 0 || sp->charcnt > TZ_MAX_CHARS ||
420                         (ttisstdcnt != sp->typecnt && ttisstdcnt != 0) ||
421                         (ttisgmtcnt != sp->typecnt && ttisgmtcnt != 0))
422                                 goto out;
423                 if (nread - (p - u->buf) <
424                         sp->timecnt * stored +          /* ats */
425                         sp->timecnt +                   /* types */
426                         sp->typecnt * 6 +               /* ttinfos */
427                         sp->charcnt +                   /* chars */
428                         sp->leapcnt * (stored + 4) +    /* lsinfos */
429                         ttisstdcnt +                    /* ttisstds */
430                         ttisgmtcnt)                     /* ttisgmts */
431                                 goto out;
432                 timecnt = 0;
433                 for (i = 0; i < sp->timecnt; ++i) {
434                         int_fast64_t at
435                           = stored == 4 ? detzcode(p) : detzcode64(p);
436                         sp->types[i] = ((TYPE_SIGNED(time_t)
437                                          ? time_t_min <= at
438                                          : 0 <= at)
439                                         && at <= time_t_max);
440                         if (sp->types[i]) {
441                                 if (i && !timecnt && at != time_t_min) {
442                                         /*
443                                         ** Keep the earlier record, but tweak
444                                         ** it so that it starts with the
445                                         ** minimum time_t value.
446                                         */
447                                         sp->types[i - 1] = 1;
448                                         sp->ats[timecnt++] = time_t_min;
449                                 }
450                                 sp->ats[timecnt++] = at;
451                         }
452                         p += stored;
453                 }
454                 timecnt = 0;
455                 for (i = 0; i < sp->timecnt; ++i) {
456                         unsigned char typ = *p++;
457                         if (sp->typecnt <= typ)
458                                 goto out;
459                         if (sp->types[i])
460                                 sp->types[timecnt++] = typ;
461                 }
462                 sp->timecnt = timecnt;
463                 for (i = 0; i < sp->typecnt; ++i) {
464                         struct ttinfo * ttisp;
465
466                         ttisp = &sp->ttis[i];
467                         ttisp->tt_gmtoff = detzcode(p);
468                         p += 4;
469                         ttisp->tt_isdst = (unsigned char) *p++;
470                         if (ttisp->tt_isdst != 0 && ttisp->tt_isdst != 1)
471                                 goto out;
472                         ttisp->tt_abbrind = (unsigned char) *p++;
473                         if (ttisp->tt_abbrind < 0 ||
474                                 ttisp->tt_abbrind > sp->charcnt)
475                                         goto out;
476                 }
477                 for (i = 0; i < sp->charcnt; ++i)
478                         sp->chars[i] = *p++;
479                 sp->chars[i] = '\0';    /* ensure '\0' at end */
480                 for (i = 0; i < sp->leapcnt; ++i) {
481                         struct lsinfo * lsisp;
482
483                         lsisp = &sp->lsis[i];
484                         lsisp->ls_trans = (stored == 4) ?
485                                 detzcode(p) : detzcode64(p);
486                         p += stored;
487                         lsisp->ls_corr = detzcode(p);
488                         p += 4;
489                 }
490                 for (i = 0; i < sp->typecnt; ++i) {
491                         struct ttinfo * ttisp;
492
493                         ttisp = &sp->ttis[i];
494                         if (ttisstdcnt == 0)
495                                 ttisp->tt_ttisstd = FALSE;
496                         else {
497                                 ttisp->tt_ttisstd = *p++;
498                                 if (ttisp->tt_ttisstd != TRUE &&
499                                         ttisp->tt_ttisstd != FALSE)
500                                                 goto out;
501                         }
502                 }
503                 for (i = 0; i < sp->typecnt; ++i) {
504                         struct ttinfo * ttisp;
505
506                         ttisp = &sp->ttis[i];
507                         if (ttisgmtcnt == 0)
508                                 ttisp->tt_ttisgmt = FALSE;
509                         else {
510                                 ttisp->tt_ttisgmt = *p++;
511                                 if (ttisp->tt_ttisgmt != TRUE &&
512                                         ttisp->tt_ttisgmt != FALSE)
513                                                 goto out;
514                         }
515                 }
516                 /*
517                 ** If this is an old file, we're done.
518                 */
519                 if (u->tzhead.tzh_version[0] == '\0')
520                         break;
521                 nread -= p - u->buf;
522                 for (i = 0; i < nread; ++i)
523                         u->buf[i] = p[i];
524                 /*
525                 ** If this is a signed narrow time_t system, we're done.
526                 */
527                 if (TYPE_SIGNED(time_t) && stored >= (int) sizeof(time_t))
528                         break;
529         }
530         if (doextend && nread > 2 &&
531                 u->buf[0] == '\n' && u->buf[nread - 1] == '\n' &&
532                 sp->typecnt + 2 <= TZ_MAX_TYPES) {
533                         struct state    *ts;
534                         int             result;
535
536                         ts = malloc(sizeof(*ts));
537                         if (ts == NULL)
538                                 goto out;
539                         u->buf[nread - 1] = '\0';
540                         result = tzparse(&u->buf[1], ts, FALSE);
541                         if (result == 0 && ts->typecnt == 2 &&
542                                 sp->charcnt + ts->charcnt <= TZ_MAX_CHARS) {
543                                         for (i = 0; i < 2; ++i)
544                                                 ts->ttis[i].tt_abbrind +=
545                                                         sp->charcnt;
546                                         for (i = 0; i < ts->charcnt; ++i)
547                                                 sp->chars[sp->charcnt++] =
548                                                         ts->chars[i];
549                                         i = 0;
550                                         while (i < ts->timecnt &&
551                                                 ts->ats[i] <=
552                                                 sp->ats[sp->timecnt - 1])
553                                                         ++i;
554                                         while (i < ts->timecnt &&
555                                             sp->timecnt < TZ_MAX_TIMES) {
556                                                 sp->ats[sp->timecnt] =
557                                                         ts->ats[i];
558                                                 sp->types[sp->timecnt] =
559                                                         sp->typecnt +
560                                                         ts->types[i];
561                                                 ++sp->timecnt;
562                                                 ++i;
563                                         }
564                                         sp->ttis[sp->typecnt++] = ts->ttis[0];
565                                         sp->ttis[sp->typecnt++] = ts->ttis[1];
566                         }
567                         free(ts);
568         }
569         if (sp->timecnt > 1) {
570                 for (i = 1; i < sp->timecnt; ++i)
571                         if (typesequiv(sp, sp->types[i], sp->types[0]) &&
572                                 differ_by_repeat(sp->ats[i], sp->ats[0])) {
573                                         sp->goback = TRUE;
574                                         break;
575                                 }
576                 for (i = sp->timecnt - 2; i >= 0; --i)
577                         if (typesequiv(sp, sp->types[sp->timecnt - 1],
578                                 sp->types[i]) &&
579                                 differ_by_repeat(sp->ats[sp->timecnt - 1],
580                                 sp->ats[i])) {
581                                         sp->goahead = TRUE;
582                                         break;
583                 }
584         }
585         /*
586         ** If type 0 is is unused in transitions,
587         ** it's the type to use for early times.
588         */
589         for (i = 0; i < sp->typecnt; ++i)
590                 if (sp->types[i] == 0)
591                         break;
592         i = (i >= sp->typecnt) ? 0 : -1;
593         /*
594         ** Absent the above,
595         ** if there are transition times
596         ** and the first transition is to a daylight time
597         ** find the standard type less than and closest to
598         ** the type of the first transition.
599         */
600         if (i < 0 && sp->timecnt > 0 && sp->ttis[sp->types[0]].tt_isdst) {
601                 i = sp->types[0];
602                 while (--i >= 0)
603                         if (!sp->ttis[i].tt_isdst)
604                                 break;
605         }
606         /*
607         ** If no result yet, find the first standard type.
608         ** If there is none, punt to type zero.
609         */
610         if (i < 0) {
611                 i = 0;
612                 while (sp->ttis[i].tt_isdst)
613                         if (++i >= sp->typecnt) {
614                                 i = 0;
615                                 break;
616                         }
617         }
618         sp->defaulttype = i;
619         res = 0;
620 out:
621         if (u != NULL)
622                 free(u);
623         return (res);
624 }
625
626 static int
627 typesequiv(const struct state * const sp, const int a, const int b)
628 {
629         int     result;
630
631         if (sp == NULL ||
632                 a < 0 || a >= sp->typecnt ||
633                 b < 0 || b >= sp->typecnt)
634                         result = FALSE;
635         else {
636                 const struct ttinfo *   ap = &sp->ttis[a];
637                 const struct ttinfo *   bp = &sp->ttis[b];
638                 result = ap->tt_gmtoff == bp->tt_gmtoff &&
639                         ap->tt_isdst == bp->tt_isdst &&
640                         ap->tt_ttisstd == bp->tt_ttisstd &&
641                         ap->tt_ttisgmt == bp->tt_ttisgmt &&
642                         strcmp(&sp->chars[ap->tt_abbrind],
643                         &sp->chars[bp->tt_abbrind]) == 0;
644         }
645         return result;
646 }
647
648 static const int        mon_lengths[2][MONSPERYEAR] = {
649         { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 },
650         { 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }
651 };
652
653 static const int        year_lengths[2] = {
654         DAYSPERNYEAR, DAYSPERLYEAR
655 };
656
657 /*
658 ** Given a pointer into a time zone string, scan until a character that is not
659 ** a valid character in a zone name is found. Return a pointer to that
660 ** character.
661 */
662
663 static const char *
664 getzname(const char *strp)
665 {
666         char    c;
667
668         while ((c = *strp) != '\0' && !is_digit(c) && c != ',' && c != '-' &&
669                 c != '+')
670                         ++strp;
671         return strp;
672 }
673
674 /*
675 ** Given a pointer into an extended time zone string, scan until the ending
676 ** delimiter of the zone name is located. Return a pointer to the delimiter.
677 **
678 ** As with getzname above, the legal character set is actually quite
679 ** restricted, with other characters producing undefined results.
680 ** We don't do any checking here; checking is done later in common-case code.
681 */
682
683 static const char *
684 getqzname(const char *strp, const int delim)
685 {
686         int     c;
687
688         while ((c = *strp) != '\0' && c != delim)
689                 ++strp;
690         return strp;
691 }
692
693 /*
694 ** Given a pointer into a time zone string, extract a number from that string.
695 ** Check that the number is within a specified range; if it is not, return
696 ** NULL.
697 ** Otherwise, return a pointer to the first character not part of the number.
698 */
699
700 static const char *
701 getnum(const char *strp, int * const nump, const int min, const int max)
702 {
703         char    c;
704         int     num;
705
706         if (strp == NULL || !is_digit(c = *strp))
707                 return NULL;
708         num = 0;
709         do {
710                 num = num * 10 + (c - '0');
711                 if (num > max)
712                         return NULL;    /* illegal value */
713                 c = *++strp;
714         } while (is_digit(c));
715         if (num < min)
716                 return NULL;            /* illegal value */
717         *nump = num;
718         return strp;
719 }
720
721 /*
722 ** Given a pointer into a time zone string, extract a number of seconds,
723 ** in hh[:mm[:ss]] form, from the string.
724 ** If any error occurs, return NULL.
725 ** Otherwise, return a pointer to the first character not part of the number
726 ** of seconds.
727 */
728
729 static const char *
730 getsecs(const char *strp, int_fast32_t * const secsp)
731 {
732         int     num;
733
734         /*
735         ** `HOURSPERDAY * DAYSPERWEEK - 1' allows quasi-Posix rules like
736         ** "M10.4.6/26", which does not conform to Posix,
737         ** but which specifies the equivalent of
738         ** ``02:00 on the first Sunday on or after 23 Oct''.
739         */
740         strp = getnum(strp, &num, 0, HOURSPERDAY * DAYSPERWEEK - 1);
741         if (strp == NULL)
742                 return NULL;
743         *secsp = num * (int_fast32_t) SECSPERHOUR;
744         if (*strp == ':') {
745                 ++strp;
746                 strp = getnum(strp, &num, 0, MINSPERHOUR - 1);
747                 if (strp == NULL)
748                         return NULL;
749                 *secsp += num * SECSPERMIN;
750                 if (*strp == ':') {
751                         ++strp;
752                         /* `SECSPERMIN' allows for leap seconds. */
753                         strp = getnum(strp, &num, 0, SECSPERMIN);
754                         if (strp == NULL)
755                                 return NULL;
756                         *secsp += num;
757                 }
758         }
759         return strp;
760 }
761
762 /*
763 ** Given a pointer into a time zone string, extract an offset, in
764 ** [+-]hh[:mm[:ss]] form, from the string.
765 ** If any error occurs, return NULL.
766 ** Otherwise, return a pointer to the first character not part of the time.
767 */
768
769 static const char *
770 getoffset(const char *strp, int_fast32_t * const offsetp)
771 {
772         int     neg = 0;
773
774         if (*strp == '-') {
775                 neg = 1;
776                 ++strp;
777         } else if (*strp == '+')
778                 ++strp;
779         strp = getsecs(strp, offsetp);
780         if (strp == NULL)
781                 return NULL;            /* illegal time */
782         if (neg)
783                 *offsetp = -*offsetp;
784         return strp;
785 }
786
787 /*
788 ** Given a pointer into a time zone string, extract a rule in the form
789 ** date[/time]. See POSIX section 8 for the format of "date" and "time".
790 ** If a valid rule is not found, return NULL.
791 ** Otherwise, return a pointer to the first character not part of the rule.
792 */
793
794 static const char *
795 getrule(const char *strp, struct rule * const rulep)
796 {
797         if (*strp == 'J') {
798                 /*
799                 ** Julian day.
800                 */
801                 rulep->r_type = JULIAN_DAY;
802                 ++strp;
803                 strp = getnum(strp, &rulep->r_day, 1, DAYSPERNYEAR);
804         } else if (*strp == 'M') {
805                 /*
806                 ** Month, week, day.
807                 */
808                 rulep->r_type = MONTH_NTH_DAY_OF_WEEK;
809                 ++strp;
810                 strp = getnum(strp, &rulep->r_mon, 1, MONSPERYEAR);
811                 if (strp == NULL)
812                         return NULL;
813                 if (*strp++ != '.')
814                         return NULL;
815                 strp = getnum(strp, &rulep->r_week, 1, 5);
816                 if (strp == NULL)
817                         return NULL;
818                 if (*strp++ != '.')
819                         return NULL;
820                 strp = getnum(strp, &rulep->r_day, 0, DAYSPERWEEK - 1);
821         } else if (is_digit(*strp)) {
822                 /*
823                 ** Day of year.
824                 */
825                 rulep->r_type = DAY_OF_YEAR;
826                 strp = getnum(strp, &rulep->r_day, 0, DAYSPERLYEAR - 1);
827         } else  return NULL;            /* invalid format */
828         if (strp == NULL)
829                 return NULL;
830         if (*strp == '/') {
831                 /*
832                 ** Time specified.
833                 */
834                 ++strp;
835                 strp = getoffset(strp, &rulep->r_time);
836         } else  rulep->r_time = 2 * SECSPERHOUR;        /* default = 2:00:00 */
837         return strp;
838 }
839
840 /*
841 ** Given a year, a rule, and the offset from UT at the time that rule takes
842 ** effect, calculate the year-relative time that rule takes effect.
843 */
844
845 static int_fast32_t
846 transtime(const int year, const struct rule * const rulep,
847           const int_fast32_t offset)
848 {
849         int     leapyear;
850         int_fast32_t value;
851         int     i;
852         int             d, m1, yy0, yy1, yy2, dow;
853
854         INITIALIZE(value);
855         leapyear = isleap(year);
856         switch (rulep->r_type) {
857
858         case JULIAN_DAY:
859                 /*
860                 ** Jn - Julian day, 1 == January 1, 60 == March 1 even in leap
861                 ** years.
862                 ** In non-leap years, or if the day number is 59 or less, just
863                 ** add SECSPERDAY times the day number-1 to the time of
864                 ** January 1, midnight, to get the day.
865                 */
866                 value = (rulep->r_day - 1) * SECSPERDAY;
867                 if (leapyear && rulep->r_day >= 60)
868                         value += SECSPERDAY;
869                 break;
870
871         case DAY_OF_YEAR:
872                 /*
873                 ** n - day of year.
874                 ** Just add SECSPERDAY times the day number to the time of
875                 ** January 1, midnight, to get the day.
876                 */
877                 value = rulep->r_day * SECSPERDAY;
878                 break;
879
880         case MONTH_NTH_DAY_OF_WEEK:
881                 /*
882                 ** Mm.n.d - nth "dth day" of month m.
883                 */
884
885                 /*
886                 ** Use Zeller's Congruence to get day-of-week of first day of
887                 ** month.
888                 */
889                 m1 = (rulep->r_mon + 9) % 12 + 1;
890                 yy0 = (rulep->r_mon <= 2) ? (year - 1) : year;
891                 yy1 = yy0 / 100;
892                 yy2 = yy0 % 100;
893                 dow = ((26 * m1 - 2) / 10 +
894                         1 + yy2 + yy2 / 4 + yy1 / 4 - 2 * yy1) % 7;
895                 if (dow < 0)
896                         dow += DAYSPERWEEK;
897
898                 /*
899                 ** "dow" is the day-of-week of the first day of the month. Get
900                 ** the day-of-month (zero-origin) of the first "dow" day of the
901                 ** month.
902                 */
903                 d = rulep->r_day - dow;
904                 if (d < 0)
905                         d += DAYSPERWEEK;
906                 for (i = 1; i < rulep->r_week; ++i) {
907                         if (d + DAYSPERWEEK >=
908                                 mon_lengths[leapyear][rulep->r_mon - 1])
909                                         break;
910                         d += DAYSPERWEEK;
911                 }
912
913                 /*
914                 ** "d" is the day-of-month (zero-origin) of the day we want.
915                 */
916                 value = d * SECSPERDAY;
917                 for (i = 0; i < rulep->r_mon - 1; ++i)
918                         value += mon_lengths[leapyear][i] * SECSPERDAY;
919                 break;
920         }
921
922         /*
923         ** "value" is the year-relative time of 00:00:00 UT on the day in
924         ** question. To get the year-relative time of the specified local
925         ** time on that day, add the transition time and the current offset
926         ** from UT.
927         */
928         return value + rulep->r_time + offset;
929 }
930
931 /*
932 ** Given a POSIX section 8-style TZ string, fill in the rule tables as
933 ** appropriate.
934 */
935
936 static int
937 tzparse(const char *name, struct state * const sp, const int lastditch)
938 {
939         const char *                    stdname;
940         const char *                    dstname;
941         size_t                          stdlen;
942         size_t                          dstlen;
943         int_fast32_t                    stdoffset;
944         int_fast32_t                    dstoffset;
945         char *                          cp;
946         int                             load_result;
947         static struct ttinfo            zttinfo;
948
949         INITIALIZE(dstname);
950         stdname = name;
951         if (lastditch) {
952                 stdlen = strlen(name);  /* length of standard zone name */
953                 name += stdlen;
954                 if (stdlen >= sizeof sp->chars)
955                         stdlen = (sizeof sp->chars) - 1;
956                 stdoffset = 0;
957         } else {
958                 if (*name == '<') {
959                         name++;
960                         stdname = name;
961                         name = getqzname(name, '>');
962                         if (*name != '>')
963                                 return (-1);
964                         stdlen = name - stdname;
965                         name++;
966                 } else {
967                         name = getzname(name);
968                         stdlen = name - stdname;
969                 }
970                 if (*name == '\0')
971                         return -1;
972                 name = getoffset(name, &stdoffset);
973                 if (name == NULL)
974                         return -1;
975         }
976         load_result = tzload(TZDEFRULES, sp, FALSE);
977         if (load_result != 0)
978                 sp->leapcnt = 0;                /* so, we're off a little */
979         if (*name != '\0') {
980                 if (*name == '<') {
981                         dstname = ++name;
982                         name = getqzname(name, '>');
983                         if (*name != '>')
984                                 return -1;
985                         dstlen = name - dstname;
986                         name++;
987                 } else {
988                         dstname = name;
989                         name = getzname(name);
990                         dstlen = name - dstname; /* length of DST zone name */
991                 }
992                 if (*name != '\0' && *name != ',' && *name != ';') {
993                         name = getoffset(name, &dstoffset);
994                         if (name == NULL)
995                                 return -1;
996                 } else  dstoffset = stdoffset - SECSPERHOUR;
997                 if (*name == '\0' && load_result != 0)
998                         name = TZDEFRULESTRING;
999                 if (*name == ',' || *name == ';') {
1000                         struct rule     start;
1001                         struct rule     end;
1002                         int             year;
1003                         int             yearlim;
1004                         int             timecnt;
1005                         time_t          janfirst;
1006
1007                         ++name;
1008                         if ((name = getrule(name, &start)) == NULL)
1009                                 return -1;
1010                         if (*name++ != ',')
1011                                 return -1;
1012                         if ((name = getrule(name, &end)) == NULL)
1013                                 return -1;
1014                         if (*name != '\0')
1015                                 return -1;
1016                         sp->typecnt = 2;        /* standard time and DST */
1017                         /*
1018                         ** Two transitions per year, from EPOCH_YEAR forward.
1019                         */
1020                         sp->ttis[0] = sp->ttis[1] = zttinfo;
1021                         sp->ttis[0].tt_gmtoff = -dstoffset;
1022                         sp->ttis[0].tt_isdst = 1;
1023                         sp->ttis[0].tt_abbrind = stdlen + 1;
1024                         sp->ttis[1].tt_gmtoff = -stdoffset;
1025                         sp->ttis[1].tt_isdst = 0;
1026                         sp->ttis[1].tt_abbrind = 0;
1027                         timecnt = 0;
1028                         janfirst = 0;
1029                         yearlim = EPOCH_YEAR + YEARSPERREPEAT;
1030                         for (year = EPOCH_YEAR; year < yearlim; year++) {
1031                                 int_fast32_t
1032                                   starttime = transtime(year, &start, stdoffset),
1033                                   endtime = transtime(year, &end, dstoffset);
1034                                 int_fast32_t
1035                                   yearsecs = (year_lengths[isleap(year)]
1036                                               * SECSPERDAY);
1037                                 int reversed = endtime < starttime;
1038                                 if (reversed) {
1039                                         int_fast32_t swap = starttime;
1040                                         starttime = endtime;
1041                                         endtime = swap;
1042                                 }
1043                                 if (reversed
1044                                     || (starttime < endtime
1045                                         && (endtime - starttime
1046                                             < (yearsecs
1047                                                + (stdoffset - dstoffset))))) {
1048                                         if (TZ_MAX_TIMES - 2 < timecnt)
1049                                                 break;
1050                                         yearlim = year + YEARSPERREPEAT + 1;
1051                                         sp->ats[timecnt] = janfirst;
1052                                         if (increment_overflow_time
1053                                             (&sp->ats[timecnt], starttime))
1054                                                 break;
1055                                         sp->types[timecnt++] = reversed;
1056                                         sp->ats[timecnt] = janfirst;
1057                                         if (increment_overflow_time
1058                                             (&sp->ats[timecnt], endtime))
1059                                                 break;
1060                                         sp->types[timecnt++] = !reversed;
1061                                 }
1062                                 if (increment_overflow_time(&janfirst, yearsecs))
1063                                         break;
1064                         }
1065                         sp->timecnt = timecnt;
1066                         if (!timecnt)
1067                                 sp->typecnt = 1;        /* Perpetual DST.  */
1068                 } else {
1069                         int_fast32_t    theirstdoffset;
1070                         int_fast32_t    theirdstoffset;
1071                         int_fast32_t    theiroffset;
1072                         int             isdst;
1073                         int             i;
1074                         int             j;
1075
1076                         if (*name != '\0')
1077                                 return -1;
1078                         /*
1079                         ** Initial values of theirstdoffset and theirdstoffset.
1080                         */
1081                         theirstdoffset = 0;
1082                         for (i = 0; i < sp->timecnt; ++i) {
1083                                 j = sp->types[i];
1084                                 if (!sp->ttis[j].tt_isdst) {
1085                                         theirstdoffset =
1086                                                 -sp->ttis[j].tt_gmtoff;
1087                                         break;
1088                                 }
1089                         }
1090                         theirdstoffset = 0;
1091                         for (i = 0; i < sp->timecnt; ++i) {
1092                                 j = sp->types[i];
1093                                 if (sp->ttis[j].tt_isdst) {
1094                                         theirdstoffset =
1095                                                 -sp->ttis[j].tt_gmtoff;
1096                                         break;
1097                                 }
1098                         }
1099                         /*
1100                         ** Initially we're assumed to be in standard time.
1101                         */
1102                         isdst = FALSE;
1103                         theiroffset = theirstdoffset;
1104                         /*
1105                         ** Now juggle transition times and types
1106                         ** tracking offsets as you do.
1107                         */
1108                         for (i = 0; i < sp->timecnt; ++i) {
1109                                 j = sp->types[i];
1110                                 sp->types[i] = sp->ttis[j].tt_isdst;
1111                                 if (sp->ttis[j].tt_ttisgmt) {
1112                                         /* No adjustment to transition time */
1113                                 } else {
1114                                         /*
1115                                         ** If summer time is in effect, and the
1116                                         ** transition time was not specified as
1117                                         ** standard time, add the summer time
1118                                         ** offset to the transition time;
1119                                         ** otherwise, add the standard time
1120                                         ** offset to the transition time.
1121                                         */
1122                                         /*
1123                                         ** Transitions from DST to DDST
1124                                         ** will effectively disappear since
1125                                         ** POSIX provides for only one DST
1126                                         ** offset.
1127                                         */
1128                                         if (isdst && !sp->ttis[j].tt_ttisstd) {
1129                                                 sp->ats[i] += dstoffset -
1130                                                         theirdstoffset;
1131                                         } else {
1132                                                 sp->ats[i] += stdoffset -
1133                                                         theirstdoffset;
1134                                         }
1135                                 }
1136                                 theiroffset = -sp->ttis[j].tt_gmtoff;
1137                                 if (sp->ttis[j].tt_isdst)
1138                                         theirdstoffset = theiroffset;
1139                                 else    theirstdoffset = theiroffset;
1140                         }
1141                         /*
1142                         ** Finally, fill in ttis.
1143                         */
1144                         sp->ttis[0] = sp->ttis[1] = zttinfo;
1145                         sp->ttis[0].tt_gmtoff = -stdoffset;
1146                         sp->ttis[0].tt_isdst = FALSE;
1147                         sp->ttis[0].tt_abbrind = 0;
1148                         sp->ttis[1].tt_gmtoff = -dstoffset;
1149                         sp->ttis[1].tt_isdst = TRUE;
1150                         sp->ttis[1].tt_abbrind = stdlen + 1;
1151                         sp->typecnt = 2;
1152                 }
1153         } else {
1154                 dstlen = 0;
1155                 sp->typecnt = 1;                /* only standard time */
1156                 sp->timecnt = 0;
1157                 sp->ttis[0] = zttinfo;
1158                 sp->ttis[0].tt_gmtoff = -stdoffset;
1159                 sp->ttis[0].tt_isdst = 0;
1160                 sp->ttis[0].tt_abbrind = 0;
1161         }
1162         sp->charcnt = stdlen + 1;
1163         if (dstlen != 0)
1164                 sp->charcnt += dstlen + 1;
1165         if ((size_t) sp->charcnt > sizeof sp->chars)
1166                 return -1;
1167         cp = sp->chars;
1168         strncpy(cp, stdname, stdlen);
1169         cp += stdlen;
1170         *cp++ = '\0';
1171         if (dstlen != 0) {
1172                 strncpy(cp, dstname, dstlen);
1173                 *(cp + dstlen) = '\0';
1174         }
1175         return 0;
1176 }
1177
1178 static void
1179 gmtload(struct state * const sp)
1180 {
1181         if (tzload(gmt, sp, TRUE) != 0)
1182                 tzparse(gmt, sp, TRUE);
1183 }
1184
1185 static void
1186 tzsetwall_basic(int rdlocked)
1187 {
1188         if (!rdlocked)
1189                 _RWLOCK_RDLOCK(&lcl_rwlock);
1190         if (lcl_is_set < 0) {
1191                 if (!rdlocked)
1192                         _RWLOCK_UNLOCK(&lcl_rwlock);
1193                 return;
1194         }
1195         _RWLOCK_UNLOCK(&lcl_rwlock);
1196
1197         _RWLOCK_WRLOCK(&lcl_rwlock);
1198         lcl_is_set = -1;
1199
1200         if (tzload(NULL, lclptr, TRUE) != 0)
1201                 gmtload(lclptr);
1202         settzname();
1203         _RWLOCK_UNLOCK(&lcl_rwlock);
1204
1205         if (rdlocked)
1206                 _RWLOCK_RDLOCK(&lcl_rwlock);
1207 }
1208
1209 void
1210 tzsetwall(void)
1211 {
1212         tzsetwall_basic(0);
1213 }
1214
1215 static void
1216 tzset_basic(int rdlocked)
1217 {
1218         const char *    name;
1219
1220         name = getenv("TZ");
1221         if (name == NULL) {
1222                 tzsetwall_basic(rdlocked);
1223                 return;
1224         }
1225
1226         if (!rdlocked)
1227                 _RWLOCK_RDLOCK(&lcl_rwlock);
1228         if (lcl_is_set > 0 && strcmp(lcl_TZname, name) == 0) {
1229                 if (!rdlocked)
1230                         _RWLOCK_UNLOCK(&lcl_rwlock);
1231                 return;
1232         }
1233         _RWLOCK_UNLOCK(&lcl_rwlock);
1234
1235         _RWLOCK_WRLOCK(&lcl_rwlock);
1236         lcl_is_set = strlen(name) < sizeof lcl_TZname;
1237         if (lcl_is_set)
1238                 strcpy(lcl_TZname, name);
1239
1240         if (*name == '\0') {
1241                 /*
1242                 ** User wants it fast rather than right.
1243                 */
1244                 lclptr->leapcnt = 0;            /* so, we're off a little */
1245                 lclptr->timecnt = 0;
1246                 lclptr->typecnt = 0;
1247                 lclptr->ttis[0].tt_isdst = 0;
1248                 lclptr->ttis[0].tt_gmtoff = 0;
1249                 lclptr->ttis[0].tt_abbrind = 0;
1250                 strcpy(lclptr->chars, gmt);
1251         } else if (tzload(name, lclptr, TRUE) != 0)
1252                 if (name[0] == ':' || tzparse(name, lclptr, FALSE) != 0)
1253                         gmtload(lclptr);
1254         settzname();
1255         _RWLOCK_UNLOCK(&lcl_rwlock);
1256
1257         if (rdlocked)
1258                 _RWLOCK_RDLOCK(&lcl_rwlock);
1259 }
1260
1261 void
1262 tzset(void)
1263 {
1264         tzset_basic(0);
1265 }
1266
1267 /*
1268 ** The easy way to behave "as if no library function calls" localtime
1269 ** is to not call it--so we drop its guts into "localsub", which can be
1270 ** freely called. (And no, the PANS doesn't require the above behavior--
1271 ** but it *is* desirable.)
1272 **
1273 ** The unused offset argument is for the benefit of mktime variants.
1274 */
1275
1276 /*ARGSUSED*/
1277 static struct tm *
1278 localsub(const time_t * const timep, const int_fast32_t offset __unused,
1279          struct tm * const tmp)
1280 {
1281         struct state *          sp;
1282         const struct ttinfo *   ttisp;
1283         int                     i;
1284         struct tm *             result;
1285         const time_t            t = *timep;
1286
1287         sp = lclptr;
1288
1289         if ((sp->goback && t < sp->ats[0]) ||
1290                 (sp->goahead && t > sp->ats[sp->timecnt - 1])) {
1291                         time_t          newt = t;
1292                         time_t          seconds;
1293                         time_t          years;
1294
1295                         if (t < sp->ats[0])
1296                                 seconds = sp->ats[0] - t;
1297                         else    seconds = t - sp->ats[sp->timecnt - 1];
1298                         --seconds;
1299                         years = (seconds / SECSPERREPEAT + 1) * YEARSPERREPEAT;
1300                         seconds = years * AVGSECSPERYEAR;
1301                         if (t < sp->ats[0])
1302                                 newt += seconds;
1303                         else    newt -= seconds;
1304                         if (newt < sp->ats[0] ||
1305                                 newt > sp->ats[sp->timecnt - 1])
1306                                         return NULL;    /* "cannot happen" */
1307                         result = localsub(&newt, offset, tmp);
1308                         if (result == tmp) {
1309                                 time_t  newy;
1310
1311                                 newy = tmp->tm_year;
1312                                 if (t < sp->ats[0])
1313                                         newy -= years;
1314                                 else    newy += years;
1315                                 tmp->tm_year = newy;
1316                                 if (tmp->tm_year != newy)
1317                                         return NULL;
1318                         }
1319                         return result;
1320         }
1321         if (sp->timecnt == 0 || t < sp->ats[0]) {
1322                 i = sp->defaulttype;
1323         } else {
1324                 int     lo = 1;
1325                 int     hi = sp->timecnt;
1326
1327                 while (lo < hi) {
1328                         int     mid = (lo + hi) >> 1;
1329
1330                         if (t < sp->ats[mid])
1331                                 hi = mid;
1332                         else    lo = mid + 1;
1333                 }
1334                 i = (int) sp->types[lo - 1];
1335         }
1336         ttisp = &sp->ttis[i];
1337         /*
1338         ** To get (wrong) behavior that's compatible with System V Release 2.0
1339         ** you'd replace the statement below with
1340         **      t += ttisp->tt_gmtoff;
1341         **      timesub(&t, 0L, sp, tmp);
1342         */
1343         result = timesub(&t, ttisp->tt_gmtoff, sp, tmp);
1344         tmp->tm_isdst = ttisp->tt_isdst;
1345         tzname[tmp->tm_isdst] = &sp->chars[ttisp->tt_abbrind];
1346         tmp->TM_ZONE = &sp->chars[ttisp->tt_abbrind];
1347         return result;
1348 }
1349
1350 static void
1351 localtime_key_init(void)
1352 {
1353
1354         localtime_key_error = _pthread_key_create(&localtime_key, free);
1355 }
1356
1357 struct tm *
1358 localtime(const time_t * const timep)
1359 {
1360         struct tm *p_tm;
1361
1362         if (__isthreaded != 0) {
1363                 _pthread_once(&localtime_once, localtime_key_init);
1364                 if (localtime_key_error != 0) {
1365                         errno = localtime_key_error;
1366                         return(NULL);
1367                 }
1368                 p_tm = _pthread_getspecific(localtime_key);
1369                 if (p_tm == NULL) {
1370                         if ((p_tm = (struct tm *)malloc(sizeof(struct tm)))
1371                             == NULL)
1372                                 return(NULL);
1373                         _pthread_setspecific(localtime_key, p_tm);
1374                 }
1375                 _RWLOCK_RDLOCK(&lcl_rwlock);
1376                 tzset_basic(1);
1377                 localsub(timep, 0L, p_tm);
1378                 _RWLOCK_UNLOCK(&lcl_rwlock);
1379                 return(p_tm);
1380         } else {
1381                 tzset_basic(0);
1382                 localsub(timep, 0L, &tm);
1383                 return(&tm);
1384         }
1385 }
1386
1387 /*
1388 ** Re-entrant version of localtime.
1389 */
1390
1391 struct tm *
1392 localtime_r(const time_t * __restrict const timep, struct tm * __restrict tmp)
1393 {
1394         _RWLOCK_RDLOCK(&lcl_rwlock);
1395         tzset_basic(1);
1396         localsub(timep, 0L, tmp);
1397         _RWLOCK_UNLOCK(&lcl_rwlock);
1398         return tmp;
1399 }
1400
1401 static void
1402 gmt_init(void)
1403 {
1404         gmtload(gmtptr);
1405 }
1406
1407 /*
1408 ** gmtsub is to gmtime as localsub is to localtime.
1409 */
1410
1411 static struct tm *
1412 gmtsub(const time_t * const timep, const int_fast32_t offset,
1413        struct tm * const tmp)
1414 {
1415         struct tm *     result;
1416
1417         _once(&gmt_once, gmt_init);
1418         result = timesub(timep, offset, gmtptr, tmp);
1419         /*
1420         ** Could get fancy here and deliver something such as
1421         ** "UT+xxxx" or "UT-xxxx" if offset is non-zero,
1422         ** but this is no time for a treasure hunt.
1423         */
1424         if (offset != 0)
1425                 tmp->TM_ZONE = wildabbr;
1426         else
1427                 tmp->TM_ZONE = gmtptr->chars;
1428         return result;
1429 }
1430
1431 static void
1432 gmtime_key_init(void)
1433 {
1434         gmtime_key_error = _pthread_key_create(&gmtime_key, free);
1435 }
1436
1437 struct tm *
1438 gmtime(const time_t * const timep)
1439 {
1440         struct tm *p_tm;
1441
1442         if (__isthreaded != 0) {
1443                 _pthread_once(&gmtime_once, gmtime_key_init);
1444                 if (gmtime_key_error != 0) {
1445                         errno = gmtime_key_error;
1446                         return(NULL);
1447                 }
1448                 /*
1449                  * Changed to follow POSIX.1 threads standard, which
1450                  * is what BSD currently has.
1451                  */
1452                 if ((p_tm = _pthread_getspecific(gmtime_key)) == NULL) {
1453                         if ((p_tm = (struct tm *)malloc(sizeof(struct tm)))
1454                             == NULL) {
1455                                 return(NULL);
1456                         }
1457                         _pthread_setspecific(gmtime_key, p_tm);
1458                 }
1459                 return gmtsub(timep, 0L, p_tm);
1460         } else {
1461                 return gmtsub(timep, 0L, &tm);
1462         }
1463 }
1464
1465 /*
1466  * Re-entrant version of gmtime.
1467  */
1468
1469 struct tm *
1470 gmtime_r(const time_t * __restrict timep, struct tm * __restrict tmp)
1471 {
1472         return gmtsub(timep, 0L, tmp);
1473 }
1474
1475 struct tm *
1476 offtime(const time_t * const timep, const long offset)
1477 {
1478         return gmtsub(timep, offset, &tm);
1479 }
1480
1481 /*
1482 ** Return the number of leap years through the end of the given year
1483 ** where, to make the math easy, the answer for year zero is defined as zero.
1484 */
1485
1486 static int
1487 leaps_thru_end_of(const int y)
1488 {
1489         return (y >= 0) ? (y / 4 - y / 100 + y / 400) :
1490                 -(leaps_thru_end_of(-(y + 1)) + 1);
1491 }
1492
1493 static struct tm *
1494 timesub(const time_t * const timep, const int_fast32_t offset,
1495         const struct state * const sp, struct tm * const tmp)
1496 {
1497         const struct lsinfo *   lp;
1498         time_t                  tdays;
1499         int                     idays;  /* unsigned would be so 2003 */
1500         int_fast64_t            rem;
1501         int                     y;
1502         const int *             ip;
1503         int_fast64_t            corr;
1504         int                     hit;
1505         int                     i;
1506
1507         corr = 0;
1508         hit = 0;
1509         i = sp->leapcnt;
1510
1511         while (--i >= 0) {
1512                 lp = &sp->lsis[i];
1513                 if (*timep >= lp->ls_trans) {
1514                         if (*timep == lp->ls_trans) {
1515                                 hit = ((i == 0 && lp->ls_corr > 0) ||
1516                                         lp->ls_corr > sp->lsis[i - 1].ls_corr);
1517                                 if (hit)
1518                                         while (i > 0 &&
1519                                                 sp->lsis[i].ls_trans ==
1520                                                 sp->lsis[i - 1].ls_trans + 1 &&
1521                                                 sp->lsis[i].ls_corr ==
1522                                                 sp->lsis[i - 1].ls_corr + 1) {
1523                                                         ++hit;
1524                                                         --i;
1525                                         }
1526                         }
1527                         corr = lp->ls_corr;
1528                         break;
1529                 }
1530         }
1531         y = EPOCH_YEAR;
1532         tdays = *timep / SECSPERDAY;
1533         rem = *timep - tdays * SECSPERDAY;
1534         while (tdays < 0 || tdays >= year_lengths[isleap(y)]) {
1535                 int     newy;
1536                 time_t  tdelta;
1537                 int     idelta;
1538                 int     leapdays;
1539
1540                 tdelta = tdays / DAYSPERLYEAR;
1541                 if (! ((! TYPE_SIGNED(time_t) || INT_MIN <= tdelta)
1542                        && tdelta <= INT_MAX))
1543                         goto out_of_range;
1544                 idelta = tdelta;
1545                 if (idelta == 0)
1546                         idelta = (tdays < 0) ? -1 : 1;
1547                 newy = y;
1548                 if (increment_overflow(&newy, idelta))
1549                         goto out_of_range;
1550                 leapdays = leaps_thru_end_of(newy - 1) -
1551                         leaps_thru_end_of(y - 1);
1552                 tdays -= ((time_t) newy - y) * DAYSPERNYEAR;
1553                 tdays -= leapdays;
1554                 y = newy;
1555         }
1556         {
1557                 int_fast32_t    seconds;
1558
1559                 seconds = tdays * SECSPERDAY;
1560                 tdays = seconds / SECSPERDAY;
1561                 rem += seconds - tdays * SECSPERDAY;
1562         }
1563         /*
1564         ** Given the range, we can now fearlessly cast...
1565         */
1566         idays = tdays;
1567         rem += offset - corr;
1568         while (rem < 0) {
1569                 rem += SECSPERDAY;
1570                 --idays;
1571         }
1572         while (rem >= SECSPERDAY) {
1573                 rem -= SECSPERDAY;
1574                 ++idays;
1575         }
1576         while (idays < 0) {
1577                 if (increment_overflow(&y, -1))
1578                         goto out_of_range;
1579                 idays += year_lengths[isleap(y)];
1580         }
1581         while (idays >= year_lengths[isleap(y)]) {
1582                 idays -= year_lengths[isleap(y)];
1583                 if (increment_overflow(&y, 1))
1584                         goto out_of_range;
1585         }
1586         tmp->tm_year = y;
1587         if (increment_overflow(&tmp->tm_year, -TM_YEAR_BASE))
1588                 goto out_of_range;
1589         tmp->tm_yday = idays;
1590         /*
1591         ** The "extra" mods below avoid overflow problems.
1592         */
1593         tmp->tm_wday = EPOCH_WDAY +
1594                 ((y - EPOCH_YEAR) % DAYSPERWEEK) *
1595                 (DAYSPERNYEAR % DAYSPERWEEK) +
1596                 leaps_thru_end_of(y - 1) -
1597                 leaps_thru_end_of(EPOCH_YEAR - 1) +
1598                 idays;
1599         tmp->tm_wday %= DAYSPERWEEK;
1600         if (tmp->tm_wday < 0)
1601                 tmp->tm_wday += DAYSPERWEEK;
1602         tmp->tm_hour = (int) (rem / SECSPERHOUR);
1603         rem %= SECSPERHOUR;
1604         tmp->tm_min = (int) (rem / SECSPERMIN);
1605         /*
1606         ** A positive leap second requires a special
1607         ** representation. This uses "... ??:59:60" et seq.
1608         */
1609         tmp->tm_sec = (int) (rem % SECSPERMIN) + hit;
1610         ip = mon_lengths[isleap(y)];
1611         for (tmp->tm_mon = 0; idays >= ip[tmp->tm_mon]; ++(tmp->tm_mon))
1612                 idays -= ip[tmp->tm_mon];
1613         tmp->tm_mday = (int) (idays + 1);
1614         tmp->tm_isdst = 0;
1615         tmp->TM_GMTOFF = offset;
1616         return tmp;
1617
1618 out_of_range:
1619         errno = EOVERFLOW;
1620         return NULL;
1621 }
1622
1623 char *
1624 ctime(const time_t * const timep)
1625 {
1626 /*
1627 ** Section 4.12.3.2 of X3.159-1989 requires that
1628 **      The ctime function converts the calendar time pointed to by timer
1629 **      to local time in the form of a string. It is equivalent to
1630 **              asctime(localtime(timer))
1631 */
1632         struct tm *tmp = localtime(timep);
1633
1634         return tmp ? asctime(tmp) : NULL;
1635 }
1636
1637 char *
1638 ctime_r(const time_t * const timep, char *buf)
1639 {
1640         struct tm       mytm;
1641         struct tm *tmp = localtime_r(timep, &mytm);
1642
1643         return tmp ? asctime_r(tmp, buf) : NULL;
1644 }
1645
1646 /*
1647 ** Adapted from code provided by Robert Elz, who writes:
1648 **      The "best" way to do mktime I think is based on an idea of Bob
1649 **      Kridle's (so its said...) from a long time ago.
1650 **      It does a binary search of the time_t space. Since time_t's are
1651 **      just 32 bits, its a max of 32 iterations (even at 64 bits it
1652 **      would still be very reasonable).
1653 */
1654
1655 #ifndef WRONG
1656 #define WRONG   (-1)
1657 #endif /* !defined WRONG */
1658
1659 /*
1660 ** Normalize logic courtesy Paul Eggert.
1661 */
1662
1663 static int
1664 increment_overflow(int * const ip, int j)
1665 {
1666         int const       i = *ip;
1667
1668         /*
1669         ** If i >= 0 there can only be overflow if i + j > INT_MAX
1670         ** or if j > INT_MAX - i; given i >= 0, INT_MAX - i cannot overflow.
1671         ** If i < 0 there can only be overflow if i + j < INT_MIN
1672         ** or if j < INT_MIN - i; given i < 0, INT_MIN - i cannot overflow.
1673         */
1674         if ((i >= 0) ? (j > INT_MAX - i) : (j < INT_MIN - i))
1675                 return TRUE;
1676         *ip += j;
1677         return FALSE;
1678 }
1679
1680 static int
1681 increment_overflow32(int_fast32_t * const lp, int const m)
1682 {
1683         int_fast32_t const      l = *lp;
1684
1685         if ((l >= 0) ? (m > INT_FAST32_MAX - l) : (m < INT_FAST32_MIN - l))
1686                 return TRUE;
1687         *lp += m;
1688         return FALSE;
1689 }
1690
1691 static int
1692 increment_overflow_time(time_t *tp, int_fast32_t j)
1693 {
1694         /*
1695         ** This is like
1696         ** 'if (! (time_t_min <= *tp + j && *tp + j <= time_t_max)) ...',
1697         ** except that it does the right thing even if *tp + j would overflow.
1698         */
1699         if (! (j < 0
1700                ? (TYPE_SIGNED(time_t) ? time_t_min - j <= *tp : -1 - j < *tp)
1701                : *tp <= time_t_max - j))
1702                 return TRUE;
1703         *tp += j;
1704         return FALSE;
1705 }
1706
1707 static int
1708 normalize_overflow(int * const tensptr, int * const unitsptr, const int base)
1709 {
1710         int     tensdelta;
1711
1712         tensdelta = (*unitsptr >= 0) ?
1713                 (*unitsptr / base) :
1714                 (-1 - (-1 - *unitsptr) / base);
1715         *unitsptr -= tensdelta * base;
1716         return increment_overflow(tensptr, tensdelta);
1717 }
1718
1719 static int
1720 normalize_overflow32(int_fast32_t * const tensptr, int * const unitsptr,
1721                      const int base)
1722 {
1723         int     tensdelta;
1724
1725         tensdelta = (*unitsptr >= 0) ?
1726                 (*unitsptr / base) :
1727                 (-1 - (-1 - *unitsptr) / base);
1728         *unitsptr -= tensdelta * base;
1729         return increment_overflow32(tensptr, tensdelta);
1730 }
1731
1732 static int
1733 tmcomp(const struct tm * const atmp, const struct tm * const btmp)
1734 {
1735         int     result;
1736
1737         if (atmp->tm_year != btmp->tm_year)
1738                 return atmp->tm_year < btmp->tm_year ? -1 : 1;
1739         if ((result = (atmp->tm_mon - btmp->tm_mon)) == 0 &&
1740                 (result = (atmp->tm_mday - btmp->tm_mday)) == 0 &&
1741                 (result = (atmp->tm_hour - btmp->tm_hour)) == 0 &&
1742                 (result = (atmp->tm_min - btmp->tm_min)) == 0)
1743                         result = atmp->tm_sec - btmp->tm_sec;
1744         return result;
1745 }
1746
1747 static time_t
1748 time2sub(struct tm * const tmp,
1749       struct tm * (* const funcp)(const time_t *, int_fast32_t, struct tm *),
1750       const int_fast32_t offset, int * const okayp, const int do_norm_secs)
1751 {
1752         const struct state *    sp;
1753         int                     dir;
1754         int                     i, j;
1755         int                     saved_seconds;
1756         int_fast32_t            li;
1757         time_t                  lo;
1758         time_t                  hi;
1759         int_fast32_t            y;
1760         time_t                  newt;
1761         time_t                  t;
1762         struct tm               yourtm, mytm;
1763
1764         *okayp = FALSE;
1765         yourtm = *tmp;
1766         if (do_norm_secs) {
1767                 if (normalize_overflow(&yourtm.tm_min, &yourtm.tm_sec,
1768                         SECSPERMIN))
1769                                 return WRONG;
1770         }
1771         if (normalize_overflow(&yourtm.tm_hour, &yourtm.tm_min, MINSPERHOUR))
1772                 return WRONG;
1773         if (normalize_overflow(&yourtm.tm_mday, &yourtm.tm_hour, HOURSPERDAY))
1774                 return WRONG;
1775         y = yourtm.tm_year;
1776         if (normalize_overflow32(&y, &yourtm.tm_mon, MONSPERYEAR))
1777                 return WRONG;
1778         /*
1779         ** Turn y into an actual year number for now.
1780         ** It is converted back to an offset from TM_YEAR_BASE later.
1781         */
1782         if (increment_overflow32(&y, TM_YEAR_BASE))
1783                 return WRONG;
1784         while (yourtm.tm_mday <= 0) {
1785                 if (increment_overflow32(&y, -1))
1786                         return WRONG;
1787                 li = y + (1 < yourtm.tm_mon);
1788                 yourtm.tm_mday += year_lengths[isleap(li)];
1789         }
1790         while (yourtm.tm_mday > DAYSPERLYEAR) {
1791                 li = y + (1 < yourtm.tm_mon);
1792                 yourtm.tm_mday -= year_lengths[isleap(li)];
1793                 if (increment_overflow32(&y, 1))
1794                         return WRONG;
1795         }
1796         for ( ; ; ) {
1797                 i = mon_lengths[isleap(y)][yourtm.tm_mon];
1798                 if (yourtm.tm_mday <= i)
1799                         break;
1800                 yourtm.tm_mday -= i;
1801                 if (++yourtm.tm_mon >= MONSPERYEAR) {
1802                         yourtm.tm_mon = 0;
1803                         if (increment_overflow32(&y, 1))
1804                                 return WRONG;
1805                 }
1806         }
1807         if (increment_overflow32(&y, -TM_YEAR_BASE))
1808                 return WRONG;
1809         yourtm.tm_year = y;
1810         if (yourtm.tm_year != y)
1811                 return WRONG;
1812         if (yourtm.tm_sec >= 0 && yourtm.tm_sec < SECSPERMIN)
1813                 saved_seconds = 0;
1814         else if (y + TM_YEAR_BASE < EPOCH_YEAR) {
1815                 /*
1816                 ** We can't set tm_sec to 0, because that might push the
1817                 ** time below the minimum representable time.
1818                 ** Set tm_sec to 59 instead.
1819                 ** This assumes that the minimum representable time is
1820                 ** not in the same minute that a leap second was deleted from,
1821                 ** which is a safer assumption than using 58 would be.
1822                 */
1823                 if (increment_overflow(&yourtm.tm_sec, 1 - SECSPERMIN))
1824                         return WRONG;
1825                 saved_seconds = yourtm.tm_sec;
1826                 yourtm.tm_sec = SECSPERMIN - 1;
1827         } else {
1828                 saved_seconds = yourtm.tm_sec;
1829                 yourtm.tm_sec = 0;
1830         }
1831         /*
1832         ** Do a binary search (this works whatever time_t's type is).
1833         */
1834         lo = time_t_min;
1835         hi = time_t_max;
1836         for ( ; ; ) {
1837                 t = lo / 2 + hi / 2;
1838                 if (t < lo)
1839                         t = lo;
1840                 else if (t > hi)
1841                         t = hi;
1842                 if ((*funcp)(&t, offset, &mytm) == NULL) {
1843                         /*
1844                         ** Assume that t is too extreme to be represented in
1845                         ** a struct tm; arrange things so that it is less
1846                         ** extreme on the next pass.
1847                         */
1848                         dir = (t > 0) ? 1 : -1;
1849                 } else  dir = tmcomp(&mytm, &yourtm);
1850                 if (dir != 0) {
1851                         if (t == lo) {
1852                                 if (t == time_t_max)
1853                                         return WRONG;
1854                                 ++t;
1855                                 ++lo;
1856                         } else if (t == hi) {
1857                                 if (t == time_t_min)
1858                                         return WRONG;
1859                                 --t;
1860                                 --hi;
1861                         }
1862                         if (lo > hi)
1863                                 return WRONG;
1864                         if (dir > 0)
1865                                 hi = t;
1866                         else    lo = t;
1867                         continue;
1868                 }
1869                 if (yourtm.tm_isdst < 0 || mytm.tm_isdst == yourtm.tm_isdst)
1870                         break;
1871                 /*
1872                 ** Right time, wrong type.
1873                 ** Hunt for right time, right type.
1874                 ** It's okay to guess wrong since the guess
1875                 ** gets checked.
1876                 */
1877                 sp = (const struct state *)
1878                         ((funcp == localsub) ? lclptr : gmtptr);
1879
1880                 for (i = sp->typecnt - 1; i >= 0; --i) {
1881                         if (sp->ttis[i].tt_isdst != yourtm.tm_isdst)
1882                                 continue;
1883                         for (j = sp->typecnt - 1; j >= 0; --j) {
1884                                 if (sp->ttis[j].tt_isdst == yourtm.tm_isdst)
1885                                         continue;
1886                                 newt = t + sp->ttis[j].tt_gmtoff -
1887                                         sp->ttis[i].tt_gmtoff;
1888                                 if ((*funcp)(&newt, offset, &mytm) == NULL)
1889                                         continue;
1890                                 if (tmcomp(&mytm, &yourtm) != 0)
1891                                         continue;
1892                                 if (mytm.tm_isdst != yourtm.tm_isdst)
1893                                         continue;
1894                                 /*
1895                                 ** We have a match.
1896                                 */
1897                                 t = newt;
1898                                 goto label;
1899                         }
1900                 }
1901                 return WRONG;
1902         }
1903 label:
1904         newt = t + saved_seconds;
1905         if ((newt < t) != (saved_seconds < 0))
1906                 return WRONG;
1907         t = newt;
1908         if ((*funcp)(&t, offset, tmp))
1909                 *okayp = TRUE;
1910         return t;
1911 }
1912
1913 static time_t
1914 time2(struct tm * const tmp,
1915       struct tm * (* const funcp)(const time_t *, int_fast32_t, struct tm *),
1916       const int_fast32_t offset, int * const okayp)
1917 {
1918         time_t  t;
1919
1920         /*
1921         ** First try without normalization of seconds
1922         ** (in case tm_sec contains a value associated with a leap second).
1923         ** If that fails, try with normalization of seconds.
1924         */
1925         t = time2sub(tmp, funcp, offset, okayp, FALSE);
1926         return *okayp ? t : time2sub(tmp, funcp, offset, okayp, TRUE);
1927 }
1928
1929 static time_t
1930 time1(struct tm * const tmp,
1931       struct tm * (* const funcp)(const time_t *, int_fast32_t, struct tm *),
1932       const int_fast32_t offset)
1933 {
1934         time_t                  t;
1935         const struct state *    sp;
1936         int                     samei, otheri;
1937         int                     sameind, otherind;
1938         int                     i;
1939         int                     nseen;
1940         int                     seen[TZ_MAX_TYPES];
1941         int                     types[TZ_MAX_TYPES];
1942         int                     okay;
1943
1944         if (tmp == NULL) {
1945                 errno = EINVAL;
1946                 return WRONG;
1947         }
1948         if (tmp->tm_isdst > 1)
1949                 tmp->tm_isdst = 1;
1950         t = time2(tmp, funcp, offset, &okay);
1951
1952         /*
1953         ** PCTS code courtesy Grant Sullivan.
1954         */
1955         if (okay)
1956                 return t;
1957         if (tmp->tm_isdst < 0)
1958                 tmp->tm_isdst = 0;      /* reset to std and try again */
1959
1960         /*
1961         ** We're supposed to assume that somebody took a time of one type
1962         ** and did some math on it that yielded a "struct tm" that's bad.
1963         ** We try to divine the type they started from and adjust to the
1964         ** type they need.
1965         */
1966         sp = (const struct state *) ((funcp == localsub) ?  lclptr : gmtptr);
1967
1968         for (i = 0; i < sp->typecnt; ++i)
1969                 seen[i] = FALSE;
1970         nseen = 0;
1971         for (i = sp->timecnt - 1; i >= 0; --i)
1972                 if (!seen[sp->types[i]]) {
1973                         seen[sp->types[i]] = TRUE;
1974                         types[nseen++] = sp->types[i];
1975                 }
1976         for (sameind = 0; sameind < nseen; ++sameind) {
1977                 samei = types[sameind];
1978                 if (sp->ttis[samei].tt_isdst != tmp->tm_isdst)
1979                         continue;
1980                 for (otherind = 0; otherind < nseen; ++otherind) {
1981                         otheri = types[otherind];
1982                         if (sp->ttis[otheri].tt_isdst == tmp->tm_isdst)
1983                                 continue;
1984                         tmp->tm_sec += sp->ttis[otheri].tt_gmtoff -
1985                                         sp->ttis[samei].tt_gmtoff;
1986                         tmp->tm_isdst = !tmp->tm_isdst;
1987                         t = time2(tmp, funcp, offset, &okay);
1988                         if (okay)
1989                                 return t;
1990                         tmp->tm_sec -= sp->ttis[otheri].tt_gmtoff -
1991                                         sp->ttis[samei].tt_gmtoff;
1992                         tmp->tm_isdst = !tmp->tm_isdst;
1993                 }
1994         }
1995         return WRONG;
1996 }
1997
1998 time_t
1999 mktime(struct tm * const tmp)
2000 {
2001         time_t mktime_return_value;
2002         _RWLOCK_RDLOCK(&lcl_rwlock);
2003         tzset_basic(1);
2004         mktime_return_value = time1(tmp, localsub, 0L);
2005         _RWLOCK_UNLOCK(&lcl_rwlock);
2006         return(mktime_return_value);
2007 }
2008
2009 time_t
2010 timelocal(struct tm * const tmp)
2011 {
2012         if (tmp != NULL)
2013                 tmp->tm_isdst = -1;     /* in case it wasn't initialized */
2014         return mktime(tmp);
2015 }
2016
2017 time_t
2018 timegm(struct tm * const tmp)
2019 {
2020         if (tmp != NULL)
2021                 tmp->tm_isdst = 0;
2022         return time1(tmp, gmtsub, 0L);
2023 }
2024
2025 time_t
2026 timeoff(struct tm * const tmp, const long offset)
2027 {
2028         if (tmp != NULL)
2029                 tmp->tm_isdst = 0;
2030         return time1(tmp, gmtsub, offset);
2031 }
2032
2033 /*
2034 ** XXX--is the below the right way to conditionalize??
2035 */
2036
2037 /*
2038 ** IEEE Std 1003.1-1988 (POSIX) legislates that 536457599
2039 ** shall correspond to "Wed Dec 31 23:59:59 UTC 1986", which
2040 ** is not the case if we are accounting for leap seconds.
2041 ** So, we provide the following conversion routines for use
2042 ** when exchanging timestamps with POSIX conforming systems.
2043 */
2044
2045 static int_fast64_t
2046 leapcorr(time_t *timep)
2047 {
2048         struct state *          sp;
2049         struct lsinfo * lp;
2050         int                     i;
2051
2052         sp = lclptr;
2053         i = sp->leapcnt;
2054         while (--i >= 0) {
2055                 lp = &sp->lsis[i];
2056                 if (*timep >= lp->ls_trans)
2057                         return lp->ls_corr;
2058         }
2059         return 0;
2060 }
2061
2062 time_t
2063 time2posix(time_t t)
2064 {
2065         tzset();
2066         return t - leapcorr(&t);
2067 }
2068
2069 time_t
2070 posix2time(time_t t)
2071 {
2072         time_t  x;
2073         time_t  y;
2074
2075         tzset();
2076         /*
2077         ** For a positive leap second hit, the result
2078         ** is not unique. For a negative leap second
2079         ** hit, the corresponding time doesn't exist,
2080         ** so we return an adjacent second.
2081         */
2082         x = t + leapcorr(&t);
2083         y = x - leapcorr(&x);
2084         if (y < t) {
2085                 do {
2086                         x++;
2087                         y = x - leapcorr(&x);
2088                 } while (y < t);
2089                 if (t != y)
2090                         return x - 1;
2091         } else if (y > t) {
2092                 do {
2093                         --x;
2094                         y = x - leapcorr(&x);
2095                 } while (y > t);
2096                 if (t != y)
2097                         return x + 1;
2098         }
2099         return x;
2100 }