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