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