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