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