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