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