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