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