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