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