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