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