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