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