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