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