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