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