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