localtime.c revision 1.133 1 /* $NetBSD: localtime.c,v 1.133 2022/03/25 19:34:04 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.133 2022/03/25 19:34:04 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 } else if (!HAVE_MALLOC_ERRNO)
1559 errno = ENOMEM;
1560 return sp;
1561 }
1562
1563 void
1564 tzfree(timezone_t sp)
1565 {
1566 free(sp);
1567 }
1568
1569 /*
1570 ** NetBSD 6.1.4 has ctime_rz, but omit it because POSIX says ctime and
1571 ** ctime_r are obsolescent and have potential security problems that
1572 ** ctime_rz would share. Callers can instead use localtime_rz + strftime.
1573 **
1574 ** NetBSD 6.1.4 has tzgetname, but omit it because it doesn't work
1575 ** in zones with three or more time zone abbreviations.
1576 ** Callers can instead use localtime_rz + strftime.
1577 */
1578
1579 #endif
1580
1581 /*
1582 ** The easy way to behave "as if no library function calls" localtime
1583 ** is to not call it, so we drop its guts into "localsub", which can be
1584 ** freely called. (And no, the PANS doesn't require the above behavior,
1585 ** but it *is* desirable.)
1586 **
1587 ** If successful and SETNAME is nonzero,
1588 ** set the applicable parts of tzname, timezone and altzone;
1589 ** however, it's OK to omit this step if the timezone is POSIX-compatible,
1590 ** since in that case tzset should have already done this step correctly.
1591 ** SETNAME's type is intfast32_t for compatibility with gmtsub,
1592 ** but it is actually a boolean and its value should be 0 or 1.
1593 */
1594
1595 /*ARGSUSED*/
1596 static struct tm *
1597 localsub(struct state const *sp, time_t const *timep, int_fast32_t setname,
1598 struct tm *const tmp)
1599 {
1600 register const struct ttinfo * ttisp;
1601 register int i;
1602 register struct tm * result;
1603 const time_t t = *timep;
1604
1605 if (sp == NULL) {
1606 /* Don't bother to set tzname etc.; tzset has already done it. */
1607 return gmtsub(gmtptr, timep, 0, tmp);
1608 }
1609 if ((sp->goback && t < sp->ats[0]) ||
1610 (sp->goahead && t > sp->ats[sp->timecnt - 1])) {
1611 time_t newt;
1612 register time_t seconds;
1613 register time_t years;
1614
1615 if (t < sp->ats[0])
1616 seconds = sp->ats[0] - t;
1617 else seconds = t - sp->ats[sp->timecnt - 1];
1618 --seconds;
1619
1620 /* Beware integer overflow, as SECONDS might
1621 be close to the maximum time_t. */
1622 years = (time_t)(seconds / SECSPERREPEAT
1623 * YEARSPERREPEAT);
1624 seconds = (time_t)(years * AVGSECSPERYEAR);
1625 years += YEARSPERREPEAT;
1626 if (t < sp->ats[0])
1627 newt = (time_t)(t + seconds + SECSPERREPEAT);
1628 else
1629 newt = (time_t)(t - seconds - SECSPERREPEAT);
1630
1631 if (newt < sp->ats[0] ||
1632 newt > sp->ats[sp->timecnt - 1]) {
1633 errno = EINVAL;
1634 return NULL; /* "cannot happen" */
1635 }
1636 result = localsub(sp, &newt, setname, tmp);
1637 if (result) {
1638 register int_fast64_t newy;
1639
1640 newy = result->tm_year;
1641 if (t < sp->ats[0])
1642 newy -= years;
1643 else newy += years;
1644 if (! (INT_MIN <= newy && newy <= INT_MAX)) {
1645 errno = EOVERFLOW;
1646 return NULL;
1647 }
1648 result->tm_year = (int)newy;
1649 }
1650 return result;
1651 }
1652 if (sp->timecnt == 0 || t < sp->ats[0]) {
1653 i = sp->defaulttype;
1654 } else {
1655 register int lo = 1;
1656 register int hi = sp->timecnt;
1657
1658 while (lo < hi) {
1659 register int mid = (lo + hi) / 2;
1660
1661 if (t < sp->ats[mid])
1662 hi = mid;
1663 else lo = mid + 1;
1664 }
1665 i = sp->types[lo - 1];
1666 }
1667 ttisp = &sp->ttis[i];
1668 /*
1669 ** To get (wrong) behavior that's compatible with System V Release 2.0
1670 ** you'd replace the statement below with
1671 ** t += ttisp->tt_utoff;
1672 ** timesub(&t, 0L, sp, tmp);
1673 */
1674 result = timesub(&t, ttisp->tt_utoff, sp, tmp);
1675 if (result) {
1676 result->tm_isdst = ttisp->tt_isdst;
1677 #ifdef TM_ZONE
1678 result->TM_ZONE = __UNCONST(&sp->chars[ttisp->tt_desigidx]);
1679 #endif /* defined TM_ZONE */
1680 if (setname)
1681 update_tzname_etc(sp, ttisp);
1682 }
1683 return result;
1684 }
1685
1686 #if NETBSD_INSPIRED
1687
1688 struct tm *
1689 localtime_rz(timezone_t sp, time_t const *timep, struct tm *tmp)
1690 {
1691 return localsub(sp, timep, 0, tmp);
1692 }
1693
1694 #endif
1695
1696 static struct tm *
1697 localtime_tzset(time_t const *timep, struct tm *tmp, bool setname)
1698 {
1699 rwlock_wrlock(&__lcl_lock);
1700 if (setname || !lcl_is_set)
1701 tzset_unlocked();
1702 tmp = localsub(__lclptr, timep, setname, tmp);
1703 rwlock_unlock(&__lcl_lock);
1704 return tmp;
1705 }
1706
1707 struct tm *
1708 localtime(const time_t *timep)
1709 {
1710 return localtime_tzset(timep, &tm, true);
1711 }
1712
1713 struct tm *
1714 localtime_r(const time_t * __restrict timep, struct tm *tmp)
1715 {
1716 return localtime_tzset(timep, tmp, true);
1717 }
1718
1719 /*
1720 ** gmtsub is to gmtime as localsub is to localtime.
1721 */
1722
1723 static struct tm *
1724 gmtsub(struct state const *sp, time_t const *timep, int_fast32_t offset,
1725 struct tm *tmp)
1726 {
1727 register struct tm * result;
1728
1729 result = timesub(timep, offset, gmtptr, tmp);
1730 #ifdef TM_ZONE
1731 /*
1732 ** Could get fancy here and deliver something such as
1733 ** "+xx" or "-xx" if offset is non-zero,
1734 ** but this is no time for a treasure hunt.
1735 */
1736 if (result)
1737 result->TM_ZONE = offset ? __UNCONST(wildabbr) : gmtptr ?
1738 gmtptr->chars : __UNCONST(gmt);
1739 #endif /* defined TM_ZONE */
1740 return result;
1741 }
1742
1743 /*
1744 * Re-entrant version of gmtime.
1745 */
1746
1747 struct tm *
1748 gmtime_r(const time_t *timep, struct tm *tmp)
1749 {
1750 gmtcheck();
1751 return gmtsub(NULL, timep, 0, tmp);
1752 }
1753
1754 struct tm *
1755 gmtime(const time_t *timep)
1756 {
1757 return gmtime_r(timep, &tm);
1758 }
1759
1760 #ifdef STD_INSPIRED
1761
1762 struct tm *
1763 offtime(const time_t *timep, long offset)
1764 {
1765 gmtcheck();
1766 return gmtsub(gmtptr, timep, (int_fast32_t)offset, &tm);
1767 }
1768
1769 struct tm *
1770 offtime_r(const time_t *timep, long offset, struct tm *tmp)
1771 {
1772 gmtcheck();
1773 return gmtsub(NULL, timep, (int_fast32_t)offset, tmp);
1774 }
1775
1776 #endif /* defined STD_INSPIRED */
1777
1778 #if TZ_TIME_T
1779
1780 # if USG_COMPAT
1781 # define daylight 0
1782 # define timezone 0
1783 # endif
1784 # if !ALTZONE
1785 # define altzone 0
1786 # endif
1787
1788 /* Convert from the underlying system's time_t to the ersatz time_tz,
1789 which is called 'time_t' in this file. Typically, this merely
1790 converts the time's integer width. On some platforms, the system
1791 time is local time not UT, or uses some epoch other than the POSIX
1792 epoch.
1793
1794 Although this code appears to define a function named 'time' that
1795 returns time_t, the macros in private.h cause this code to actually
1796 define a function named 'tz_time' that returns tz_time_t. The call
1797 to sys_time invokes the underlying system's 'time' function. */
1798
1799 time_t
1800 time(time_t *p)
1801 {
1802 __time_t r = sys_time(0);
1803 if (r != (time_t) -1) {
1804 int_fast32_t offset = EPOCH_LOCAL ? (daylight ? timezone : altzone) : 0;
1805 if (increment_overflow32(&offset, -EPOCH_OFFSET)
1806 || increment_overflow_time(&r, offset)) {
1807 errno = EOVERFLOW;
1808 r = -1;
1809 }
1810 }
1811 if (p)
1812 *p = (time_t)r;
1813 return (time_t)r;
1814 }
1815 #endif
1816
1817 /*
1818 ** Return the number of leap years through the end of the given year
1819 ** where, to make the math easy, the answer for year zero is defined as zero.
1820 */
1821
1822 static time_t
1823 leaps_thru_end_of_nonneg(time_t y)
1824 {
1825 return y / 4 - y / 100 + y / 400;
1826 }
1827
1828 static time_t
1829 leaps_thru_end_of(time_t y)
1830 {
1831 return (y < 0
1832 ? -1 - leaps_thru_end_of_nonneg(-1 - y)
1833 : leaps_thru_end_of_nonneg(y));
1834 }
1835
1836 static struct tm *
1837 timesub(const time_t *timep, int_fast32_t offset,
1838 const struct state *sp, struct tm *tmp)
1839 {
1840 register const struct lsinfo * lp;
1841 register time_t tdays;
1842 register const int * ip;
1843 register int_fast32_t corr;
1844 register int i;
1845 int_fast32_t idays, rem, dayoff, dayrem;
1846 time_t y;
1847
1848 /* If less than SECSPERMIN, the number of seconds since the
1849 most recent positive leap second; otherwise, do not add 1
1850 to localtime tm_sec because of leap seconds. */
1851 time_t secs_since_posleap = SECSPERMIN;
1852
1853 corr = 0;
1854 i = (sp == NULL) ? 0 : sp->leapcnt;
1855 while (--i >= 0) {
1856 lp = &sp->lsis[i];
1857 if (*timep >= lp->ls_trans) {
1858 corr = lp->ls_corr;
1859 if ((i == 0 ? 0 : lp[-1].ls_corr) < corr)
1860 secs_since_posleap = *timep - lp->ls_trans;
1861 break;
1862 }
1863 }
1864
1865 /* Calculate the year, avoiding integer overflow even if
1866 time_t is unsigned. */
1867 tdays = (time_t)(*timep / SECSPERDAY);
1868 rem = (int)(*timep % SECSPERDAY);
1869 rem += offset % SECSPERDAY - corr % SECSPERDAY + 3 * SECSPERDAY;
1870 dayoff = offset / SECSPERDAY - corr / SECSPERDAY + rem / SECSPERDAY - 3;
1871 rem %= SECSPERDAY;
1872 /* y = (EPOCH_YEAR
1873 + floor((tdays + dayoff) / DAYSPERREPEAT) * YEARSPERREPEAT),
1874 sans overflow. But calculate against 1570 (EPOCH_YEAR -
1875 YEARSPERREPEAT) instead of against 1970 so that things work
1876 for localtime values before 1970 when time_t is unsigned. */
1877 dayrem = (int)(tdays % DAYSPERREPEAT);
1878 dayrem += dayoff % DAYSPERREPEAT;
1879 y = (EPOCH_YEAR - YEARSPERREPEAT
1880 + ((1 + dayoff / DAYSPERREPEAT + dayrem / DAYSPERREPEAT
1881 - ((dayrem % DAYSPERREPEAT) < 0)
1882 + tdays / DAYSPERREPEAT)
1883 * YEARSPERREPEAT));
1884 /* idays = (tdays + dayoff) mod DAYSPERREPEAT, sans overflow. */
1885 idays = (int)(tdays % DAYSPERREPEAT);
1886 idays += dayoff % DAYSPERREPEAT + 2 * DAYSPERREPEAT;
1887 idays %= DAYSPERREPEAT;
1888 /* Increase Y and decrease IDAYS until IDAYS is in range for Y. */
1889 while (year_lengths[isleap(y)] <= idays) {
1890 int tdelta = idays / DAYSPERLYEAR;
1891 int_fast32_t ydelta = tdelta + !tdelta;
1892 time_t newy = y + ydelta;
1893 register int leapdays;
1894 leapdays = (int)(leaps_thru_end_of(newy - 1) -
1895 leaps_thru_end_of(y - 1));
1896 idays -= ydelta * DAYSPERNYEAR;
1897 idays -= leapdays;
1898 y = newy;
1899 }
1900
1901 if (!TYPE_SIGNED(time_t) && y < TM_YEAR_BASE) {
1902 int signed_y = (int)y;
1903 tmp->tm_year = signed_y - TM_YEAR_BASE;
1904 } else if ((!TYPE_SIGNED(time_t) || INT_MIN + TM_YEAR_BASE <= y)
1905 && y - TM_YEAR_BASE <= INT_MAX)
1906 tmp->tm_year = (int)(y - TM_YEAR_BASE);
1907 else {
1908 errno = EOVERFLOW;
1909 return NULL;
1910 }
1911 tmp->tm_yday = idays;
1912 /*
1913 ** The "extra" mods below avoid overflow problems.
1914 */
1915 tmp->tm_wday = (int)(TM_WDAY_BASE
1916 + ((tmp->tm_year % DAYSPERWEEK)
1917 * (DAYSPERNYEAR % DAYSPERWEEK))
1918 + leaps_thru_end_of(y - 1)
1919 - leaps_thru_end_of(TM_YEAR_BASE - 1)
1920 + idays);
1921 tmp->tm_wday %= DAYSPERWEEK;
1922 if (tmp->tm_wday < 0)
1923 tmp->tm_wday += DAYSPERWEEK;
1924 tmp->tm_hour = (int) (rem / SECSPERHOUR);
1925 rem %= SECSPERHOUR;
1926 tmp->tm_min = rem / SECSPERMIN;
1927 tmp->tm_sec = rem % SECSPERMIN;
1928
1929 /* Use "... ??:??:60" at the end of the localtime minute containing
1930 the second just before the positive leap second. */
1931 tmp->tm_sec += secs_since_posleap <= tmp->tm_sec;
1932
1933 ip = mon_lengths[isleap(y)];
1934 for (tmp->tm_mon = 0; idays >= ip[tmp->tm_mon]; ++(tmp->tm_mon))
1935 idays -= ip[tmp->tm_mon];
1936 tmp->tm_mday = idays + 1;
1937 tmp->tm_isdst = 0;
1938 #ifdef TM_GMTOFF
1939 tmp->TM_GMTOFF = offset;
1940 #endif /* defined TM_GMTOFF */
1941 return tmp;
1942 }
1943
1944 char *
1945 ctime(const time_t *timep)
1946 {
1947 /*
1948 ** Section 4.12.3.2 of X3.159-1989 requires that
1949 ** The ctime function converts the calendar time pointed to by timer
1950 ** to local time in the form of a string. It is equivalent to
1951 ** asctime(localtime(timer))
1952 */
1953 struct tm *tmp = localtime(timep);
1954 return tmp ? asctime(tmp) : NULL;
1955 }
1956
1957 char *
1958 ctime_r(const time_t *timep, char *buf)
1959 {
1960 struct tm mytm;
1961 struct tm *tmp = localtime_r(timep, &mytm);
1962 return tmp ? asctime_r(tmp, buf) : NULL;
1963 }
1964
1965 char *
1966 ctime_rz(const timezone_t sp, const time_t * timep, char *buf)
1967 {
1968 struct tm mytm, *rtm;
1969
1970 rtm = localtime_rz(sp, timep, &mytm);
1971 if (rtm == NULL)
1972 return NULL;
1973 return asctime_r(rtm, buf);
1974 }
1975
1976 /*
1977 ** Adapted from code provided by Robert Elz, who writes:
1978 ** The "best" way to do mktime I think is based on an idea of Bob
1979 ** Kridle's (so its said...) from a long time ago.
1980 ** It does a binary search of the time_t space. Since time_t's are
1981 ** just 32 bits, its a max of 32 iterations (even at 64 bits it
1982 ** would still be very reasonable).
1983 */
1984
1985 #ifndef WRONG
1986 #define WRONG ((time_t)-1)
1987 #endif /* !defined WRONG */
1988
1989 /*
1990 ** Normalize logic courtesy Paul Eggert.
1991 */
1992
1993 static bool
1994 increment_overflow(int *ip, int j)
1995 {
1996 register int const i = *ip;
1997
1998 /*
1999 ** If i >= 0 there can only be overflow if i + j > INT_MAX
2000 ** or if j > INT_MAX - i; given i >= 0, INT_MAX - i cannot overflow.
2001 ** If i < 0 there can only be overflow if i + j < INT_MIN
2002 ** or if j < INT_MIN - i; given i < 0, INT_MIN - i cannot overflow.
2003 */
2004 if ((i >= 0) ? (j > INT_MAX - i) : (j < INT_MIN - i))
2005 return true;
2006 *ip += j;
2007 return false;
2008 }
2009
2010 static bool
2011 increment_overflow32(int_fast32_t *const lp, int const m)
2012 {
2013 register int_fast32_t const l = *lp;
2014
2015 if ((l >= 0) ? (m > INT_FAST32_MAX - l) : (m < INT_FAST32_MIN - l))
2016 return true;
2017 *lp += m;
2018 return false;
2019 }
2020
2021 static bool
2022 increment_overflow_time(__time_t *tp, int_fast32_t j)
2023 {
2024 /*
2025 ** This is like
2026 ** 'if (! (TIME_T_MIN <= *tp + j && *tp + j <= TIME_T_MAX)) ...',
2027 ** except that it does the right thing even if *tp + j would overflow.
2028 */
2029 if (! (j < 0
2030 ? (TYPE_SIGNED(time_t) ? TIME_T_MIN - j <= *tp : -1 - j < *tp)
2031 : *tp <= TIME_T_MAX - j))
2032 return true;
2033 *tp += j;
2034 return false;
2035 }
2036
2037 static bool
2038 normalize_overflow(int *const tensptr, int *const unitsptr, const int base)
2039 {
2040 register int tensdelta;
2041
2042 tensdelta = (*unitsptr >= 0) ?
2043 (*unitsptr / base) :
2044 (-1 - (-1 - *unitsptr) / base);
2045 *unitsptr -= tensdelta * base;
2046 return increment_overflow(tensptr, tensdelta);
2047 }
2048
2049 static bool
2050 normalize_overflow32(int_fast32_t *tensptr, int *unitsptr, int base)
2051 {
2052 register int tensdelta;
2053
2054 tensdelta = (*unitsptr >= 0) ?
2055 (*unitsptr / base) :
2056 (-1 - (-1 - *unitsptr) / base);
2057 *unitsptr -= tensdelta * base;
2058 return increment_overflow32(tensptr, tensdelta);
2059 }
2060
2061 static int
2062 tmcomp(register const struct tm *const atmp,
2063 register const struct tm *const btmp)
2064 {
2065 register int result;
2066
2067 if (atmp->tm_year != btmp->tm_year)
2068 return atmp->tm_year < btmp->tm_year ? -1 : 1;
2069 if ((result = (atmp->tm_mon - btmp->tm_mon)) == 0 &&
2070 (result = (atmp->tm_mday - btmp->tm_mday)) == 0 &&
2071 (result = (atmp->tm_hour - btmp->tm_hour)) == 0 &&
2072 (result = (atmp->tm_min - btmp->tm_min)) == 0)
2073 result = atmp->tm_sec - btmp->tm_sec;
2074 return result;
2075 }
2076
2077 static time_t
2078 time2sub(struct tm *const tmp,
2079 struct tm *(*funcp)(struct state const *, time_t const *,
2080 int_fast32_t, struct tm *),
2081 struct state const *sp,
2082 const int_fast32_t offset,
2083 bool *okayp,
2084 bool do_norm_secs)
2085 {
2086 register int dir;
2087 register int i, j;
2088 register int saved_seconds;
2089 register int_fast32_t li;
2090 register time_t lo;
2091 register time_t hi;
2092 #ifdef NO_ERROR_IN_DST_GAP
2093 time_t ilo;
2094 #endif
2095 int_fast32_t y;
2096 time_t newt;
2097 time_t t;
2098 struct tm yourtm, mytm;
2099
2100 *okayp = false;
2101 yourtm = *tmp;
2102 #ifdef NO_ERROR_IN_DST_GAP
2103 again:
2104 #endif
2105 if (do_norm_secs) {
2106 if (normalize_overflow(&yourtm.tm_min, &yourtm.tm_sec,
2107 SECSPERMIN))
2108 goto out_of_range;
2109 }
2110 if (normalize_overflow(&yourtm.tm_hour, &yourtm.tm_min, MINSPERHOUR))
2111 goto out_of_range;
2112 if (normalize_overflow(&yourtm.tm_mday, &yourtm.tm_hour, HOURSPERDAY))
2113 goto out_of_range;
2114 y = yourtm.tm_year;
2115 if (normalize_overflow32(&y, &yourtm.tm_mon, MONSPERYEAR))
2116 goto out_of_range;
2117 /*
2118 ** Turn y into an actual year number for now.
2119 ** It is converted back to an offset from TM_YEAR_BASE later.
2120 */
2121 if (increment_overflow32(&y, TM_YEAR_BASE))
2122 goto out_of_range;
2123 while (yourtm.tm_mday <= 0) {
2124 if (increment_overflow32(&y, -1))
2125 goto out_of_range;
2126 li = y + (1 < yourtm.tm_mon);
2127 yourtm.tm_mday += year_lengths[isleap(li)];
2128 }
2129 while (yourtm.tm_mday > DAYSPERLYEAR) {
2130 li = y + (1 < yourtm.tm_mon);
2131 yourtm.tm_mday -= year_lengths[isleap(li)];
2132 if (increment_overflow32(&y, 1))
2133 goto out_of_range;
2134 }
2135 for ( ; ; ) {
2136 i = mon_lengths[isleap(y)][yourtm.tm_mon];
2137 if (yourtm.tm_mday <= i)
2138 break;
2139 yourtm.tm_mday -= i;
2140 if (++yourtm.tm_mon >= MONSPERYEAR) {
2141 yourtm.tm_mon = 0;
2142 if (increment_overflow32(&y, 1))
2143 goto out_of_range;
2144 }
2145 }
2146 if (increment_overflow32(&y, -TM_YEAR_BASE))
2147 goto out_of_range;
2148 if (! (INT_MIN <= y && y <= INT_MAX))
2149 goto out_of_range;
2150 yourtm.tm_year = (int)y;
2151 if (yourtm.tm_sec >= 0 && yourtm.tm_sec < SECSPERMIN)
2152 saved_seconds = 0;
2153 else if (y + TM_YEAR_BASE < EPOCH_YEAR) {
2154 /*
2155 ** We can't set tm_sec to 0, because that might push the
2156 ** time below the minimum representable time.
2157 ** Set tm_sec to 59 instead.
2158 ** This assumes that the minimum representable time is
2159 ** not in the same minute that a leap second was deleted from,
2160 ** which is a safer assumption than using 58 would be.
2161 */
2162 if (increment_overflow(&yourtm.tm_sec, 1 - SECSPERMIN))
2163 goto out_of_range;
2164 saved_seconds = yourtm.tm_sec;
2165 yourtm.tm_sec = SECSPERMIN - 1;
2166 } else {
2167 saved_seconds = yourtm.tm_sec;
2168 yourtm.tm_sec = 0;
2169 }
2170 /*
2171 ** Do a binary search (this works whatever time_t's type is).
2172 */
2173 lo = TIME_T_MIN;
2174 hi = TIME_T_MAX;
2175 #ifdef NO_ERROR_IN_DST_GAP
2176 ilo = lo;
2177 #endif
2178 for ( ; ; ) {
2179 t = lo / 2 + hi / 2;
2180 if (t < lo)
2181 t = lo;
2182 else if (t > hi)
2183 t = hi;
2184 if (! funcp(sp, &t, offset, &mytm)) {
2185 /*
2186 ** Assume that t is too extreme to be represented in
2187 ** a struct tm; arrange things so that it is less
2188 ** extreme on the next pass.
2189 */
2190 dir = (t > 0) ? 1 : -1;
2191 } else dir = tmcomp(&mytm, &yourtm);
2192 if (dir != 0) {
2193 if (t == lo) {
2194 if (t == TIME_T_MAX)
2195 goto out_of_range;
2196 ++t;
2197 ++lo;
2198 } else if (t == hi) {
2199 if (t == TIME_T_MIN)
2200 goto out_of_range;
2201 --t;
2202 --hi;
2203 }
2204 #ifdef NO_ERROR_IN_DST_GAP
2205 if (ilo != lo && lo - 1 == hi && yourtm.tm_isdst < 0 &&
2206 do_norm_secs) {
2207 for (i = sp->typecnt - 1; i >= 0; --i) {
2208 for (j = sp->typecnt - 1; j >= 0; --j) {
2209 time_t off;
2210 if (sp->ttis[j].tt_isdst ==
2211 sp->ttis[i].tt_isdst)
2212 continue;
2213 if (ttunspecified(sp, j))
2214 continue;
2215 off = sp->ttis[j].tt_utoff -
2216 sp->ttis[i].tt_utoff;
2217 yourtm.tm_sec += off < 0 ?
2218 -off : off;
2219 goto again;
2220 }
2221 }
2222 }
2223 #endif
2224 if (lo > hi)
2225 goto invalid;
2226 if (dir > 0)
2227 hi = t;
2228 else lo = t;
2229 continue;
2230 }
2231 #if defined TM_GMTOFF && ! UNINIT_TRAP
2232 if (mytm.TM_GMTOFF != yourtm.TM_GMTOFF
2233 && (yourtm.TM_GMTOFF < 0
2234 ? (-SECSPERDAY <= yourtm.TM_GMTOFF
2235 && (mytm.TM_GMTOFF <=
2236 (/*CONSTCOND*/SMALLEST(INT_FAST32_MAX, LONG_MAX)
2237 + yourtm.TM_GMTOFF)))
2238 : (yourtm.TM_GMTOFF <= SECSPERDAY
2239 && ((/*CONSTCOND*/BIGGEST(INT_FAST32_MIN, LONG_MIN)
2240 + yourtm.TM_GMTOFF)
2241 <= mytm.TM_GMTOFF)))) {
2242 /* MYTM matches YOURTM except with the wrong UT offset.
2243 YOURTM.TM_GMTOFF is plausible, so try it instead.
2244 It's OK if YOURTM.TM_GMTOFF contains uninitialized data,
2245 since the guess gets checked. */
2246 __time_t altt = t;
2247 int_fast32_t diff = (int_fast32_t)
2248 (mytm.TM_GMTOFF - yourtm.TM_GMTOFF);
2249 if (!increment_overflow_time(&altt, diff)) {
2250 struct tm alttm;
2251 time_t xaltt = (time_t)altt;
2252 if (funcp(sp, &xaltt, offset, &alttm)
2253 && alttm.tm_isdst == mytm.tm_isdst
2254 && alttm.TM_GMTOFF == yourtm.TM_GMTOFF
2255 && tmcomp(&alttm, &yourtm) == 0) {
2256 t = xaltt;
2257 mytm = alttm;
2258 }
2259 }
2260 }
2261 #endif
2262 if (yourtm.tm_isdst < 0 || mytm.tm_isdst == yourtm.tm_isdst)
2263 break;
2264 /*
2265 ** Right time, wrong type.
2266 ** Hunt for right time, right type.
2267 ** It's okay to guess wrong since the guess
2268 ** gets checked.
2269 */
2270 if (sp == NULL)
2271 goto invalid;
2272 for (i = sp->typecnt - 1; i >= 0; --i) {
2273 if (sp->ttis[i].tt_isdst != yourtm.tm_isdst)
2274 continue;
2275 for (j = sp->typecnt - 1; j >= 0; --j) {
2276 if (sp->ttis[j].tt_isdst == yourtm.tm_isdst)
2277 continue;
2278 newt = (time_t)(t + sp->ttis[j].tt_utoff -
2279 sp->ttis[i].tt_utoff);
2280 if (! funcp(sp, &newt, offset, &mytm))
2281 continue;
2282 if (tmcomp(&mytm, &yourtm) != 0)
2283 continue;
2284 if (mytm.tm_isdst != yourtm.tm_isdst)
2285 continue;
2286 /*
2287 ** We have a match.
2288 */
2289 t = newt;
2290 goto label;
2291 }
2292 }
2293 goto invalid;
2294 }
2295 label:
2296 newt = t + saved_seconds;
2297 if ((newt < t) != (saved_seconds < 0))
2298 goto out_of_range;
2299 t = newt;
2300 if (funcp(sp, &t, offset, tmp)) {
2301 *okayp = true;
2302 return t;
2303 }
2304 out_of_range:
2305 errno = EOVERFLOW;
2306 return WRONG;
2307 invalid:
2308 errno = EINVAL;
2309 return WRONG;
2310 }
2311
2312 static time_t
2313 time2(struct tm * const tmp,
2314 struct tm *(*funcp)(struct state const *, time_t const *,
2315 int_fast32_t, struct tm *),
2316 struct state const *sp,
2317 const int_fast32_t offset,
2318 bool *okayp)
2319 {
2320 time_t t;
2321
2322 /*
2323 ** First try without normalization of seconds
2324 ** (in case tm_sec contains a value associated with a leap second).
2325 ** If that fails, try with normalization of seconds.
2326 */
2327 t = time2sub(tmp, funcp, sp, offset, okayp, false);
2328 return *okayp ? t : time2sub(tmp, funcp, sp, offset, okayp, true);
2329 }
2330
2331 static time_t
2332 time1(struct tm *const tmp,
2333 struct tm *(*funcp)(struct state const *, time_t const *,
2334 int_fast32_t, struct tm *),
2335 struct state const *sp,
2336 const int_fast32_t offset)
2337 {
2338 register time_t t;
2339 register int samei, otheri;
2340 register int sameind, otherind;
2341 register int i;
2342 register int nseen;
2343 int save_errno;
2344 char seen[TZ_MAX_TYPES];
2345 unsigned char types[TZ_MAX_TYPES];
2346 bool okay;
2347
2348 if (tmp == NULL) {
2349 errno = EINVAL;
2350 return WRONG;
2351 }
2352 if (tmp->tm_isdst > 1)
2353 tmp->tm_isdst = 1;
2354 save_errno = errno;
2355 t = time2(tmp, funcp, sp, offset, &okay);
2356 if (okay) {
2357 errno = save_errno;
2358 return t;
2359 }
2360 if (tmp->tm_isdst < 0)
2361 #ifdef PCTS
2362 /*
2363 ** POSIX Conformance Test Suite code courtesy Grant Sullivan.
2364 */
2365 tmp->tm_isdst = 0; /* reset to std and try again */
2366 #else
2367 return t;
2368 #endif /* !defined PCTS */
2369 /*
2370 ** We're supposed to assume that somebody took a time of one type
2371 ** and did some math on it that yielded a "struct tm" that's bad.
2372 ** We try to divine the type they started from and adjust to the
2373 ** type they need.
2374 */
2375 if (sp == NULL) {
2376 errno = EINVAL;
2377 return WRONG;
2378 }
2379 for (i = 0; i < sp->typecnt; ++i)
2380 seen[i] = false;
2381 nseen = 0;
2382 for (i = sp->timecnt - 1; i >= 0; --i)
2383 if (!seen[sp->types[i]] && !ttunspecified(sp, sp->types[i])) {
2384 seen[sp->types[i]] = true;
2385 types[nseen++] = sp->types[i];
2386 }
2387 for (sameind = 0; sameind < nseen; ++sameind) {
2388 samei = types[sameind];
2389 if (sp->ttis[samei].tt_isdst != tmp->tm_isdst)
2390 continue;
2391 for (otherind = 0; otherind < nseen; ++otherind) {
2392 otheri = types[otherind];
2393 if (sp->ttis[otheri].tt_isdst == tmp->tm_isdst)
2394 continue;
2395 tmp->tm_sec += (int)(sp->ttis[otheri].tt_utoff
2396 - sp->ttis[samei].tt_utoff);
2397 tmp->tm_isdst = !tmp->tm_isdst;
2398 t = time2(tmp, funcp, sp, offset, &okay);
2399 if (okay) {
2400 errno = save_errno;
2401 return t;
2402 }
2403 tmp->tm_sec -= (int)(sp->ttis[otheri].tt_utoff
2404 - sp->ttis[samei].tt_utoff);
2405 tmp->tm_isdst = !tmp->tm_isdst;
2406 }
2407 }
2408 errno = EOVERFLOW;
2409 return WRONG;
2410 }
2411
2412 static time_t
2413 mktime_tzname(timezone_t sp, struct tm *tmp, bool setname)
2414 {
2415 if (sp)
2416 return time1(tmp, localsub, sp, setname);
2417 else {
2418 gmtcheck();
2419 return time1(tmp, gmtsub, gmtptr, 0);
2420 }
2421 }
2422
2423 #if NETBSD_INSPIRED
2424
2425 time_t
2426 mktime_z(timezone_t sp, struct tm *const tmp)
2427 {
2428 return mktime_tzname(sp, tmp, false);
2429 }
2430
2431 #endif
2432
2433 time_t
2434 mktime(struct tm *tmp)
2435 {
2436 time_t t;
2437
2438 rwlock_wrlock(&__lcl_lock);
2439 tzset_unlocked();
2440 t = mktime_tzname(__lclptr, tmp, true);
2441 rwlock_unlock(&__lcl_lock);
2442 return t;
2443 }
2444
2445 #ifdef STD_INSPIRED
2446
2447 time_t
2448 timelocal_z(const timezone_t sp, struct tm *const tmp)
2449 {
2450 if (tmp != NULL)
2451 tmp->tm_isdst = -1; /* in case it wasn't initialized */
2452 return mktime_z(sp, tmp);
2453 }
2454
2455 time_t
2456 timelocal(struct tm *tmp)
2457 {
2458 if (tmp != NULL)
2459 tmp->tm_isdst = -1; /* in case it wasn't initialized */
2460 return mktime(tmp);
2461 }
2462
2463 time_t
2464 timegm(struct tm *tmp)
2465 {
2466 return timeoff(tmp, 0);
2467 }
2468
2469 time_t
2470 timeoff(struct tm *tmp, long offset)
2471 {
2472 if (tmp)
2473 tmp->tm_isdst = 0;
2474 gmtcheck();
2475 return time1(tmp, gmtsub, gmtptr, (int_fast32_t)offset);
2476 }
2477
2478 #endif /* defined STD_INSPIRED */
2479
2480 static int_fast32_t
2481 leapcorr(struct state const *sp, time_t t)
2482 {
2483 register struct lsinfo const * lp;
2484 register int i;
2485
2486 i = sp->leapcnt;
2487 while (--i >= 0) {
2488 lp = &sp->lsis[i];
2489 if (t >= lp->ls_trans)
2490 return lp->ls_corr;
2491 }
2492 return 0;
2493 }
2494
2495 /* NETBSD_INSPIRED_EXTERN functions are exported to callers if
2496 NETBSD_INSPIRED is defined, and are private otherwise. */
2497 # if NETBSD_INSPIRED
2498 # define NETBSD_INSPIRED_EXTERN
2499 # else
2500 # define NETBSD_INSPIRED_EXTERN static
2501 # endif
2502
2503 /*
2504 ** IEEE Std 1003.1 (POSIX) says that 536457599
2505 ** shall correspond to "Wed Dec 31 23:59:59 UTC 1986", which
2506 ** is not the case if we are accounting for leap seconds.
2507 ** So, we provide the following conversion routines for use
2508 ** when exchanging timestamps with POSIX conforming systems.
2509 */
2510
2511 NETBSD_INSPIRED_EXTERN time_t
2512 time2posix_z(timezone_t sp, time_t t)
2513 {
2514 return (time_t)(t - leapcorr(sp, t));
2515 }
2516
2517 time_t
2518 time2posix(time_t t)
2519 {
2520 rwlock_wrlock(&__lcl_lock);
2521 if (!lcl_is_set)
2522 tzset_unlocked();
2523 if (__lclptr)
2524 t = (time_t)(t - leapcorr(__lclptr, t));
2525 rwlock_unlock(&__lcl_lock);
2526 return t;
2527 }
2528
2529 /*
2530 ** XXX--is the below the right way to conditionalize??
2531 */
2532
2533 #ifdef STD_INSPIRED
2534
2535 NETBSD_INSPIRED_EXTERN time_t
2536 posix2time_z(timezone_t sp, time_t t)
2537 {
2538 time_t x;
2539 time_t y;
2540 /*
2541 ** For a positive leap second hit, the result
2542 ** is not unique. For a negative leap second
2543 ** hit, the corresponding time doesn't exist,
2544 ** so we return an adjacent second.
2545 */
2546 x = (time_t)(t + leapcorr(sp, t));
2547 y = (time_t)(x - leapcorr(sp, x));
2548 if (y < t) {
2549 do {
2550 x++;
2551 y = (time_t)(x - leapcorr(sp, x));
2552 } while (y < t);
2553 x -= y != t;
2554 } else if (y > t) {
2555 do {
2556 --x;
2557 y = (time_t)(x - leapcorr(sp, x));
2558 } while (y > t);
2559 x += y != t;
2560 }
2561 return x;
2562 }
2563
2564 time_t
2565 posix2time(time_t t)
2566 {
2567 rwlock_wrlock(&__lcl_lock);
2568 if (!lcl_is_set)
2569 tzset_unlocked();
2570 if (__lclptr)
2571 t = posix2time_z(__lclptr, t);
2572 rwlock_unlock(&__lcl_lock);
2573 return t;
2574 }
2575
2576 #endif /* defined STD_INSPIRED */
2577