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