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