Home | History | Annotate | Line # | Download | only in time
localtime.c revision 1.132
      1 /*	$NetBSD: localtime.c,v 1.132 2022/03/25 19:25:23 rillig Exp $	*/
      2 
      3 /* Convert timestamp from time_t to struct tm.  */
      4 
      5 /*
      6 ** This file is in the public domain, so clarified as of
      7 ** 1996-06-05 by Arthur David Olson.
      8 */
      9 
     10 #include <sys/cdefs.h>
     11 #if defined(LIBC_SCCS) && !defined(lint)
     12 #if 0
     13 static char	elsieid[] = "@(#)localtime.c	8.17";
     14 #else
     15 __RCSID("$NetBSD: localtime.c,v 1.132 2022/03/25 19:25:23 rillig Exp $");
     16 #endif
     17 #endif /* LIBC_SCCS and not lint */
     18 
     19 /*
     20 ** Leap second handling from Bradley White.
     21 ** POSIX-style TZ environment variable handling from Guy Harris.
     22 */
     23 
     24 /*LINTLIBRARY*/
     25 
     26 #include "namespace.h"
     27 #include <assert.h>
     28 #define LOCALTIME_IMPLEMENTATION
     29 #include "private.h"
     30 
     31 #include "tzfile.h"
     32 #include <fcntl.h>
     33 
     34 #if defined(__weak_alias)
     35 __weak_alias(daylight,_daylight)
     36 __weak_alias(tzname,_tzname)
     37 #endif
     38 
     39 #ifndef TZ_ABBR_MAX_LEN
     40 #define TZ_ABBR_MAX_LEN	16
     41 #endif /* !defined TZ_ABBR_MAX_LEN */
     42 
     43 #ifndef TZ_ABBR_CHAR_SET
     44 #define TZ_ABBR_CHAR_SET \
     45 	"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789 :+-._"
     46 #endif /* !defined TZ_ABBR_CHAR_SET */
     47 
     48 #ifndef TZ_ABBR_ERR_CHAR
     49 #define TZ_ABBR_ERR_CHAR	'_'
     50 #endif /* !defined TZ_ABBR_ERR_CHAR */
     51 
     52 /*
     53 ** SunOS 4.1.1 headers lack O_BINARY.
     54 */
     55 
     56 #ifdef O_BINARY
     57 #define OPEN_MODE	(O_RDONLY | O_BINARY | O_CLOEXEC)
     58 #endif /* defined O_BINARY */
     59 #ifndef O_BINARY
     60 #define OPEN_MODE	(O_RDONLY | O_CLOEXEC)
     61 #endif /* !defined O_BINARY */
     62 
     63 #ifndef WILDABBR
     64 /*
     65 ** Someone might make incorrect use of a time zone abbreviation:
     66 **	1.	They might reference tzname[0] before calling tzset (explicitly
     67 **		or implicitly).
     68 **	2.	They might reference tzname[1] before calling tzset (explicitly
     69 **		or implicitly).
     70 **	3.	They might reference tzname[1] after setting to a time zone
     71 **		in which Daylight Saving Time is never observed.
     72 **	4.	They might reference tzname[0] after setting to a time zone
     73 **		in which Standard Time is never observed.
     74 **	5.	They might reference tm.TM_ZONE after calling offtime.
     75 ** What's best to do in the above cases is open to debate;
     76 ** for now, we just set things up so that in any of the five cases
     77 ** WILDABBR is used. Another possibility: initialize tzname[0] to the
     78 ** string "tzname[0] used before set", and similarly for the other cases.
     79 ** And another: initialize tzname[0] to "ERA", with an explanation in the
     80 ** manual page of what this "time zone abbreviation" means (doing this so
     81 ** that tzname[0] has the "normal" length of three characters).
     82 */
     83 #define WILDABBR	"   "
     84 #endif /* !defined WILDABBR */
     85 
     86 static const char	wildabbr[] = WILDABBR;
     87 
     88 static const char	gmt[] = "GMT";
     89 
     90 /*
     91 ** The DST rules to use if TZ has no rules and we can't load TZDEFRULES.
     92 ** Default to US rules as of 2017-05-07.
     93 ** POSIX does not specify the default DST rules;
     94 ** for historical reasons, US rules are a common default.
     95 */
     96 #ifndef TZDEFRULESTRING
     97 #define TZDEFRULESTRING ",M3.2.0,M11.1.0"
     98 #endif
     99 
    100 typedef int_fast64_t __time_t;
    101 
    102 struct ttinfo {				/* time type information */
    103 	int_fast32_t	tt_utoff;	/* UT offset in seconds */
    104 	bool		tt_isdst;	/* used to set tm_isdst */
    105 	int		tt_desigidx;	/* abbreviation list index */
    106 	bool		tt_ttisstd;	/* transition is std time */
    107 	bool		tt_ttisut;	/* transition is UT */
    108 };
    109 
    110 struct lsinfo {				/* leap second information */
    111 	__time_t	ls_trans;	/* transition time */
    112 	int_fast32_t	ls_corr;	/* correction to apply */
    113 };
    114 
    115 #define SMALLEST(a, b)	(((a) < (b)) ? (a) : (b))
    116 #define BIGGEST(a, b)	(((a) > (b)) ? (a) : (b))
    117 
    118 /* This abbreviation means local time is unspecified.  */
    119 static char const UNSPEC[] = "-00";
    120 
    121 /* How many extra bytes are needed at the end of struct state's chars array.
    122    This needs to be at least 1 for null termination in case the input
    123    data isn't properly terminated, and it also needs to be big enough
    124    for ttunspecified to work without crashing.  */
    125 enum { CHARS_EXTRA = BIGGEST(sizeof UNSPEC, 2) - 1 };
    126 
    127 #ifdef TZNAME_MAX
    128 #define MY_TZNAME_MAX	TZNAME_MAX
    129 #endif /* defined TZNAME_MAX */
    130 #ifndef TZNAME_MAX
    131 #define MY_TZNAME_MAX	255
    132 #endif /* !defined TZNAME_MAX */
    133 
    134 #define state __state
    135 struct state {
    136 	int		leapcnt;
    137 	int		timecnt;
    138 	int		typecnt;
    139 	int		charcnt;
    140 	bool		goback;
    141 	bool		goahead;
    142 	__time_t	ats[TZ_MAX_TIMES];
    143 	unsigned char	types[TZ_MAX_TIMES];
    144 	struct ttinfo	ttis[TZ_MAX_TYPES];
    145 	char		chars[/*CONSTCOND*/
    146 			    BIGGEST(BIGGEST(TZ_MAX_CHARS + CHARS_EXTRA,
    147 			    sizeof gmt), (2 * (MY_TZNAME_MAX + 1)))];
    148 	struct lsinfo	lsis[TZ_MAX_LEAPS];
    149 
    150 	/* The time type to use for early times or if no transitions.
    151 	   It is always zero for recent tzdb releases.
    152 	   It might be nonzero for data from tzdb 2018e or earlier.  */
    153 	int defaulttype;
    154 };
    155 
    156 enum r_type {
    157   JULIAN_DAY,		/* Jn = Julian day */
    158   DAY_OF_YEAR,		/* n = day of year */
    159   MONTH_NTH_DAY_OF_WEEK	/* Mm.n.d = month, week, day of week */
    160 };
    161 
    162 struct rule {
    163 	enum r_type	r_type;		/* type of rule */
    164 	int		r_day;		/* day number of rule */
    165 	int		r_week;		/* week number of rule */
    166 	int		r_mon;		/* month number of rule */
    167 	int_fast32_t	r_time;		/* transition time of rule */
    168 };
    169 
    170 static struct tm *gmtsub(struct state const *, time_t const *, int_fast32_t,
    171 			 struct tm *);
    172 static bool increment_overflow(int *, int);
    173 static bool increment_overflow_time(__time_t *, int_fast32_t);
    174 static int_fast32_t leapcorr(struct state const *, time_t);
    175 static bool normalize_overflow32(int_fast32_t *, int *, int);
    176 static struct tm *timesub(time_t const *, int_fast32_t, struct state const *,
    177 			  struct tm *);
    178 static bool typesequiv(struct state const *, int, int);
    179 static bool tzparse(char const *, struct state *, struct state *);
    180 
    181 static timezone_t gmtptr;
    182 
    183 #ifndef TZ_STRLEN_MAX
    184 #define TZ_STRLEN_MAX 255
    185 #endif /* !defined TZ_STRLEN_MAX */
    186 
    187 static char		lcl_TZname[TZ_STRLEN_MAX + 1];
    188 static int		lcl_is_set;
    189 
    190 
    191 #if !defined(__LIBC12_SOURCE__)
    192 timezone_t __lclptr;
    193 #ifdef _REENTRANT
    194 rwlock_t __lcl_lock = RWLOCK_INITIALIZER;
    195 #endif
    196 #endif
    197 
    198 /*
    199 ** Section 4.12.3 of X3.159-1989 requires that
    200 **	Except for the strftime function, these functions [asctime,
    201 **	ctime, gmtime, localtime] return values in one of two static
    202 **	objects: a broken-down time structure and an array of char.
    203 ** Thanks to Paul Eggert for noting this.
    204 */
    205 
    206 static struct tm	tm;
    207 
    208 #if 2 <= HAVE_TZNAME + TZ_TIME_T || defined(__NetBSD__)
    209 # if !defined(__LIBC12_SOURCE__)
    210 
    211 __aconst char *		tzname[2] = {
    212 	(__aconst char *)__UNCONST(wildabbr),
    213 	(__aconst char *)__UNCONST(wildabbr)
    214 };
    215 
    216 # else
    217 
    218 extern __aconst char *	tzname[2];
    219 
    220 # endif /* __LIBC12_SOURCE__ */
    221 #endif
    222 
    223 #if 2 <= USG_COMPAT + TZ_TIME_T || defined(__NetBSD__)
    224 # if !defined(__LIBC12_SOURCE__)
    225 long 			timezone = 0;
    226 int			daylight = 0;
    227 # else
    228 extern int		daylight;
    229 extern long		timezone __RENAME(__timezone13);
    230 # endif /* __LIBC12_SOURCE__ */
    231 #endif /* 2<= USG_COMPAT + TZ_TIME_T */
    232 
    233 #if 2 <= ALTZONE + TZ_TIME_T
    234 long			altzone = 0;
    235 #endif /* 2 <= ALTZONE + TZ_TIME_T */
    236 
    237 /* Initialize *S to a value based on UTOFF, ISDST, and DESIGIDX.  */
    238 static void
    239 init_ttinfo(struct ttinfo *s, int_fast32_t utoff, bool isdst, int desigidx)
    240 {
    241   s->tt_utoff = utoff;
    242   s->tt_isdst = isdst;
    243   s->tt_desigidx = desigidx;
    244   s->tt_ttisstd = false;
    245   s->tt_ttisut = false;
    246 }
    247 
    248 /* Return true if SP's time type I does not specify local time.  */
    249 static bool
    250 ttunspecified(struct state const *sp, int i)
    251 {
    252   char const *abbr = &sp->chars[sp->ttis[i].tt_desigidx];
    253   /* memcmp is likely faster than strcmp, and is safe due to CHARS_EXTRA.  */
    254   return memcmp(abbr, UNSPEC, sizeof UNSPEC) == 0;
    255 }
    256 
    257 static int_fast32_t
    258 detzcode(const char *const codep)
    259 {
    260 	register int_fast32_t	result;
    261 	register int		i;
    262 	int_fast32_t one = 1;
    263 	int_fast32_t halfmaxval = one << (32 - 2);
    264 	int_fast32_t maxval = halfmaxval - 1 + halfmaxval;
    265 	int_fast32_t minval = -1 - maxval;
    266 
    267 	result = codep[0] & 0x7f;
    268 	for (i = 1; i < 4; ++i)
    269 		result = (result << 8) | (codep[i] & 0xff);
    270 
    271 	if (codep[0] & 0x80) {
    272 	  /* Do two's-complement negation even on non-two's-complement machines.
    273 	     If the result would be minval - 1, return minval.  */
    274 	  result -= !TWOS_COMPLEMENT(int_fast32_t) && result != 0;
    275 	  result += minval;
    276 	}
    277 	return result;
    278 }
    279 
    280 static int_fast64_t
    281 detzcode64(const char *const codep)
    282 {
    283 	register int_fast64_t result;
    284 	register int	i;
    285 	int_fast64_t one = 1;
    286 	int_fast64_t halfmaxval = one << (64 - 2);
    287 	int_fast64_t maxval = halfmaxval - 1 + halfmaxval;
    288 	int_fast64_t minval = -TWOS_COMPLEMENT(int_fast64_t) - maxval;
    289 
    290 	result = codep[0] & 0x7f;
    291 	for (i = 1; i < 8; ++i)
    292 		result = (result << 8) | (codep[i] & 0xff);
    293 
    294 	if (codep[0] & 0x80) {
    295 	  /* Do two's-complement negation even on non-two's-complement machines.
    296 	     If the result would be minval - 1, return minval.  */
    297 	  result -= !TWOS_COMPLEMENT(int_fast64_t) && result != 0;
    298 	  result += minval;
    299 	}
    300 	return result;
    301 }
    302 
    303 #include <stdio.h>
    304 
    305 const char *
    306 tzgetname(const timezone_t sp, int isdst)
    307 {
    308 	int i;
    309 	const char *name = NULL;
    310 	for (i = 0; i < sp->typecnt; ++i) {
    311 		const struct ttinfo *const ttisp = &sp->ttis[i];
    312 		if (ttisp->tt_isdst == isdst)
    313 			name = &sp->chars[ttisp->tt_desigidx];
    314 	}
    315 	if (name != NULL)
    316 		return name;
    317 	errno = ESRCH;
    318 	return NULL;
    319 }
    320 
    321 long
    322 tzgetgmtoff(const timezone_t sp, int isdst)
    323 {
    324 	int i;
    325 	long l = -1;
    326 	for (i = 0; i < sp->typecnt; ++i) {
    327 		const struct ttinfo *const ttisp = &sp->ttis[i];
    328 
    329 		if (ttisp->tt_isdst == isdst) {
    330 			l = ttisp->tt_utoff;
    331 		}
    332 	}
    333 	if (l == -1)
    334 		errno = ESRCH;
    335 	return l;
    336 }
    337 
    338 static void
    339 update_tzname_etc(struct state const *sp, struct ttinfo const *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
    352 }
    353 
    354 static void
    355 settzname(void)
    356 {
    357 	register timezone_t const	sp = __lclptr;
    358 	register int			i;
    359 
    360 #if HAVE_TZNAME
    361 	tzname[0] = tzname[1] =
    362 	    (__aconst char *) __UNCONST(sp ? wildabbr : gmt);
    363 #endif
    364 #if USG_COMPAT
    365 	daylight = 0;
    366 	timezone = 0;
    367 #endif
    368 #if ALTZONE
    369 	altzone = 0;
    370 #endif
    371 	if (sp == NULL) {
    372 		return;
    373 	}
    374 	/*
    375 	** And to get the latest time zone abbreviations into tzname. . .
    376 	*/
    377 	for (i = 0; i < sp->typecnt; ++i)
    378 		update_tzname_etc(sp, &sp->ttis[i]);
    379 
    380 	for (i = 0; i < sp->timecnt; ++i) {
    381 		register const struct ttinfo * const	ttisp =
    382 							&sp->ttis[
    383 								sp->types[i]];
    384 		update_tzname_etc(sp, ttisp);
    385 #if USG_COMPAT
    386 		if (ttisp->tt_isdst)
    387 			daylight = 1;
    388 #endif
    389 	}
    390 }
    391 
    392 static void
    393 scrub_abbrs(struct state *sp)
    394 {
    395 	int i;
    396 	/*
    397 	** First, replace bogus characters.
    398 	*/
    399 	for (i = 0; i < sp->charcnt; ++i)
    400 		if (strchr(TZ_ABBR_CHAR_SET, sp->chars[i]) == NULL)
    401 			sp->chars[i] = TZ_ABBR_ERR_CHAR;
    402 	/*
    403 	** Second, truncate long abbreviations.
    404 	*/
    405 	for (i = 0; i < sp->typecnt; ++i) {
    406 		register const struct ttinfo * const	ttisp = &sp->ttis[i];
    407 		char *cp = &sp->chars[ttisp->tt_desigidx];
    408 
    409 		if (strlen(cp) > TZ_ABBR_MAX_LEN &&
    410 			strcmp(cp, GRANDPARENTED) != 0)
    411 				*(cp + TZ_ABBR_MAX_LEN) = '\0';
    412 	}
    413 }
    414 
    415 /* Input buffer for data read from a compiled tz file.  */
    416 union input_buffer {
    417   /* The first part of the buffer, interpreted as a header.  */
    418   struct tzhead tzhead;
    419 
    420   /* The entire buffer.  */
    421   char buf[2 * sizeof(struct tzhead) + 2 * sizeof(struct state)
    422 	   + 4 * TZ_MAX_TIMES];
    423 };
    424 
    425 /* TZDIR with a trailing '/' rather than a trailing '\0'.  */
    426 static char const tzdirslash[sizeof TZDIR] = TZDIR "/";
    427 
    428 /* Local storage needed for 'tzloadbody'.  */
    429 union local_storage {
    430   /* The results of analyzing the file's contents after it is opened.  */
    431   struct file_analysis {
    432     /* The input buffer.  */
    433     union input_buffer u;
    434 
    435     /* A temporary state used for parsing a TZ string in the file.  */
    436     struct state st;
    437   } u;
    438 
    439   /* The file name to be opened.  */
    440   char fullname[/*CONSTCOND*/BIGGEST(sizeof(struct file_analysis),
    441 			sizeof tzdirslash + 1024)];
    442 };
    443 
    444 /* Load tz data from the file named NAME into *SP.  Read extended
    445    format if DOEXTEND.  Use *LSP for temporary storage.  Return 0 on
    446    success, an errno value on failure.  */
    447 static int
    448 tzloadbody(char const *name, struct state *sp, bool doextend,
    449 	   union local_storage *lsp)
    450 {
    451 	register int			i;
    452 	register int			fid;
    453 	register int			stored;
    454 	register ssize_t		nread;
    455 	register bool doaccess;
    456 	register union input_buffer *up = &lsp->u.u;
    457 	register size_t tzheadsize = sizeof(struct tzhead);
    458 
    459 	sp->goback = sp->goahead = false;
    460 
    461 	if (! name) {
    462 		name = TZDEFAULT;
    463 		if (! name)
    464 		  return EINVAL;
    465 	}
    466 
    467 	if (name[0] == ':')
    468 		++name;
    469 #ifdef SUPPRESS_TZDIR
    470 	/* Do not prepend TZDIR.  This is intended for specialized
    471 	   applications only, due to its security implications.  */
    472 	doaccess = true;
    473 #else
    474 	doaccess = name[0] == '/';
    475 #endif
    476 	if (!doaccess) {
    477 		char const *dot;
    478 		size_t namelen = strlen(name);
    479 		if (sizeof lsp->fullname - sizeof tzdirslash <= namelen)
    480 		  return ENAMETOOLONG;
    481 
    482 		/* Create a string "TZDIR/NAME".  Using sprintf here
    483 		   would pull in stdio (and would fail if the
    484 		   resulting string length exceeded INT_MAX!).  */
    485 		memcpy(lsp->fullname, tzdirslash, sizeof tzdirslash);
    486 		strcpy(lsp->fullname + sizeof tzdirslash, name);
    487 
    488 		/* Set doaccess if NAME contains a ".." file name
    489 		   component, as such a name could read a file outside
    490 		   the TZDIR virtual subtree.  */
    491 		for (dot = name; (dot = strchr(dot, '.')); dot++)
    492 		  if ((dot == name || dot[-1] == '/') && dot[1] == '.'
    493 		      && (dot[2] == '/' || !dot[2])) {
    494 		    doaccess = true;
    495 		    break;
    496 		  }
    497 
    498 		name = lsp->fullname;
    499 	}
    500 	if (doaccess && access(name, R_OK) != 0)
    501 	  return errno;
    502 	fid = open(name, OPEN_MODE);
    503 	if (fid < 0)
    504 	  return errno;
    505 
    506 	nread = read(fid, up->buf, sizeof up->buf);
    507 	if (nread < (ssize_t)tzheadsize) {
    508 	  int err = nread < 0 ? errno : EINVAL;
    509 	  close(fid);
    510 	  return err;
    511 	}
    512 	if (close(fid) < 0)
    513 	  return errno;
    514 	for (stored = 4; stored <= 8; stored *= 2) {
    515 	    char version = up->tzhead.tzh_version[0];
    516 	    bool skip_datablock = stored == 4 && version;
    517 	    int_fast32_t datablock_size;
    518 	    int_fast32_t ttisstdcnt = detzcode(up->tzhead.tzh_ttisstdcnt);
    519 	    int_fast32_t ttisutcnt = detzcode(up->tzhead.tzh_ttisutcnt);
    520 	    int_fast64_t prevtr = -1;
    521 	    int_fast32_t prevcorr = 0;
    522 	    int_fast32_t leapcnt = detzcode(up->tzhead.tzh_leapcnt);
    523 	    int_fast32_t timecnt = detzcode(up->tzhead.tzh_timecnt);
    524 	    int_fast32_t typecnt = detzcode(up->tzhead.tzh_typecnt);
    525 	    int_fast32_t charcnt = detzcode(up->tzhead.tzh_charcnt);
    526 	    char const *p = up->buf + tzheadsize;
    527 	    /* Although tzfile(5) currently requires typecnt to be nonzero,
    528 	       support future formats that may allow zero typecnt
    529 	       in files that have a TZ string and no transitions.  */
    530 	    if (! (0 <= leapcnt && leapcnt < TZ_MAX_LEAPS
    531 		   && 0 <= typecnt && typecnt < TZ_MAX_TYPES
    532 		   && 0 <= timecnt && timecnt < TZ_MAX_TIMES
    533 		   && 0 <= charcnt && charcnt < TZ_MAX_CHARS
    534 		   && 0 <= ttisstdcnt && ttisstdcnt < TZ_MAX_TYPES
    535 		   && 0 <= ttisutcnt && ttisutcnt < TZ_MAX_TYPES))
    536 	      return EINVAL;
    537 	    datablock_size
    538 		    = (timecnt * stored		/* ats */
    539 		       + timecnt		/* types */
    540 		       + typecnt * 6		/* ttinfos */
    541 		       + charcnt		/* chars */
    542 		       + leapcnt * (stored + 4)	/* lsinfos */
    543 		       + ttisstdcnt		/* ttisstds */
    544 		       + ttisutcnt);		/* ttisuts */
    545 	    if (nread < (ssize_t)(tzheadsize + datablock_size))
    546 	      return EINVAL;
    547 	    if (skip_datablock)
    548 		p += datablock_size;
    549 	    else {
    550 		if (! ((ttisstdcnt == typecnt || ttisstdcnt == 0)
    551 		       && (ttisutcnt == typecnt || ttisutcnt == 0)))
    552 		  return EINVAL;
    553 
    554 		sp->leapcnt = leapcnt;
    555 		sp->timecnt = timecnt;
    556 		sp->typecnt = typecnt;
    557 		sp->charcnt = charcnt;
    558 
    559 		/* Read transitions, discarding those out of time_t range.
    560 		   But pretend the last transition before TIME_T_MIN
    561 		   occurred at TIME_T_MIN.  */
    562 		timecnt = 0;
    563 		for (i = 0; i < sp->timecnt; ++i) {
    564 			int_fast64_t at
    565 			  = stored == 4 ? detzcode(p) : detzcode64(p);
    566 			sp->types[i] = at <= TIME_T_MAX;
    567 			if (sp->types[i]) {
    568 			  time_t attime
    569 			    = ((TYPE_SIGNED(time_t) ? at < TIME_T_MIN : at < 0)
    570 			       ? TIME_T_MIN : (time_t)at);
    571 			  if (timecnt && attime <= sp->ats[timecnt - 1]) {
    572 			    if (attime < sp->ats[timecnt - 1])
    573 			      return EINVAL;
    574 			    sp->types[i - 1] = 0;
    575 			    timecnt--;
    576 			  }
    577 			  sp->ats[timecnt++] = attime;
    578 			}
    579 			p += stored;
    580 		}
    581 
    582 		timecnt = 0;
    583 		for (i = 0; i < sp->timecnt; ++i) {
    584 			unsigned char typ = *p++;
    585 			if (sp->typecnt <= typ)
    586 			  return EINVAL;
    587 			if (sp->types[i])
    588 				sp->types[timecnt++] = typ;
    589 		}
    590 		sp->timecnt = timecnt;
    591 		for (i = 0; i < sp->typecnt; ++i) {
    592 			register struct ttinfo *	ttisp;
    593 			unsigned char isdst, desigidx;
    594 
    595 			ttisp = &sp->ttis[i];
    596 			ttisp->tt_utoff = detzcode(p);
    597 			p += 4;
    598 			isdst = *p++;
    599 			if (! (isdst < 2))
    600 			  return EINVAL;
    601 			ttisp->tt_isdst = isdst;
    602 			desigidx = *p++;
    603 			if (! (desigidx < sp->charcnt))
    604 			  return EINVAL;
    605 			ttisp->tt_desigidx = desigidx;
    606 		}
    607 		for (i = 0; i < sp->charcnt; ++i)
    608 			sp->chars[i] = *p++;
    609 		/* Ensure '\0'-terminated, and make it safe to call
    610 		   ttunspecified later.  */
    611 		memset(&sp->chars[i], 0, CHARS_EXTRA);
    612 
    613 		/* Read leap seconds, discarding those out of time_t range.  */
    614 		leapcnt = 0;
    615 		for (i = 0; i < sp->leapcnt; ++i) {
    616 		  int_fast64_t tr = stored == 4 ? detzcode(p) : 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 			register 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 			register 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 	register 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 		register const struct ttinfo *	ap = &sp->ttis[a];
    852 		register 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(register const char *strp)
    888 {
    889 	register 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(register const char *strp, const int delim)
    909 {
    910 	register 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(register const char *strp, int *const nump, const int min, const int max)
    926 {
    927 	register char	c;
    928 	register 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(register 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(register const char *strp, int_fast32_t *const offsetp)
   1002 {
   1003 	register 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, register 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, register const struct rule *const rulep,
   1078 	  const int_fast32_t offset)
   1079 {
   1080 	register bool	leapyear;
   1081 	register int_fast32_t value;
   1082 	register 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 	register char *			cp;
   1179 	register 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 			register int	year;
   1246 			register 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 			while (true) {
   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 			register int_fast32_t	theirstdoffset;
   1350 			register int_fast32_t	theirdstoffset;
   1351 			register int_fast32_t	theiroffset;
   1352 			register bool		isdst;
   1353 			register int		i;
   1354 			register 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] != ':' && 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
   1491       ? 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(char const *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 	register const struct ttinfo *	ttisp;
   1604 	register int			i;
   1605 	register 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 			register time_t		seconds;
   1616 			register 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 				register 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 		register int	lo = 1;
   1659 		register int	hi = sp->timecnt;
   1660 
   1661 		while (lo < hi) {
   1662 			register 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, time_t const *timep, int_fast32_t offset,
   1728        struct tm *tmp)
   1729 {
   1730 	register 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 * 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 
   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(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 	register const struct lsinfo *	lp;
   1844 	register time_t			tdays;
   1845 	register const int *		ip;
   1846 	register int_fast32_t		corr;
   1847 	register 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 		register 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 	register 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 	register 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 	register 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 	register 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(register const struct tm *const atmp,
   2066        register const struct tm *const btmp)
   2067 {
   2068 	register 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 	register int			dir;
   2090 	register int			i, j;
   2091 	register int			saved_seconds;
   2092 	register int_fast32_t		li;
   2093 	register time_t			lo;
   2094 	register 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 	register time_t			t;
   2342 	register int			samei, otheri;
   2343 	register int			sameind, otherind;
   2344 	register int			i;
   2345 	register 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   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 	register struct lsinfo const *	lp;
   2487 	register 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 ** IEEE Std 1003.1 (POSIX) says that 536457599
   2508 ** shall correspond to "Wed Dec 31 23:59:59 UTC 1986", which
   2509 ** is not the case if we are accounting for leap seconds.
   2510 ** So, we provide the following conversion routines for use
   2511 ** when exchanging timestamps with POSIX conforming systems.
   2512 */
   2513 
   2514 NETBSD_INSPIRED_EXTERN time_t
   2515 time2posix_z(timezone_t sp, time_t t)
   2516 {
   2517   return (time_t)(t - leapcorr(sp, t));
   2518 }
   2519 
   2520 time_t
   2521 time2posix(time_t t)
   2522 {
   2523   rwlock_wrlock(&__lcl_lock);
   2524   if (!lcl_is_set)
   2525     tzset_unlocked();
   2526   if (__lclptr)
   2527     t = (time_t)(t - leapcorr(__lclptr, t));
   2528   rwlock_unlock(&__lcl_lock);
   2529   return t;
   2530 }
   2531 
   2532 /*
   2533 ** XXX--is the below the right way to conditionalize??
   2534 */
   2535 
   2536 #ifdef STD_INSPIRED
   2537 
   2538 NETBSD_INSPIRED_EXTERN time_t
   2539 posix2time_z(timezone_t sp, time_t t)
   2540 {
   2541 	time_t	x;
   2542 	time_t	y;
   2543 	/*
   2544 	** For a positive leap second hit, the result
   2545 	** is not unique. For a negative leap second
   2546 	** hit, the corresponding time doesn't exist,
   2547 	** so we return an adjacent second.
   2548 	*/
   2549 	x = (time_t)(t + leapcorr(sp, t));
   2550 	y = (time_t)(x - leapcorr(sp, x));
   2551 	if (y < t) {
   2552 		do {
   2553 			x++;
   2554 			y = (time_t)(x - leapcorr(sp, x));
   2555 		} while (y < t);
   2556 		x -= y != t;
   2557 	} else if (y > t) {
   2558 		do {
   2559 			--x;
   2560 			y = (time_t)(x - leapcorr(sp, x));
   2561 		} while (y > t);
   2562 		x += y != t;
   2563 	}
   2564 	return x;
   2565 }
   2566 
   2567 time_t
   2568 posix2time(time_t t)
   2569 {
   2570   rwlock_wrlock(&__lcl_lock);
   2571   if (!lcl_is_set)
   2572     tzset_unlocked();
   2573   if (__lclptr)
   2574     t = posix2time_z(__lclptr, t);
   2575   rwlock_unlock(&__lcl_lock);
   2576   return t;
   2577 }
   2578 
   2579 #endif /* defined STD_INSPIRED */
   2580