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