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