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