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