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