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