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