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