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