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