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