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