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