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