Home | History | Annotate | Line # | Download | only in time
localtime.c revision 1.119
      1 /*	$NetBSD: localtime.c,v 1.119 2019/04/07 14:58:25 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.119 2019/04/07 14:58:25 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[sp->types[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[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, '.')) != NULL; 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 = 1;
   1395 		sp->charcnt = 0;
   1396 		sp->goback = sp->goahead = false;
   1397 		sp->types[0] = 0;
   1398 		init_ttinfo(&sp->ttis[0], 0, false, 0);
   1399 		strcpy(sp->chars, gmt);
   1400 		sp->defaulttype = 0;
   1401 		return 0;
   1402 	} else {
   1403 		int err = tzload(name, sp, true);
   1404 		if (err != 0 && name && name[0] != ':' &&
   1405 		    tzparse(name, sp, false))
   1406 			err = 0;
   1407 		if (err == 0)
   1408 			scrub_abbrs(sp);
   1409 		return err;
   1410 	}
   1411 }
   1412 
   1413 static void
   1414 tzsetlcl(char const *name)
   1415 {
   1416 	struct state *sp = __lclptr;
   1417 	int lcl = name ? strlen(name) < sizeof lcl_TZname : -1;
   1418 	if (lcl < 0 ? lcl_is_set < 0
   1419 	    : 0 < lcl_is_set && strcmp(lcl_TZname, name) == 0)
   1420 		return;
   1421 
   1422 	if (! sp)
   1423 		__lclptr = sp = malloc(sizeof *__lclptr);
   1424 	if (sp) {
   1425 		if (zoneinit(sp, name) != 0)
   1426 			zoneinit(sp, "");
   1427 		if (0 < lcl)
   1428 			strcpy(lcl_TZname, name);
   1429 	}
   1430 	settzname();
   1431 	lcl_is_set = lcl;
   1432 }
   1433 
   1434 #ifdef STD_INSPIRED
   1435 void
   1436 tzsetwall(void)
   1437 {
   1438 	rwlock_wrlock(&__lcl_lock);
   1439 	tzsetlcl(NULL);
   1440 	rwlock_unlock(&__lcl_lock);
   1441 }
   1442 #endif
   1443 
   1444 void
   1445 tzset_unlocked(void)
   1446 {
   1447 	tzsetlcl(getenv("TZ"));
   1448 }
   1449 
   1450 void
   1451 tzset(void)
   1452 {
   1453 	rwlock_wrlock(&__lcl_lock);
   1454 	tzset_unlocked();
   1455 	rwlock_unlock(&__lcl_lock);
   1456 }
   1457 
   1458 static void
   1459 gmtcheck(void)
   1460 {
   1461 	static bool gmt_is_set;
   1462 	rwlock_wrlock(&__lcl_lock);
   1463 	if (! gmt_is_set) {
   1464 		gmtptr = malloc(sizeof *gmtptr);
   1465 		if (gmtptr)
   1466 			gmtload(gmtptr);
   1467 		gmt_is_set = true;
   1468 	}
   1469 	rwlock_unlock(&__lcl_lock);
   1470 }
   1471 
   1472 #if NETBSD_INSPIRED
   1473 
   1474 timezone_t
   1475 tzalloc(const char *name)
   1476 {
   1477 	timezone_t sp = malloc(sizeof *sp);
   1478 	if (sp) {
   1479 		int err = zoneinit(sp, name);
   1480 		if (err != 0) {
   1481 			free(sp);
   1482 			errno = err;
   1483 			return NULL;
   1484 		}
   1485 	}
   1486 	return sp;
   1487 }
   1488 
   1489 void
   1490 tzfree(timezone_t sp)
   1491 {
   1492 	free(sp);
   1493 }
   1494 
   1495 /*
   1496 ** NetBSD 6.1.4 has ctime_rz, but omit it because POSIX says ctime and
   1497 ** ctime_r are obsolescent and have potential security problems that
   1498 ** ctime_rz would share.  Callers can instead use localtime_rz + strftime.
   1499 **
   1500 ** NetBSD 6.1.4 has tzgetname, but omit it because it doesn't work
   1501 ** in zones with three or more time zone abbreviations.
   1502 ** Callers can instead use localtime_rz + strftime.
   1503 */
   1504 
   1505 #endif
   1506 
   1507 /*
   1508 ** The easy way to behave "as if no library function calls" localtime
   1509 ** is to not call it, so we drop its guts into "localsub", which can be
   1510 ** freely called. (And no, the PANS doesn't require the above behavior,
   1511 ** but it *is* desirable.)
   1512 **
   1513 ** If successful and SETNAME is nonzero,
   1514 ** set the applicable parts of tzname, timezone and altzone;
   1515 ** however, it's OK to omit this step if the timezone is POSIX-compatible,
   1516 ** since in that case tzset should have already done this step correctly.
   1517 ** SETNAME's type is intfast32_t for compatibility with gmtsub,
   1518 ** but it is actually a boolean and its value should be 0 or 1.
   1519 */
   1520 
   1521 /*ARGSUSED*/
   1522 static struct tm *
   1523 localsub(struct state const *sp, time_t const *timep, int_fast32_t setname,
   1524 	 struct tm *const tmp)
   1525 {
   1526 	const struct ttinfo *	ttisp;
   1527 	int			i;
   1528 	struct tm *		result;
   1529 	const time_t			t = *timep;
   1530 
   1531 	if (sp == NULL) {
   1532 		/* Don't bother to set tzname etc.; tzset has already done it.  */
   1533 		return gmtsub(gmtptr, timep, 0, tmp);
   1534 	}
   1535 	if ((sp->goback && t < sp->ats[0]) ||
   1536 		(sp->goahead && t > sp->ats[sp->timecnt - 1])) {
   1537 			time_t			newt = t;
   1538 			time_t		seconds;
   1539 			time_t		years;
   1540 
   1541 			if (t < sp->ats[0])
   1542 				seconds = sp->ats[0] - t;
   1543 			else	seconds = t - sp->ats[sp->timecnt - 1];
   1544 			--seconds;
   1545 			years = (time_t)((seconds / SECSPERREPEAT + 1) * YEARSPERREPEAT);
   1546 			seconds = (time_t)(years * AVGSECSPERYEAR);
   1547 			if (t < sp->ats[0])
   1548 				newt += seconds;
   1549 			else	newt -= seconds;
   1550 			if (newt < sp->ats[0] ||
   1551 				newt > sp->ats[sp->timecnt - 1]) {
   1552 				errno = EINVAL;
   1553 				return NULL;	/* "cannot happen" */
   1554 			}
   1555 			result = localsub(sp, &newt, setname, tmp);
   1556 			if (result) {
   1557 				int_fast64_t newy;
   1558 
   1559 				newy = result->tm_year;
   1560 				if (t < sp->ats[0])
   1561 					newy -= years;
   1562 				else	newy += years;
   1563 				if (! (INT_MIN <= newy && newy <= INT_MAX)) {
   1564 					errno = EOVERFLOW;
   1565 					return NULL;
   1566 				}
   1567 				result->tm_year = (int)newy;
   1568 			}
   1569 			return result;
   1570 	}
   1571 	if (sp->timecnt == 0 || t < sp->ats[0]) {
   1572 		i = sp->defaulttype;
   1573 	} else {
   1574 		int	lo = 1;
   1575 		int	hi = sp->timecnt;
   1576 
   1577 		while (lo < hi) {
   1578 			int	mid = (lo + hi) / 2;
   1579 
   1580 			if (t < sp->ats[mid])
   1581 				hi = mid;
   1582 			else	lo = mid + 1;
   1583 		}
   1584 		i = (int) sp->types[lo - 1];
   1585 	}
   1586 	ttisp = &sp->ttis[i];
   1587 	/*
   1588 	** To get (wrong) behavior that's compatible with System V Release 2.0
   1589 	** you'd replace the statement below with
   1590 	**	t += ttisp->tt_gmtoff;
   1591 	**	timesub(&t, 0L, sp, tmp);
   1592 	*/
   1593 	result = timesub(&t, ttisp->tt_gmtoff, sp, tmp);
   1594 	if (result) {
   1595 		result->tm_isdst = ttisp->tt_isdst;
   1596 #ifdef TM_ZONE
   1597 		result->TM_ZONE = __UNCONST(&sp->chars[ttisp->tt_abbrind]);
   1598 #endif /* defined TM_ZONE */
   1599 		if (setname)
   1600 			update_tzname_etc(sp, ttisp);
   1601 	}
   1602 	return result;
   1603 }
   1604 
   1605 #if NETBSD_INSPIRED
   1606 
   1607 struct tm *
   1608 localtime_rz(timezone_t sp, time_t const *timep, struct tm *tmp)
   1609 {
   1610 	return localsub(sp, timep, 0, tmp);
   1611 }
   1612 
   1613 #endif
   1614 
   1615 static struct tm *
   1616 localtime_tzset(time_t const *timep, struct tm *tmp, bool setname)
   1617 {
   1618 	rwlock_wrlock(&__lcl_lock);
   1619 	if (setname || !lcl_is_set)
   1620 		tzset_unlocked();
   1621 	tmp = localsub(__lclptr, timep, setname, tmp);
   1622 	rwlock_unlock(&__lcl_lock);
   1623 	return tmp;
   1624 }
   1625 
   1626 struct tm *
   1627 localtime(const time_t *timep)
   1628 {
   1629 	return localtime_tzset(timep, &tm, true);
   1630 }
   1631 
   1632 struct tm *
   1633 localtime_r(const time_t * __restrict timep, struct tm *tmp)
   1634 {
   1635 	return localtime_tzset(timep, tmp, true);
   1636 }
   1637 
   1638 /*
   1639 ** gmtsub is to gmtime as localsub is to localtime.
   1640 */
   1641 
   1642 static struct tm *
   1643 gmtsub(struct state const *sp, const time_t *timep, int_fast32_t offset,
   1644        struct tm *tmp)
   1645 {
   1646 	struct tm *	result;
   1647 
   1648 	result = timesub(timep, offset, gmtptr, tmp);
   1649 #ifdef TM_ZONE
   1650 	/*
   1651 	** Could get fancy here and deliver something such as
   1652 	** "+xx" or "-xx" if offset is non-zero,
   1653 	** but this is no time for a treasure hunt.
   1654 	*/
   1655 	if (result)
   1656 		result->TM_ZONE = offset ? __UNCONST(wildabbr) : gmtptr ?
   1657 		    gmtptr->chars : __UNCONST(gmt);
   1658 #endif /* defined TM_ZONE */
   1659 	return result;
   1660 }
   1661 
   1662 
   1663 /*
   1664 ** Re-entrant version of gmtime.
   1665 */
   1666 
   1667 struct tm *
   1668 gmtime_r(const time_t *timep, struct tm *tmp)
   1669 {
   1670 	gmtcheck();
   1671 	return gmtsub(NULL, timep, 0, tmp);
   1672 }
   1673 
   1674 struct tm *
   1675 gmtime(const time_t *timep)
   1676 {
   1677 	return gmtime_r(timep, &tm);
   1678 }
   1679 #ifdef STD_INSPIRED
   1680 
   1681 struct tm *
   1682 offtime(const time_t *timep, long offset)
   1683 {
   1684 	gmtcheck();
   1685 	return gmtsub(gmtptr, timep, (int_fast32_t)offset, &tm);
   1686 }
   1687 
   1688 struct tm *
   1689 offtime_r(const time_t *timep, long offset, struct tm *tmp)
   1690 {
   1691 	gmtcheck();
   1692 	return gmtsub(NULL, timep, (int_fast32_t)offset, tmp);
   1693 }
   1694 
   1695 #endif /* defined STD_INSPIRED */
   1696 
   1697 #if TZ_TIME_T
   1698 
   1699 # if USG_COMPAT
   1700 #  define daylight 0
   1701 #  define timezone 0
   1702 # endif
   1703 # ifndef ALTZONE
   1704 #  define altzone 0
   1705 # endif
   1706 
   1707 /* Convert from the underlying system's time_t to the ersatz time_tz,
   1708    which is called 'time_t' in this file.  Typically, this merely
   1709    converts the time's integer width.  On some platforms, the system
   1710    time is local time not UT, or uses some epoch other than the POSIX
   1711    epoch.
   1712 
   1713    Although this code appears to define a function named 'time' that
   1714    returns time_t, the macros in private.h cause this code to actually
   1715    define a function named 'tz_time' that returns tz_time_t.  The call
   1716    to sys_time invokes the underlying system's 'time' function.  */
   1717 
   1718 time_t
   1719 time(time_t *p)
   1720 {
   1721   time_t r = sys_time(0);
   1722   if (r != (time_t) -1) {
   1723     int_fast32_t offset = EPOCH_LOCAL ? (daylight ? timezone : altzone) : 0;
   1724     if (increment_overflow32(&offset, -EPOCH_OFFSET)
   1725 	|| increment_overflow_time (&r, offset)) {
   1726       errno = EOVERFLOW;
   1727       r = -1;
   1728     }
   1729   }
   1730   if (p)
   1731     *p = r;
   1732   return r;
   1733 }
   1734 #endif
   1735 
   1736 /*
   1737 ** Return the number of leap years through the end of the given year
   1738 ** where, to make the math easy, the answer for year zero is defined as zero.
   1739 */
   1740 static int
   1741 leaps_thru_end_of_nonneg(int y)
   1742 {
   1743 	return y / 4 - y / 100 + y / 400;
   1744 }
   1745 
   1746 static int ATTRIBUTE_PURE
   1747 leaps_thru_end_of(const int y)
   1748 {
   1749 	return (y < 0
   1750 		? -1 - leaps_thru_end_of_nonneg(-1 - y)
   1751 		: leaps_thru_end_of_nonneg(y));
   1752 }
   1753 
   1754 static struct tm *
   1755 timesub(const time_t *timep, int_fast32_t offset,
   1756     const struct state *sp, struct tm *tmp)
   1757 {
   1758 	const struct lsinfo *	lp;
   1759 	time_t			tdays;
   1760 	int			idays;	/* unsigned would be so 2003 */
   1761 	int_fast64_t		rem;
   1762 	int			y;
   1763 	const int *		ip;
   1764 	int_fast64_t		corr;
   1765 	int			hit;
   1766 	int			i;
   1767 
   1768 	corr = 0;
   1769 	hit = false;
   1770 	i = (sp == NULL) ? 0 : sp->leapcnt;
   1771 	while (--i >= 0) {
   1772 		lp = &sp->lsis[i];
   1773 		if (*timep >= lp->ls_trans) {
   1774 			corr = lp->ls_corr;
   1775 			hit = (*timep == lp->ls_trans
   1776 			       && (i == 0 ? 0 : lp[-1].ls_corr) < corr);
   1777 			break;
   1778 		}
   1779 	}
   1780 	y = EPOCH_YEAR;
   1781 	tdays = (time_t)(*timep / SECSPERDAY);
   1782 	rem = *timep % SECSPERDAY;
   1783 	while (tdays < 0 || tdays >= year_lengths[isleap(y)]) {
   1784 		int		newy;
   1785 		time_t	tdelta;
   1786 		int	idelta;
   1787 		int	leapdays;
   1788 
   1789 		tdelta = tdays / DAYSPERLYEAR;
   1790 		if (! ((! TYPE_SIGNED(time_t) || INT_MIN <= tdelta)
   1791 		       && tdelta <= INT_MAX))
   1792 			goto out_of_range;
   1793 		_DIAGASSERT(__type_fit(int, tdelta));
   1794 		idelta = (int)tdelta;
   1795 		if (idelta == 0)
   1796 			idelta = (tdays < 0) ? -1 : 1;
   1797 		newy = y;
   1798 		if (increment_overflow(&newy, idelta))
   1799 			goto out_of_range;
   1800 		leapdays = leaps_thru_end_of(newy - 1) -
   1801 			leaps_thru_end_of(y - 1);
   1802 		tdays -= ((time_t) newy - y) * DAYSPERNYEAR;
   1803 		tdays -= leapdays;
   1804 		y = newy;
   1805 	}
   1806 	/*
   1807 	** Given the range, we can now fearlessly cast...
   1808 	*/
   1809 	idays = (int) tdays;
   1810 	rem += offset - corr;
   1811 	while (rem < 0) {
   1812 		rem += SECSPERDAY;
   1813 		--idays;
   1814 	}
   1815 	while (rem >= SECSPERDAY) {
   1816 		rem -= SECSPERDAY;
   1817 		++idays;
   1818 	}
   1819 	while (idays < 0) {
   1820 		if (increment_overflow(&y, -1))
   1821 			goto out_of_range;
   1822 		idays += year_lengths[isleap(y)];
   1823 	}
   1824 	while (idays >= year_lengths[isleap(y)]) {
   1825 		idays -= year_lengths[isleap(y)];
   1826 		if (increment_overflow(&y, 1))
   1827 			goto out_of_range;
   1828 	}
   1829 	tmp->tm_year = y;
   1830 	if (increment_overflow(&tmp->tm_year, -TM_YEAR_BASE))
   1831 		goto out_of_range;
   1832 	tmp->tm_yday = idays;
   1833 	/*
   1834 	** The "extra" mods below avoid overflow problems.
   1835 	*/
   1836 	tmp->tm_wday = EPOCH_WDAY +
   1837 		((y - EPOCH_YEAR) % DAYSPERWEEK) *
   1838 		(DAYSPERNYEAR % DAYSPERWEEK) +
   1839 		leaps_thru_end_of(y - 1) -
   1840 		leaps_thru_end_of(EPOCH_YEAR - 1) +
   1841 		idays;
   1842 	tmp->tm_wday %= DAYSPERWEEK;
   1843 	if (tmp->tm_wday < 0)
   1844 		tmp->tm_wday += DAYSPERWEEK;
   1845 	tmp->tm_hour = (int) (rem / SECSPERHOUR);
   1846 	rem %= SECSPERHOUR;
   1847 	tmp->tm_min = (int) (rem / SECSPERMIN);
   1848 	/*
   1849 	** A positive leap second requires a special
   1850 	** representation. This uses "... ??:59:60" et seq.
   1851 	*/
   1852 	tmp->tm_sec = (int) (rem % SECSPERMIN) + hit;
   1853 	ip = mon_lengths[isleap(y)];
   1854 	for (tmp->tm_mon = 0; idays >= ip[tmp->tm_mon]; ++(tmp->tm_mon))
   1855 		idays -= ip[tmp->tm_mon];
   1856 	tmp->tm_mday = (int) (idays + 1);
   1857 	tmp->tm_isdst = 0;
   1858 #ifdef TM_GMTOFF
   1859 	tmp->TM_GMTOFF = offset;
   1860 #endif /* defined TM_GMTOFF */
   1861 	return tmp;
   1862 out_of_range:
   1863 	errno = EOVERFLOW;
   1864 	return NULL;
   1865 }
   1866 
   1867 char *
   1868 ctime(const time_t *timep)
   1869 {
   1870 /*
   1871 ** Section 4.12.3.2 of X3.159-1989 requires that
   1872 **	The ctime function converts the calendar time pointed to by timer
   1873 **	to local time in the form of a string. It is equivalent to
   1874 **		asctime(localtime(timer))
   1875 */
   1876 	struct tm *tmp = localtime(timep);
   1877 	return tmp ? asctime(tmp) : NULL;
   1878 }
   1879 
   1880 char *
   1881 ctime_r(const time_t *timep, char *buf)
   1882 {
   1883 	struct tm mytm;
   1884 	struct tm *tmp = localtime_r(timep, &mytm);
   1885 	return tmp ? asctime_r(tmp, buf) : NULL;
   1886 }
   1887 
   1888 char *
   1889 ctime_rz(const timezone_t sp, const time_t * timep, char *buf)
   1890 {
   1891 	struct tm	mytm, *rtm;
   1892 
   1893 	rtm = localtime_rz(sp, timep, &mytm);
   1894 	if (rtm == NULL)
   1895 		return NULL;
   1896 	return asctime_r(rtm, buf);
   1897 }
   1898 
   1899 /*
   1900 ** Adapted from code provided by Robert Elz, who writes:
   1901 **	The "best" way to do mktime I think is based on an idea of Bob
   1902 **	Kridle's (so its said...) from a long time ago.
   1903 **	It does a binary search of the time_t space. Since time_t's are
   1904 **	just 32 bits, its a max of 32 iterations (even at 64 bits it
   1905 **	would still be very reasonable).
   1906 */
   1907 
   1908 #ifndef WRONG
   1909 #define WRONG	((time_t)-1)
   1910 #endif /* !defined WRONG */
   1911 
   1912 /*
   1913 ** Normalize logic courtesy Paul Eggert.
   1914 */
   1915 
   1916 static bool
   1917 increment_overflow(int *ip, int j)
   1918 {
   1919 	int const	i = *ip;
   1920 
   1921 	/*
   1922 	** If i >= 0 there can only be overflow if i + j > INT_MAX
   1923 	** or if j > INT_MAX - i; given i >= 0, INT_MAX - i cannot overflow.
   1924 	** If i < 0 there can only be overflow if i + j < INT_MIN
   1925 	** or if j < INT_MIN - i; given i < 0, INT_MIN - i cannot overflow.
   1926 	*/
   1927 	if ((i >= 0) ? (j > INT_MAX - i) : (j < INT_MIN - i))
   1928 		return true;
   1929 	*ip += j;
   1930 	return false;
   1931 }
   1932 
   1933 static bool
   1934 increment_overflow32(int_fast32_t *const lp, int const m)
   1935 {
   1936 	int_fast32_t const l = *lp;
   1937 
   1938 	if ((l >= 0) ? (m > INT_FAST32_MAX - l) : (m < INT_FAST32_MIN - l))
   1939 		return true;
   1940 	*lp += m;
   1941 	return false;
   1942 }
   1943 
   1944 static bool
   1945 increment_overflow_time(time_t *tp, int_fast32_t j)
   1946 {
   1947 	/*
   1948 	** This is like
   1949 	** 'if (! (TIME_T_MIN <= *tp + j && *tp + j <= TIME_T_MAX)) ...',
   1950 	** except that it does the right thing even if *tp + j would overflow.
   1951 	*/
   1952 	if (! (j < 0
   1953 	       ? (TYPE_SIGNED(time_t) ? TIME_T_MIN - j <= *tp : -1 - j < *tp)
   1954 	       : *tp <= TIME_T_MAX - j))
   1955 		return true;
   1956 	*tp += j;
   1957 	return false;
   1958 }
   1959 
   1960 static bool
   1961 normalize_overflow(int *const tensptr, int *const unitsptr, const int base)
   1962 {
   1963 	int	tensdelta;
   1964 
   1965 	tensdelta = (*unitsptr >= 0) ?
   1966 		(*unitsptr / base) :
   1967 		(-1 - (-1 - *unitsptr) / base);
   1968 	*unitsptr -= tensdelta * base;
   1969 	return increment_overflow(tensptr, tensdelta);
   1970 }
   1971 
   1972 static bool
   1973 normalize_overflow32(int_fast32_t *tensptr, int *unitsptr, int base)
   1974 {
   1975 	int	tensdelta;
   1976 
   1977 	tensdelta = (*unitsptr >= 0) ?
   1978 		(*unitsptr / base) :
   1979 		(-1 - (-1 - *unitsptr) / base);
   1980 	*unitsptr -= tensdelta * base;
   1981 	return increment_overflow32(tensptr, tensdelta);
   1982 }
   1983 
   1984 static int
   1985 tmcomp(const struct tm *const atmp,
   1986        const struct tm *const btmp)
   1987 {
   1988 	int	result;
   1989 
   1990 	if (atmp->tm_year != btmp->tm_year)
   1991 		return atmp->tm_year < btmp->tm_year ? -1 : 1;
   1992 	if ((result = (atmp->tm_mon - btmp->tm_mon)) == 0 &&
   1993 		(result = (atmp->tm_mday - btmp->tm_mday)) == 0 &&
   1994 		(result = (atmp->tm_hour - btmp->tm_hour)) == 0 &&
   1995 		(result = (atmp->tm_min - btmp->tm_min)) == 0)
   1996 			result = atmp->tm_sec - btmp->tm_sec;
   1997 	return result;
   1998 }
   1999 
   2000 static time_t
   2001 time2sub(struct tm *const tmp,
   2002 	 struct tm *(*funcp)(struct state const *, time_t const *,
   2003 			     int_fast32_t, struct tm *),
   2004 	 struct state const *sp,
   2005  	 const int_fast32_t offset,
   2006 	 bool *okayp,
   2007 	 bool do_norm_secs)
   2008 {
   2009 	int			dir;
   2010 	int			i, j;
   2011 	int			saved_seconds;
   2012 	int_fast32_t		li;
   2013 	time_t			lo;
   2014 	time_t			hi;
   2015 #ifdef NO_ERROR_IN_DST_GAP
   2016 	time_t			ilo;
   2017 #endif
   2018 	int_fast32_t		y;
   2019 	time_t			newt;
   2020 	time_t			t;
   2021 	struct tm		yourtm, mytm;
   2022 
   2023 	*okayp = false;
   2024 	yourtm = *tmp;
   2025 #ifdef NO_ERROR_IN_DST_GAP
   2026 again:
   2027 #endif
   2028 	if (do_norm_secs) {
   2029 		if (normalize_overflow(&yourtm.tm_min, &yourtm.tm_sec,
   2030 		    SECSPERMIN))
   2031 			goto out_of_range;
   2032 	}
   2033 	if (normalize_overflow(&yourtm.tm_hour, &yourtm.tm_min, MINSPERHOUR))
   2034 		goto out_of_range;
   2035 	if (normalize_overflow(&yourtm.tm_mday, &yourtm.tm_hour, HOURSPERDAY))
   2036 		goto out_of_range;
   2037 	y = yourtm.tm_year;
   2038 	if (normalize_overflow32(&y, &yourtm.tm_mon, MONSPERYEAR))
   2039 		goto out_of_range;
   2040 	/*
   2041 	** Turn y into an actual year number for now.
   2042 	** It is converted back to an offset from TM_YEAR_BASE later.
   2043 	*/
   2044 	if (increment_overflow32(&y, TM_YEAR_BASE))
   2045 		goto out_of_range;
   2046 	while (yourtm.tm_mday <= 0) {
   2047 		if (increment_overflow32(&y, -1))
   2048 			goto out_of_range;
   2049 		li = y + (1 < yourtm.tm_mon);
   2050 		yourtm.tm_mday += year_lengths[isleap(li)];
   2051 	}
   2052 	while (yourtm.tm_mday > DAYSPERLYEAR) {
   2053 		li = y + (1 < yourtm.tm_mon);
   2054 		yourtm.tm_mday -= year_lengths[isleap(li)];
   2055 		if (increment_overflow32(&y, 1))
   2056 			goto out_of_range;
   2057 	}
   2058 	for ( ; ; ) {
   2059 		i = mon_lengths[isleap(y)][yourtm.tm_mon];
   2060 		if (yourtm.tm_mday <= i)
   2061 			break;
   2062 		yourtm.tm_mday -= i;
   2063 		if (++yourtm.tm_mon >= MONSPERYEAR) {
   2064 			yourtm.tm_mon = 0;
   2065 			if (increment_overflow32(&y, 1))
   2066 				goto out_of_range;
   2067 		}
   2068 	}
   2069 	if (increment_overflow32(&y, -TM_YEAR_BASE))
   2070 		goto out_of_range;
   2071 	if (! (INT_MIN <= y && y <= INT_MAX))
   2072 		goto out_of_range;
   2073 	yourtm.tm_year = (int)y;
   2074 	if (yourtm.tm_sec >= 0 && yourtm.tm_sec < SECSPERMIN)
   2075 		saved_seconds = 0;
   2076 	else if (y + TM_YEAR_BASE < EPOCH_YEAR) {
   2077 		/*
   2078 		** We can't set tm_sec to 0, because that might push the
   2079 		** time below the minimum representable time.
   2080 		** Set tm_sec to 59 instead.
   2081 		** This assumes that the minimum representable time is
   2082 		** not in the same minute that a leap second was deleted from,
   2083 		** which is a safer assumption than using 58 would be.
   2084 		*/
   2085 		if (increment_overflow(&yourtm.tm_sec, 1 - SECSPERMIN))
   2086 			goto out_of_range;
   2087 		saved_seconds = yourtm.tm_sec;
   2088 		yourtm.tm_sec = SECSPERMIN - 1;
   2089 	} else {
   2090 		saved_seconds = yourtm.tm_sec;
   2091 		yourtm.tm_sec = 0;
   2092 	}
   2093 	/*
   2094 	** Do a binary search (this works whatever time_t's type is).
   2095 	*/
   2096 	lo = TIME_T_MIN;
   2097 	hi = TIME_T_MAX;
   2098 #ifdef NO_ERROR_IN_DST_GAP
   2099 	ilo = lo;
   2100 #endif
   2101 	for ( ; ; ) {
   2102 		t = lo / 2 + hi / 2;
   2103 		if (t < lo)
   2104 			t = lo;
   2105 		else if (t > hi)
   2106 			t = hi;
   2107 		if (! funcp(sp, &t, offset, &mytm)) {
   2108 			/*
   2109 			** Assume that t is too extreme to be represented in
   2110 			** a struct tm; arrange things so that it is less
   2111 			** extreme on the next pass.
   2112 			*/
   2113 			dir = (t > 0) ? 1 : -1;
   2114 		} else	dir = tmcomp(&mytm, &yourtm);
   2115 		if (dir != 0) {
   2116 			if (t == lo) {
   2117 				if (t == TIME_T_MAX)
   2118 					goto out_of_range;
   2119 				++t;
   2120 				++lo;
   2121 			} else if (t == hi) {
   2122 				if (t == TIME_T_MIN)
   2123 					goto out_of_range;
   2124 				--t;
   2125 				--hi;
   2126 			}
   2127 #ifdef NO_ERROR_IN_DST_GAP
   2128 			if (ilo != lo && lo - 1 == hi && yourtm.tm_isdst < 0 &&
   2129 			    do_norm_secs) {
   2130 				for (i = sp->typecnt - 1; i >= 0; --i) {
   2131 					for (j = sp->typecnt - 1; j >= 0; --j) {
   2132 						time_t off;
   2133 						if (sp->ttis[j].tt_isdst ==
   2134 						    sp->ttis[i].tt_isdst)
   2135 							continue;
   2136 						off = sp->ttis[j].tt_gmtoff -
   2137 						    sp->ttis[i].tt_gmtoff;
   2138 						yourtm.tm_sec += off < 0 ?
   2139 						    -off : off;
   2140 						goto again;
   2141 					}
   2142 				}
   2143 			}
   2144 #endif
   2145 			if (lo > hi)
   2146 				goto invalid;
   2147 			if (dir > 0)
   2148 				hi = t;
   2149 			else	lo = t;
   2150 			continue;
   2151 		}
   2152 #if defined TM_GMTOFF && ! UNINIT_TRAP
   2153 		if (mytm.TM_GMTOFF != yourtm.TM_GMTOFF
   2154 		    && (yourtm.TM_GMTOFF < 0
   2155 			? (-SECSPERDAY <= yourtm.TM_GMTOFF
   2156 			   && (mytm.TM_GMTOFF <=
   2157 			       (/*CONSTCOND*/SMALLEST (INT_FAST32_MAX, LONG_MAX)
   2158 				+ yourtm.TM_GMTOFF)))
   2159 			: (yourtm.TM_GMTOFF <= SECSPERDAY
   2160 			   && ((/*CONSTCOND*/BIGGEST (INT_FAST32_MIN, LONG_MIN)
   2161 				+ yourtm.TM_GMTOFF)
   2162 			       <= mytm.TM_GMTOFF)))) {
   2163 		  /* MYTM matches YOURTM except with the wrong UT offset.
   2164 		     YOURTM.TM_GMTOFF is plausible, so try it instead.
   2165 		     It's OK if YOURTM.TM_GMTOFF contains uninitialized data,
   2166 		     since the guess gets checked.  */
   2167 		  time_t altt = t;
   2168 		  int_fast32_t diff = (int_fast32_t)
   2169 		      (mytm.TM_GMTOFF - yourtm.TM_GMTOFF);
   2170 		  if (!increment_overflow_time(&altt, diff)) {
   2171 		    struct tm alttm;
   2172 		    if (! funcp(sp, &altt, offset, &alttm)
   2173 			&& alttm.tm_isdst == mytm.tm_isdst
   2174 			&& alttm.TM_GMTOFF == yourtm.TM_GMTOFF
   2175 			&& tmcomp(&alttm, &yourtm)) {
   2176 		      t = altt;
   2177 		      mytm = alttm;
   2178 		    }
   2179 		  }
   2180 		}
   2181 #endif
   2182 		if (yourtm.tm_isdst < 0 || mytm.tm_isdst == yourtm.tm_isdst)
   2183 			break;
   2184 		/*
   2185 		** Right time, wrong type.
   2186 		** Hunt for right time, right type.
   2187 		** It's okay to guess wrong since the guess
   2188 		** gets checked.
   2189 		*/
   2190 		if (sp == NULL)
   2191 			goto invalid;
   2192 		for (i = sp->typecnt - 1; i >= 0; --i) {
   2193 			if (sp->ttis[i].tt_isdst != yourtm.tm_isdst)
   2194 				continue;
   2195 			for (j = sp->typecnt - 1; j >= 0; --j) {
   2196 				if (sp->ttis[j].tt_isdst == yourtm.tm_isdst)
   2197 					continue;
   2198 				newt = (time_t)(t + sp->ttis[j].tt_gmtoff -
   2199 				    sp->ttis[i].tt_gmtoff);
   2200 				if (! funcp(sp, &newt, offset, &mytm))
   2201 					continue;
   2202 				if (tmcomp(&mytm, &yourtm) != 0)
   2203 					continue;
   2204 				if (mytm.tm_isdst != yourtm.tm_isdst)
   2205 					continue;
   2206 				/*
   2207 				** We have a match.
   2208 				*/
   2209 				t = newt;
   2210 				goto label;
   2211 			}
   2212 		}
   2213 		goto invalid;
   2214 	}
   2215 label:
   2216 	newt = t + saved_seconds;
   2217 	if ((newt < t) != (saved_seconds < 0))
   2218 		goto out_of_range;
   2219 	t = newt;
   2220 	if (funcp(sp, &t, offset, tmp)) {
   2221 		*okayp = true;
   2222 		return t;
   2223 	}
   2224 out_of_range:
   2225 	errno = EOVERFLOW;
   2226 	return WRONG;
   2227 invalid:
   2228 	errno = EINVAL;
   2229 	return WRONG;
   2230 }
   2231 
   2232 static time_t
   2233 time2(struct tm * const	tmp,
   2234       struct tm *(*funcp)(struct state const *, time_t const *,
   2235 			  int_fast32_t, struct tm *),
   2236       struct state const *sp,
   2237       const int_fast32_t offset,
   2238       bool *okayp)
   2239 {
   2240 	time_t	t;
   2241 
   2242 	/*
   2243 	** First try without normalization of seconds
   2244 	** (in case tm_sec contains a value associated with a leap second).
   2245 	** If that fails, try with normalization of seconds.
   2246 	*/
   2247 	t = time2sub(tmp, funcp, sp, offset, okayp, false);
   2248 	return *okayp ? t : time2sub(tmp, funcp, sp, offset, okayp, true);
   2249 }
   2250 
   2251 static time_t
   2252 time1(struct tm *const tmp,
   2253       struct tm *(*funcp) (struct state const *, time_t const *,
   2254 			   int_fast32_t, struct tm *),
   2255       struct state const *sp,
   2256       const int_fast32_t offset)
   2257 {
   2258 	time_t			t;
   2259 	int			samei, otheri;
   2260 	int			sameind, otherind;
   2261 	int			i;
   2262 	int			nseen;
   2263 	int			save_errno;
   2264 	char				seen[TZ_MAX_TYPES];
   2265 	unsigned char			types[TZ_MAX_TYPES];
   2266 	bool				okay;
   2267 
   2268 	if (tmp == NULL) {
   2269 		errno = EINVAL;
   2270 		return WRONG;
   2271 	}
   2272 	if (tmp->tm_isdst > 1)
   2273 		tmp->tm_isdst = 1;
   2274 	save_errno = errno;
   2275 	t = time2(tmp, funcp, sp, offset, &okay);
   2276 	if (okay) {
   2277 		errno = save_errno;
   2278 		return t;
   2279 	}
   2280 	if (tmp->tm_isdst < 0)
   2281 #ifdef PCTS
   2282 		/*
   2283 		** POSIX Conformance Test Suite code courtesy Grant Sullivan.
   2284 		*/
   2285 		tmp->tm_isdst = 0;	/* reset to std and try again */
   2286 #else
   2287 		return t;
   2288 #endif /* !defined PCTS */
   2289 	/*
   2290 	** We're supposed to assume that somebody took a time of one type
   2291 	** and did some math on it that yielded a "struct tm" that's bad.
   2292 	** We try to divine the type they started from and adjust to the
   2293 	** type they need.
   2294 	*/
   2295 	if (sp == NULL) {
   2296 		errno = EINVAL;
   2297 		return WRONG;
   2298 	}
   2299 	for (i = 0; i < sp->typecnt; ++i)
   2300 		seen[i] = false;
   2301 	nseen = 0;
   2302 	for (i = sp->timecnt - 1; i >= 0; --i)
   2303 		if (!seen[sp->types[i]]) {
   2304 			seen[sp->types[i]] = true;
   2305 			types[nseen++] = sp->types[i];
   2306 		}
   2307 	for (sameind = 0; sameind < nseen; ++sameind) {
   2308 		samei = types[sameind];
   2309 		if (sp->ttis[samei].tt_isdst != tmp->tm_isdst)
   2310 			continue;
   2311 		for (otherind = 0; otherind < nseen; ++otherind) {
   2312 			otheri = types[otherind];
   2313 			if (sp->ttis[otheri].tt_isdst == tmp->tm_isdst)
   2314 				continue;
   2315 			tmp->tm_sec += (int)(sp->ttis[otheri].tt_gmtoff -
   2316 					sp->ttis[samei].tt_gmtoff);
   2317 			tmp->tm_isdst = !tmp->tm_isdst;
   2318 			t = time2(tmp, funcp, sp, offset, &okay);
   2319 			if (okay) {
   2320 				errno = save_errno;
   2321 				return t;
   2322 			}
   2323 			tmp->tm_sec -= (int)(sp->ttis[otheri].tt_gmtoff -
   2324 					sp->ttis[samei].tt_gmtoff);
   2325 			tmp->tm_isdst = !tmp->tm_isdst;
   2326 		}
   2327 	}
   2328 	errno = EOVERFLOW;
   2329 	return WRONG;
   2330 }
   2331 
   2332 static time_t
   2333 mktime_tzname(timezone_t sp, struct tm *tmp, bool setname)
   2334 {
   2335 	if (sp)
   2336 		return time1(tmp, localsub, sp, setname);
   2337 	else {
   2338 		gmtcheck();
   2339 		return time1(tmp, gmtsub, gmtptr, 0);
   2340 	}
   2341 }
   2342 
   2343 #if NETBSD_INSPIRED
   2344 
   2345 time_t
   2346 mktime_z(timezone_t sp, struct tm *const tmp)
   2347 {
   2348 	return mktime_tzname(sp, tmp, false);
   2349 }
   2350 
   2351 #endif
   2352 
   2353 time_t
   2354 mktime(struct tm *tmp)
   2355 {
   2356 	time_t t;
   2357 
   2358 	rwlock_wrlock(&__lcl_lock);
   2359 	tzset_unlocked();
   2360 	t = mktime_tzname(__lclptr, tmp, true);
   2361 	rwlock_unlock(&__lcl_lock);
   2362 	return t;
   2363 }
   2364 
   2365 #ifdef STD_INSPIRED
   2366 
   2367 time_t
   2368 timelocal_z(const timezone_t sp, struct tm *const tmp)
   2369 {
   2370 	if (tmp != NULL)
   2371 		tmp->tm_isdst = -1;	/* in case it wasn't initialized */
   2372 	return mktime_z(sp, tmp);
   2373 }
   2374 
   2375 time_t
   2376 timelocal(struct tm *tmp)
   2377 {
   2378 	if (tmp != NULL)
   2379 		tmp->tm_isdst = -1;	/* in case it wasn't initialized */
   2380 	return mktime(tmp);
   2381 }
   2382 
   2383 time_t
   2384 timegm(struct tm *tmp)
   2385 {
   2386 
   2387 	return timeoff(tmp, 0);
   2388 }
   2389 
   2390 time_t
   2391 timeoff(struct tm *tmp, long offset)
   2392 {
   2393 	if (tmp)
   2394 		tmp->tm_isdst = 0;
   2395 	gmtcheck();
   2396 	return time1(tmp, gmtsub, gmtptr, (int_fast32_t)offset);
   2397 }
   2398 
   2399 #endif /* defined STD_INSPIRED */
   2400 
   2401 /*
   2402 ** XXX--is the below the right way to conditionalize??
   2403 */
   2404 
   2405 #ifdef STD_INSPIRED
   2406 
   2407 /*
   2408 ** IEEE Std 1003.1 (POSIX) says that 536457599
   2409 ** shall correspond to "Wed Dec 31 23:59:59 UTC 1986", which
   2410 ** is not the case if we are accounting for leap seconds.
   2411 ** So, we provide the following conversion routines for use
   2412 ** when exchanging timestamps with POSIX conforming systems.
   2413 */
   2414 
   2415 static int_fast64_t
   2416 leapcorr(const timezone_t sp, time_t t)
   2417 {
   2418 	struct lsinfo const * lp;
   2419 	int		i;
   2420 
   2421 	i = sp->leapcnt;
   2422 	while (--i >= 0) {
   2423 		lp = &sp->lsis[i];
   2424 		if (t >= lp->ls_trans)
   2425 			return lp->ls_corr;
   2426 	}
   2427 	return 0;
   2428 }
   2429 
   2430 NETBSD_INSPIRED_EXTERN time_t
   2431 time2posix_z(timezone_t sp, time_t t)
   2432 {
   2433 	return (time_t)(t - leapcorr(sp, t));
   2434 }
   2435 
   2436 time_t
   2437 time2posix(time_t t)
   2438 {
   2439 	rwlock_wrlock(&__lcl_lock);
   2440 	if (!lcl_is_set)
   2441 		tzset_unlocked();
   2442 	if (__lclptr)
   2443 		t = (time_t)(t - leapcorr(__lclptr, t));
   2444 	rwlock_unlock(&__lcl_lock);
   2445 	return t;
   2446 }
   2447 
   2448 NETBSD_INSPIRED_EXTERN time_t
   2449 posix2time_z(timezone_t sp, time_t t)
   2450 {
   2451 	time_t	x;
   2452 	time_t	y;
   2453 
   2454 	/*
   2455 	** For a positive leap second hit, the result
   2456 	** is not unique. For a negative leap second
   2457 	** hit, the corresponding time doesn't exist,
   2458 	** so we return an adjacent second.
   2459 	*/
   2460 	x = (time_t)(t + leapcorr(sp, t));
   2461 	y = (time_t)(x - leapcorr(sp, x));
   2462 	if (y < t) {
   2463 		do {
   2464 			x++;
   2465 			y = (time_t)(x - leapcorr(sp, x));
   2466 		} while (y < t);
   2467 		x -= y != t;
   2468 	} else if (y > t) {
   2469 		do {
   2470 			--x;
   2471 			y = (time_t)(x - leapcorr(sp, x));
   2472 		} while (y > t);
   2473 		x += y != t;
   2474 	}
   2475 	return x;
   2476 }
   2477 
   2478 time_t
   2479 posix2time(time_t t)
   2480 {
   2481 	rwlock_wrlock(&__lcl_lock);
   2482 	if (!lcl_is_set)
   2483 		tzset_unlocked();
   2484 	if (__lclptr)
   2485 		t = posix2time_z(__lclptr, t);
   2486 	rwlock_unlock(&__lcl_lock);
   2487 	return t;
   2488 }
   2489 
   2490 #endif /* defined STD_INSPIRED */
   2491