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