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