1/*	$NetBSD: localtime.c,v 1.143 2024/03/11 23:03:35 christos Exp $	*/
2
3/* Convert timestamp from time_t to struct tm.  */
4
5/*
6** This file is in the public domain, so clarified as of
7** 1996-06-05 by Arthur David Olson.
8*/
9
10#include <sys/cdefs.h>
11#if defined(LIBC_SCCS) && !defined(lint)
12#if 0
13static char	elsieid[] = "@(#)localtime.c	8.17";
14#else
15__RCSID("$NetBSD: localtime.c,v 1.143 2024/03/11 23:03:35 christos Exp $");
16#endif
17#endif /* LIBC_SCCS and not lint */
18
19/*
20** Leap second handling from Bradley White.
21** POSIX.1-1988 style TZ environment variable handling from Guy Harris.
22*/
23
24/*LINTLIBRARY*/
25
26#include "namespace.h"
27#include <assert.h>
28#define LOCALTIME_IMPLEMENTATION
29#include "private.h"
30
31#include "tzfile.h"
32#include <fcntl.h>
33
34#if defined(__weak_alias)
35__weak_alias(daylight,_daylight)
36__weak_alias(tzname,_tzname)
37#endif
38
39#ifndef TZ_ABBR_CHAR_SET
40# define TZ_ABBR_CHAR_SET \
41	"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789 :+-._"
42#endif /* !defined TZ_ABBR_CHAR_SET */
43
44#ifndef TZ_ABBR_ERR_CHAR
45# define TZ_ABBR_ERR_CHAR '_'
46#endif /* !defined TZ_ABBR_ERR_CHAR */
47
48/*
49** Support non-POSIX platforms that distinguish between text and binary files.
50*/
51
52#ifndef O_BINARY
53# define O_BINARY 0
54#endif
55
56#ifndef WILDABBR
57/*
58** Someone might make incorrect use of a time zone abbreviation:
59**	1.	They might reference tzname[0] before calling tzset (explicitly
60**		or implicitly).
61**	2.	They might reference tzname[1] before calling tzset (explicitly
62**		or implicitly).
63**	3.	They might reference tzname[1] after setting to a time zone
64**		in which Daylight Saving Time is never observed.
65**	4.	They might reference tzname[0] after setting to a time zone
66**		in which Standard Time is never observed.
67**	5.	They might reference tm.TM_ZONE after calling offtime.
68** What's best to do in the above cases is open to debate;
69** for now, we just set things up so that in any of the five cases
70** WILDABBR is used. Another possibility: initialize tzname[0] to the
71** string "tzname[0] used before set", and similarly for the other cases.
72** And another: initialize tzname[0] to "ERA", with an explanation in the
73** manual page of what this "time zone abbreviation" means (doing this so
74** that tzname[0] has the "normal" length of three characters).
75*/
76# define WILDABBR "   "
77#endif /* !defined WILDABBR */
78
79static const char	wildabbr[] = WILDABBR;
80
81static char const etc_utc[] = "Etc/UTC";
82static char const *utc = etc_utc + sizeof "Etc/" - 1;
83
84/*
85** The DST rules to use if TZ has no rules and we can't load TZDEFRULES.
86** Default to US rules as of 2017-05-07.
87** POSIX does not specify the default DST rules;
88** for historical reasons, US rules are a common default.
89*/
90#ifndef TZDEFRULESTRING
91# define TZDEFRULESTRING ",M3.2.0,M11.1.0"
92#endif
93
94typedef int_fast64_t __time_t;
95
96struct ttinfo {				/* time type information */
97	int_fast32_t	tt_utoff;	/* UT offset in seconds */
98	bool		tt_isdst;	/* used to set tm_isdst */
99	int		tt_desigidx;	/* abbreviation list index */
100	bool		tt_ttisstd;	/* transition is std time */
101	bool		tt_ttisut;	/* transition is UT */
102};
103
104struct lsinfo {				/* leap second information */
105	__time_t	ls_trans;	/* transition time */
106	int_fast32_t	ls_corr;	/* correction to apply */
107};
108
109/* This abbreviation means local time is unspecified.  */
110static char const UNSPEC[] = "-00";
111
112/* How many extra bytes are needed at the end of struct state's chars array.
113   This needs to be at least 1 for null termination in case the input
114   data isn't properly terminated, and it also needs to be big enough
115   for ttunspecified to work without crashing.  */
116enum { CHARS_EXTRA = max(sizeof UNSPEC, 2) - 1 };
117
118/* Limit to time zone abbreviation length in POSIX.1-2017-style TZ strings.
119   This is distinct from TZ_MAX_CHARS, which limits TZif file contents.  */
120#ifndef TZNAME_MAXIMUM
121# define TZNAME_MAXIMUM 255
122#endif
123
124#define state __state
125/* A representation of the contents of a TZif file.  Ideally this
126   would have no size limits; the following sizes should suffice for
127   practical use.  This struct should not be too large, as instances
128   are put on the stack and stacks are relatively small on some platforms.
129   See tzfile.h for more about the sizes.  */
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	/*CONSTCOND*/
141	char chars[max(max(TZ_MAX_CHARS + CHARS_EXTRA, sizeof "UTC"),
142		       2 * (TZNAME_MAXIMUM + 1))];
143	struct lsinfo	lsis[TZ_MAX_LEAPS];
144
145	/* The time type to use for early times or if no transitions.
146	   It is always zero for recent tzdb releases.
147	   It might be nonzero for data from tzdb 2018e or earlier.  */
148	int defaulttype;
149};
150
151enum r_type {
152  JULIAN_DAY,		/* Jn = Julian day */
153  DAY_OF_YEAR,		/* n = day of year */
154  MONTH_NTH_DAY_OF_WEEK	/* Mm.n.d = month, week, day of week */
155};
156
157struct rule {
158	enum r_type	r_type;		/* type of rule */
159	int		r_day;		/* day number of rule */
160	int		r_week;		/* week number of rule */
161	int		r_mon;		/* month number of rule */
162	int_fast32_t	r_time;		/* transition time of rule */
163};
164
165static struct tm *gmtsub(struct state const *, time_t const *, int_fast32_t,
166			 struct tm *);
167static bool increment_overflow(int *, int);
168static bool increment_overflow_time(__time_t *, int_fast32_t);
169static int_fast32_t leapcorr(struct state const *, __time_t);
170static bool normalize_overflow32(int_fast32_t *, int *, int);
171static struct tm *timesub(time_t const *, int_fast32_t, struct state const *,
172			  struct tm *);
173static bool tzparse(char const *, struct state *, struct state const *);
174
175static timezone_t gmtptr;
176
177#ifndef TZ_STRLEN_MAX
178# define TZ_STRLEN_MAX 255
179#endif /* !defined TZ_STRLEN_MAX */
180
181static char		lcl_TZname[TZ_STRLEN_MAX + 1];
182static int		lcl_is_set;
183
184
185#if !defined(__LIBC12_SOURCE__)
186timezone_t __lclptr;
187#ifdef _REENTRANT
188rwlock_t __lcl_lock = RWLOCK_INITIALIZER;
189#endif
190#endif
191
192/*
193** Section 4.12.3 of X3.159-1989 requires that
194**	Except for the strftime function, these functions [asctime,
195**	ctime, gmtime, localtime] return values in one of two static
196**	objects: a broken-down time structure and an array of char.
197** Thanks to Paul Eggert for noting this.
198**
199** This requirement was removed in C99, so support it only if requested,
200** as support is more likely to lead to bugs in badly written programs.
201*/
202
203#if SUPPORT_C89
204static struct tm	tm;
205#endif
206
207#if 2 <= HAVE_TZNAME + TZ_TIME_T || defined(__NetBSD__)
208# if !defined(__LIBC12_SOURCE__)
209
210__aconst char *		tzname[2] = {
211	(__aconst char *)__UNCONST(wildabbr),
212	(__aconst char *)__UNCONST(wildabbr)
213};
214
215# else
216
217extern __aconst char *	tzname[2];
218
219# endif /* __LIBC12_SOURCE__ */
220#endif
221
222#if 2 <= USG_COMPAT + TZ_TIME_T || defined(__NetBSD__)
223# if !defined(__LIBC12_SOURCE__)
224long 			timezone = 0;
225int			daylight = 0;
226# endif /* __LIBC12_SOURCE__ */
227#endif /* 2<= USG_COMPAT + TZ_TIME_T */
228
229#if 2 <= ALTZONE + TZ_TIME_T
230long			altzone = 0;
231#endif /* 2 <= ALTZONE + TZ_TIME_T */
232
233/* Initialize *S to a value based on UTOFF, ISDST, and DESIGIDX.  */
234static void
235init_ttinfo(struct ttinfo *s, int_fast32_t utoff, bool isdst, int desigidx)
236{
237  s->tt_utoff = utoff;
238  s->tt_isdst = isdst;
239  s->tt_desigidx = desigidx;
240  s->tt_ttisstd = false;
241  s->tt_ttisut = false;
242}
243
244/* Return true if SP's time type I does not specify local time.  */
245static bool
246ttunspecified(struct state const *sp, int i)
247{
248  char const *abbr = &sp->chars[sp->ttis[i].tt_desigidx];
249  /* memcmp is likely faster than strcmp, and is safe due to CHARS_EXTRA.  */
250  return memcmp(abbr, UNSPEC, sizeof UNSPEC) == 0;
251}
252
253static int_fast32_t
254detzcode(const char *const codep)
255{
256	register int_fast32_t	result;
257	register int		i;
258	int_fast32_t one = 1;
259	int_fast32_t halfmaxval = one << (32 - 2);
260	int_fast32_t maxval = halfmaxval - 1 + halfmaxval;
261	int_fast32_t minval = -1 - maxval;
262
263	result = codep[0] & 0x7f;
264	for (i = 1; i < 4; ++i)
265		result = (result << 8) | (codep[i] & 0xff);
266
267	if (codep[0] & 0x80) {
268	  /* Do two's-complement negation even on non-two's-complement machines.
269	     If the result would be minval - 1, return minval.  */
270	  result -= !TWOS_COMPLEMENT(int_fast32_t) && result != 0;
271	  result += minval;
272	}
273	return result;
274}
275
276static int_fast64_t
277detzcode64(const char *const codep)
278{
279	register int_fast64_t result;
280	register int	i;
281	int_fast64_t one = 1;
282	int_fast64_t halfmaxval = one << (64 - 2);
283	int_fast64_t maxval = halfmaxval - 1 + halfmaxval;
284	int_fast64_t minval = -TWOS_COMPLEMENT(int_fast64_t) - maxval;
285
286	result = codep[0] & 0x7f;
287	for (i = 1; i < 8; ++i)
288		result = (result << 8) | (codep[i] & 0xff);
289
290	if (codep[0] & 0x80) {
291	  /* Do two's-complement negation even on non-two's-complement machines.
292	     If the result would be minval - 1, return minval.  */
293	  result -= !TWOS_COMPLEMENT(int_fast64_t) && result != 0;
294	  result += minval;
295	}
296	return result;
297}
298
299#include <stdio.h>
300
301const char *
302tzgetname(const timezone_t sp, int isdst)
303{
304	int i;
305	const char *name = NULL;
306	for (i = 0; i < sp->typecnt; ++i) {
307		const struct ttinfo *const ttisp = &sp->ttis[i];
308		if (ttisp->tt_isdst == isdst)
309			name = &sp->chars[ttisp->tt_desigidx];
310	}
311	if (name != NULL)
312		return name;
313	errno = ESRCH;
314	return NULL;
315}
316
317long
318tzgetgmtoff(const timezone_t sp, int isdst)
319{
320	int i;
321	long l = -1;
322	for (i = 0; i < sp->typecnt; ++i) {
323		const struct ttinfo *const ttisp = &sp->ttis[i];
324
325		if (ttisp->tt_isdst == isdst) {
326			l = ttisp->tt_utoff;
327		}
328	}
329	if (l == -1)
330		errno = ESRCH;
331	return l;
332}
333
334static void
335update_tzname_etc(struct state const *sp, struct ttinfo const *ttisp)
336{
337#if HAVE_TZNAME
338  tzname[ttisp->tt_isdst] = __UNCONST(&sp->chars[ttisp->tt_desigidx]);
339#endif
340#if USG_COMPAT
341  if (!ttisp->tt_isdst)
342    timezone = - ttisp->tt_utoff;
343#endif
344#if ALTZONE
345  if (ttisp->tt_isdst)
346    altzone = - ttisp->tt_utoff;
347#endif
348}
349
350/* If STDDST_MASK indicates that SP's TYPE provides useful info,
351   update tzname, timezone, and/or altzone and return STDDST_MASK,
352   diminished by the provided info if it is a specified local time.
353   Otherwise, return STDDST_MASK.  See settzname for STDDST_MASK.  */
354static int
355may_update_tzname_etc(int stddst_mask, struct state *sp, int type)
356{
357  struct ttinfo *ttisp = &sp->ttis[type];
358  int this_bit = 1 << ttisp->tt_isdst;
359  if (stddst_mask & this_bit) {
360    update_tzname_etc(sp, ttisp);
361    if (!ttunspecified(sp, type))
362      return stddst_mask & ~this_bit;
363  }
364  return stddst_mask;
365}
366
367static void
368settzname(void)
369{
370	register timezone_t const	sp = __lclptr;
371	register int			i;
372
373	/* If STDDST_MASK & 1 we need info about a standard time.
374	   If STDDST_MASK & 2 we need info about a daylight saving time.
375	   When STDDST_MASK becomes zero we can stop looking.  */
376	int stddst_mask = 0;
377
378#if HAVE_TZNAME
379	tzname[0] = tzname[1] = __UNCONST(sp ? wildabbr : utc);
380	stddst_mask = 3;
381#endif
382#if USG_COMPAT
383	timezone = 0;
384	stddst_mask = 3;
385#endif
386#if ALTZONE
387	altzone = 0;
388	stddst_mask |= 2;
389#endif
390	/*
391	** And to get the latest time zone abbreviations into tzname. . .
392	*/
393	if (sp) {
394	  for (i = sp->timecnt - 1; stddst_mask && 0 <= i; i--)
395	    stddst_mask = may_update_tzname_etc(stddst_mask, sp, sp->types[i]);
396	  for (i = sp->typecnt - 1; stddst_mask && 0 <= i; i--)
397	    stddst_mask = may_update_tzname_etc(stddst_mask, sp, i);
398 	}
399
400#if USG_COMPAT
401	daylight = (unsigned int)stddst_mask >> 1 ^ 1;
402#endif
403}
404
405/* Replace bogus characters in time zone abbreviations.
406   Return 0 on success, an errno value if a time zone abbreviation is
407   too long.  */
408static int
409scrub_abbrs(struct state *sp)
410{
411	int i;
412
413	/* Reject overlong abbreviations.  */
414	for (i = 0; i < sp->charcnt - (TZNAME_MAXIMUM + 1); ) {
415	  int len = (int)strlen(&sp->chars[i]);
416	  if (TZNAME_MAXIMUM < len)
417	    return EOVERFLOW;
418	  i += len + 1;
419	}
420
421	/* Replace bogus characters.  */
422	for (i = 0; i < sp->charcnt; ++i)
423		if (strchr(TZ_ABBR_CHAR_SET, sp->chars[i]) == NULL)
424			sp->chars[i] = TZ_ABBR_ERR_CHAR;
425
426	return 0;
427}
428
429/* Input buffer for data read from a compiled tz file.  */
430union input_buffer {
431  /* The first part of the buffer, interpreted as a header.  */
432  struct tzhead tzhead;
433
434  /* The entire buffer.  Ideally this would have no size limits;
435     the following should suffice for practical use.  */
436  char buf[2 * sizeof(struct tzhead) + 2 * sizeof(struct state)
437	   + 4 * TZ_MAX_TIMES];
438};
439
440/* TZDIR with a trailing '/' rather than a trailing '\0'.  */
441static char const tzdirslash[sizeof TZDIR] = TZDIR "/";
442
443/* Local storage needed for 'tzloadbody'.  */
444union local_storage {
445  /* The results of analyzing the file's contents after it is opened.  */
446  struct file_analysis {
447    /* The input buffer.  */
448    union input_buffer u;
449
450    /* A temporary state used for parsing a TZ string in the file.  */
451    struct state st;
452  } u;
453
454  /* The name of the file to be opened.  Ideally this would have no
455     size limits, to support arbitrarily long Zone names.
456     Limiting Zone names to 1024 bytes should suffice for practical use.
457     However, there is no need for this to be smaller than struct
458     file_analysis as that struct is allocated anyway, as the other
459     union member.  */
460  char fullname[max(sizeof(struct file_analysis), sizeof tzdirslash + 1024)];
461};
462
463/* Load tz data from the file named NAME into *SP.  Read extended
464   format if DOEXTEND.  Use *LSP for temporary storage.  Return 0 on
465   success, an errno value on failure.  */
466static int
467tzloadbody(char const *name, struct state *sp, bool doextend,
468	   union local_storage *lsp)
469{
470	register int			i;
471	register int			fid;
472	register int			stored;
473	register ssize_t		nread;
474	register bool doaccess;
475	register union input_buffer *up = &lsp->u.u;
476	register size_t tzheadsize = sizeof(struct tzhead);
477
478	sp->goback = sp->goahead = false;
479
480	if (! name) {
481		name = TZDEFAULT;
482		if (! name)
483		  return EINVAL;
484	}
485
486	if (name[0] == ':')
487		++name;
488#ifdef SUPPRESS_TZDIR
489	/* Do not prepend TZDIR.  This is intended for specialized
490	   applications only, due to its security implications.  */
491	doaccess = true;
492#else
493	doaccess = name[0] == '/';
494#endif
495	if (!doaccess) {
496		char const *dot;
497		if (sizeof lsp->fullname - sizeof tzdirslash <= strlen(name))
498		  return ENAMETOOLONG;
499
500		/* Create a string "TZDIR/NAME".  Using sprintf here
501		   would pull in stdio (and would fail if the
502		   resulting string length exceeded INT_MAX!).  */
503		memcpy(lsp->fullname, tzdirslash, sizeof tzdirslash);
504		strcpy(lsp->fullname + sizeof tzdirslash, name);
505
506		/* Set doaccess if NAME contains a ".." file name
507		   component, as such a name could read a file outside
508		   the TZDIR virtual subtree.  */
509		for (dot = name; (dot = strchr(dot, '.')); dot++)
510		  if ((dot == name || dot[-1] == '/') && dot[1] == '.'
511		      && (dot[2] == '/' || !dot[2])) {
512		    doaccess = true;
513		    break;
514		  }
515
516		name = lsp->fullname;
517	}
518	if (doaccess && access(name, R_OK) != 0)
519	  return errno;
520	fid = open(name, O_RDONLY | O_BINARY);
521	if (fid < 0)
522	  return errno;
523
524	nread = read(fid, up->buf, sizeof up->buf);
525	if (nread < (ssize_t)tzheadsize) {
526	  int err = nread < 0 ? errno : EINVAL;
527	  close(fid);
528	  return err;
529	}
530	if (close(fid) < 0)
531	  return errno;
532	for (stored = 4; stored <= 8; stored *= 2) {
533	    char version = up->tzhead.tzh_version[0];
534	    bool skip_datablock = stored == 4 && version;
535	    int_fast32_t datablock_size;
536	    int_fast32_t ttisstdcnt = detzcode(up->tzhead.tzh_ttisstdcnt);
537	    int_fast32_t ttisutcnt = detzcode(up->tzhead.tzh_ttisutcnt);
538	    int_fast64_t prevtr = -1;
539	    int_fast32_t prevcorr = 0;
540	    int_fast32_t leapcnt = detzcode(up->tzhead.tzh_leapcnt);
541	    int_fast32_t timecnt = detzcode(up->tzhead.tzh_timecnt);
542	    int_fast32_t typecnt = detzcode(up->tzhead.tzh_typecnt);
543	    int_fast32_t charcnt = detzcode(up->tzhead.tzh_charcnt);
544	    char const *p = up->buf + tzheadsize;
545	    /* Although tzfile(5) currently requires typecnt to be nonzero,
546	       support future formats that may allow zero typecnt
547	       in files that have a TZ string and no transitions.  */
548	    if (! (0 <= leapcnt && leapcnt < TZ_MAX_LEAPS
549		   && 0 <= typecnt && typecnt < TZ_MAX_TYPES
550		   && 0 <= timecnt && timecnt < TZ_MAX_TIMES
551		   && 0 <= charcnt && charcnt < TZ_MAX_CHARS
552		   && 0 <= ttisstdcnt && ttisstdcnt < TZ_MAX_TYPES
553		   && 0 <= ttisutcnt && ttisutcnt < TZ_MAX_TYPES))
554	      return EINVAL;
555	    datablock_size
556		    = (timecnt * stored		/* ats */
557		       + timecnt		/* types */
558		       + typecnt * 6		/* ttinfos */
559		       + charcnt		/* chars */
560		       + leapcnt * (stored + 4)	/* lsinfos */
561		       + ttisstdcnt		/* ttisstds */
562		       + ttisutcnt);		/* ttisuts */
563	    if (nread < (ssize_t)(tzheadsize + datablock_size))
564	      return EINVAL;
565	    if (skip_datablock)
566		p += datablock_size;
567	    else {
568		if (! ((ttisstdcnt == typecnt || ttisstdcnt == 0)
569		       && (ttisutcnt == typecnt || ttisutcnt == 0)))
570		  return EINVAL;
571
572		sp->leapcnt = (int)leapcnt;
573		sp->timecnt = (int)timecnt;
574		sp->typecnt = (int)typecnt;
575		sp->charcnt = (int)charcnt;
576
577		/* Read transitions, discarding those out of time_t range.
578		   But pretend the last transition before TIME_T_MIN
579		   occurred at TIME_T_MIN.  */
580		timecnt = 0;
581		for (i = 0; i < sp->timecnt; ++i) {
582			int_fast64_t at
583			  = stored == 4 ? detzcode(p) : detzcode64(p);
584			sp->types[i] = at <= TIME_T_MAX;
585			if (sp->types[i]) {
586			  time_t attime
587			    = ((TYPE_SIGNED(time_t) ? at < TIME_T_MIN : at < 0)
588			       ? TIME_T_MIN : (time_t)at);
589			  if (timecnt && attime <= sp->ats[timecnt - 1]) {
590			    if (attime < sp->ats[timecnt - 1])
591			      return EINVAL;
592			    sp->types[i - 1] = 0;
593			    timecnt--;
594			  }
595			  sp->ats[timecnt++] = attime;
596			}
597			p += stored;
598		}
599
600		timecnt = 0;
601		for (i = 0; i < sp->timecnt; ++i) {
602			unsigned char typ = *p++;
603			if (sp->typecnt <= typ)
604			  return EINVAL;
605			if (sp->types[i])
606				sp->types[timecnt++] = typ;
607		}
608		sp->timecnt = (int)timecnt;
609		for (i = 0; i < sp->typecnt; ++i) {
610			register struct ttinfo *	ttisp;
611			unsigned char isdst, desigidx;
612
613			ttisp = &sp->ttis[i];
614			ttisp->tt_utoff = detzcode(p);
615			p += 4;
616			isdst = *p++;
617			if (! (isdst < 2))
618			  return EINVAL;
619			ttisp->tt_isdst = isdst;
620			desigidx = *p++;
621			if (! (desigidx < sp->charcnt))
622			  return EINVAL;
623			ttisp->tt_desigidx = desigidx;
624		}
625		for (i = 0; i < sp->charcnt; ++i)
626			sp->chars[i] = *p++;
627		/* Ensure '\0'-terminated, and make it safe to call
628		   ttunspecified later.  */
629		memset(&sp->chars[i], 0, CHARS_EXTRA);
630
631		/* Read leap seconds, discarding those out of time_t range.  */
632		leapcnt = 0;
633		for (i = 0; i < sp->leapcnt; ++i) {
634		  int_fast64_t tr = stored == 4 ? detzcode(p) : detzcode64(p);
635		  int_fast32_t corr = detzcode(p + stored);
636		  p += stored + 4;
637
638		  /* Leap seconds cannot occur before the Epoch,
639		     or out of order.  */
640		  if (tr <= prevtr)
641		    return EINVAL;
642
643		  /* To avoid other botches in this code, each leap second's
644		     correction must differ from the previous one's by 1
645		     second or less, except that the first correction can be
646		     any value; these requirements are more generous than
647		     RFC 8536, to allow future RFC extensions.  */
648		  if (! (i == 0
649			 || (prevcorr < corr
650			     ? corr == prevcorr + 1
651			     : (corr == prevcorr
652				|| corr == prevcorr - 1))))
653		    return EINVAL;
654		  prevtr = tr;
655		  prevcorr = corr;
656
657		  if (tr <= TIME_T_MAX) {
658		    sp->lsis[leapcnt].ls_trans = (time_t)tr;
659		    sp->lsis[leapcnt].ls_corr = corr;
660		    leapcnt++;
661		  }
662		}
663		sp->leapcnt = (int)leapcnt;
664
665		for (i = 0; i < sp->typecnt; ++i) {
666			register struct ttinfo *	ttisp;
667
668			ttisp = &sp->ttis[i];
669			if (ttisstdcnt == 0)
670				ttisp->tt_ttisstd = false;
671			else {
672				if (*p != true && *p != false)
673				  return EINVAL;
674				ttisp->tt_ttisstd = *p++;
675			}
676		}
677		for (i = 0; i < sp->typecnt; ++i) {
678			register struct ttinfo *	ttisp;
679
680			ttisp = &sp->ttis[i];
681			if (ttisutcnt == 0)
682				ttisp->tt_ttisut = false;
683			else {
684				if (*p != true && *p != false)
685						return EINVAL;
686				ttisp->tt_ttisut = *p++;
687			}
688		}
689	    }
690
691	    nread -= p - up->buf;
692	    memmove(up->buf, p, (size_t)nread);
693
694	    /* If this is an old file, we're done.  */
695	    if (!version)
696	      break;
697	}
698	if (doextend && nread > 2 &&
699		up->buf[0] == '\n' && up->buf[nread - 1] == '\n' &&
700		sp->typecnt + 2 <= TZ_MAX_TYPES) {
701			struct state	*ts = &lsp->u.st;
702
703			up->buf[nread - 1] = '\0';
704			if (tzparse(&up->buf[1], ts, sp)) {
705
706			  /* Attempt to reuse existing abbreviations.
707			     Without this, America/Anchorage would be right on
708			     the edge after 2037 when TZ_MAX_CHARS is 50, as
709			     sp->charcnt equals 40 (for LMT AST AWT APT AHST
710			     AHDT YST AKDT AKST) and ts->charcnt equals 10
711			     (for AKST AKDT).  Reusing means sp->charcnt can
712			     stay 40 in this example.  */
713			  int gotabbr = 0;
714			  int charcnt = sp->charcnt;
715			  for (i = 0; i < ts->typecnt; i++) {
716			    char *tsabbr = ts->chars + ts->ttis[i].tt_desigidx;
717			    int j;
718			    for (j = 0; j < charcnt; j++)
719			      if (strcmp(sp->chars + j, tsabbr) == 0) {
720				ts->ttis[i].tt_desigidx = j;
721				gotabbr++;
722				break;
723			      }
724			    if (! (j < charcnt)) {
725			      size_t tsabbrlen = strlen(tsabbr);
726			      if (j + tsabbrlen < TZ_MAX_CHARS) {
727				strcpy(sp->chars + j, tsabbr);
728				charcnt = (int)(j + tsabbrlen + 1);
729				ts->ttis[i].tt_desigidx = j;
730				gotabbr++;
731			      }
732			    }
733			  }
734			  if (gotabbr == ts->typecnt) {
735			    sp->charcnt = charcnt;
736
737			    /* Ignore any trailing, no-op transitions generated
738			       by zic as they don't help here and can run afoul
739			       of bugs in zic 2016j or earlier.  */
740			    while (1 < sp->timecnt
741				   && (sp->types[sp->timecnt - 1]
742				       == sp->types[sp->timecnt - 2]))
743			      sp->timecnt--;
744
745			    sp->goahead = ts->goahead;
746
747			    for (i = 0; i < ts->timecnt; i++) {
748			      __time_t t = ts->ats[i];
749			      if (increment_overflow_time(&t, leapcorr(sp, t))
750				  || (0 < sp->timecnt
751				      && t <= sp->ats[sp->timecnt - 1]))
752				continue;
753			      if (TZ_MAX_TIMES <= sp->timecnt) {
754				sp->goahead = false;
755				break;
756			      }
757			      sp->ats[sp->timecnt] = t;
758			      sp->types[sp->timecnt] = (sp->typecnt
759							+ ts->types[i]);
760			      sp->timecnt++;
761			    }
762			    for (i = 0; i < ts->typecnt; i++)
763			      sp->ttis[sp->typecnt++] = ts->ttis[i];
764			  }
765			}
766	}
767	if (sp->typecnt == 0)
768	  return EINVAL;
769
770	/* Infer sp->defaulttype from the data.  Although this default
771	   type is always zero for data from recent tzdb releases,
772	   things are trickier for data from tzdb 2018e or earlier.
773
774	   The first set of heuristics work around bugs in 32-bit data
775	   generated by tzdb 2013c or earlier.  The workaround is for
776	   zones like Australia/Macquarie where timestamps before the
777	   first transition have a time type that is not the earliest
778	   standard-time type.  See:
779	   https://mm.icann.org/pipermail/tz/2013-May/019368.html */
780	/*
781	** If type 0 does not specify local time, or is unused in transitions,
782	** it's the type to use for early times.
783	*/
784	for (i = 0; i < sp->timecnt; ++i)
785		if (sp->types[i] == 0)
786			break;
787	i = i < sp->timecnt && ! ttunspecified(sp, 0) ? -1 : 0;
788	/*
789	** Absent the above,
790	** if there are transition times
791	** and the first transition is to a daylight time
792	** find the standard type less than and closest to
793	** the type of the first transition.
794	*/
795	if (i < 0 && sp->timecnt > 0 && sp->ttis[sp->types[0]].tt_isdst) {
796		i = sp->types[0];
797		while (--i >= 0)
798			if (!sp->ttis[i].tt_isdst)
799				break;
800	}
801	/* The next heuristics are for data generated by tzdb 2018e or
802	   earlier, for zones like EST5EDT where the first transition
803	   is to DST.  */
804	/*
805	** If no result yet, find the first standard type.
806	** If there is none, punt to type zero.
807	*/
808	if (i < 0) {
809		i = 0;
810		while (sp->ttis[i].tt_isdst)
811			if (++i >= sp->typecnt) {
812				i = 0;
813				break;
814			}
815	}
816	/* A simple 'sp->defaulttype = 0;' would suffice here if we
817	   didn't have to worry about 2018e-or-earlier data.  Even
818	   simpler would be to remove the defaulttype member and just
819	   use 0 in its place.  */
820	sp->defaulttype = i;
821
822	return 0;
823}
824
825/* Load tz data from the file named NAME into *SP.  Read extended
826   format if DOEXTEND.  Return 0 on success, an errno value on failure.  */
827static int
828tzload(char const *name, struct state *sp, bool doextend)
829{
830  union local_storage *lsp = malloc(sizeof *lsp);
831  if (!lsp) {
832    return /*CONSTCOND*/HAVE_MALLOC_ERRNO ? errno : ENOMEM;
833  } else {
834    int err = tzloadbody(name, sp, doextend, lsp);
835    free(lsp);
836    return err;
837  }
838}
839
840static const int	mon_lengths[2][MONSPERYEAR] = {
841	{ 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 },
842	{ 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }
843};
844
845static const int	year_lengths[2] = {
846	DAYSPERNYEAR, DAYSPERLYEAR
847};
848
849/* Is C an ASCII digit?  */
850static bool
851is_digit(char c)
852{
853  return '0' <= c && c <= '9';
854}
855
856/*
857** Given a pointer into a timezone string, scan until a character that is not
858** a valid character in a time zone abbreviation is found.
859** Return a pointer to that character.
860*/
861
862ATTRIBUTE_REPRODUCIBLE static const char *
863getzname(register const char *strp)
864{
865	register char	c;
866
867	while ((c = *strp) != '\0' && !is_digit(c) && c != ',' && c != '-' &&
868		c != '+')
869			++strp;
870	return strp;
871}
872
873/*
874** Given a pointer into an extended timezone string, scan until the ending
875** delimiter of the time zone abbreviation is located.
876** Return a pointer to the delimiter.
877**
878** As with getzname above, the legal character set is actually quite
879** restricted, with other characters producing undefined results.
880** We don't do any checking here; checking is done later in common-case code.
881*/
882
883ATTRIBUTE_REPRODUCIBLE static const char *
884getqzname(register const char *strp, const int delim)
885{
886	register int	c;
887
888	while ((c = *strp) != '\0' && c != delim)
889		++strp;
890	return strp;
891}
892
893/*
894** Given a pointer into a timezone string, extract a number from that string.
895** Check that the number is within a specified range; if it is not, return
896** NULL.
897** Otherwise, return a pointer to the first character not part of the number.
898*/
899
900static const char *
901getnum(register const char *strp, int *const nump, const int min, const int max)
902{
903	register char	c;
904	register int	num;
905
906	if (strp == NULL || !is_digit(c = *strp)) {
907		errno = EINVAL;
908		return NULL;
909	}
910	num = 0;
911	do {
912		num = num * 10 + (c - '0');
913		if (num > max) {
914			errno = EOVERFLOW;
915			return NULL;	/* illegal value */
916		}
917		c = *++strp;
918	} while (is_digit(c));
919	if (num < min) {
920		errno = EINVAL;
921		return NULL;		/* illegal value */
922	}
923	*nump = num;
924	return strp;
925}
926
927/*
928** Given a pointer into a timezone string, extract a number of seconds,
929** in hh[:mm[:ss]] form, from the string.
930** If any error occurs, return NULL.
931** Otherwise, return a pointer to the first character not part of the number
932** of seconds.
933*/
934
935static const char *
936getsecs(register const char *strp, int_fast32_t *const secsp)
937{
938	int	num;
939	int_fast32_t secsperhour = SECSPERHOUR;
940
941	/*
942	** 'HOURSPERDAY * DAYSPERWEEK - 1' allows quasi-POSIX rules like
943	** "M10.4.6/26", which does not conform to POSIX,
944	** but which specifies the equivalent of
945	** "02:00 on the first Sunday on or after 23 Oct".
946	*/
947	strp = getnum(strp, &num, 0, HOURSPERDAY * DAYSPERWEEK - 1);
948	if (strp == NULL)
949		return NULL;
950	*secsp = num * secsperhour;
951	if (*strp == ':') {
952		++strp;
953		strp = getnum(strp, &num, 0, MINSPERHOUR - 1);
954		if (strp == NULL)
955			return NULL;
956		*secsp += num * SECSPERMIN;
957		if (*strp == ':') {
958			++strp;
959			/* 'SECSPERMIN' allows for leap seconds.  */
960			strp = getnum(strp, &num, 0, SECSPERMIN);
961			if (strp == NULL)
962				return NULL;
963			*secsp += num;
964		}
965	}
966	return strp;
967}
968
969/*
970** Given a pointer into a timezone string, extract an offset, in
971** [+-]hh[:mm[:ss]] form, from the string.
972** If any error occurs, return NULL.
973** Otherwise, return a pointer to the first character not part of the time.
974*/
975
976static const char *
977getoffset(register const char *strp, int_fast32_t *const offsetp)
978{
979	register bool neg = false;
980
981	if (*strp == '-') {
982		neg = true;
983		++strp;
984	} else if (*strp == '+')
985		++strp;
986	strp = getsecs(strp, offsetp);
987	if (strp == NULL)
988		return NULL;		/* illegal time */
989	if (neg)
990		*offsetp = -*offsetp;
991	return strp;
992}
993
994/*
995** Given a pointer into a timezone string, extract a rule in the form
996** date[/time]. See POSIX Base Definitions section 8.3 variable TZ
997** for the format of "date" and "time".
998** If a valid rule is not found, return NULL.
999** Otherwise, return a pointer to the first character not part of the rule.
1000*/
1001
1002static const char *
1003getrule(const char *strp, register struct rule *const rulep)
1004{
1005	if (*strp == 'J') {
1006		/*
1007		** Julian day.
1008		*/
1009		rulep->r_type = JULIAN_DAY;
1010		++strp;
1011		strp = getnum(strp, &rulep->r_day, 1, DAYSPERNYEAR);
1012	} else if (*strp == 'M') {
1013		/*
1014		** Month, week, day.
1015		*/
1016		rulep->r_type = MONTH_NTH_DAY_OF_WEEK;
1017		++strp;
1018		strp = getnum(strp, &rulep->r_mon, 1, MONSPERYEAR);
1019		if (strp == NULL)
1020			return NULL;
1021		if (*strp++ != '.')
1022			return NULL;
1023		strp = getnum(strp, &rulep->r_week, 1, 5);
1024		if (strp == NULL)
1025			return NULL;
1026		if (*strp++ != '.')
1027			return NULL;
1028		strp = getnum(strp, &rulep->r_day, 0, DAYSPERWEEK - 1);
1029	} else if (is_digit(*strp)) {
1030		/*
1031		** Day of year.
1032		*/
1033		rulep->r_type = DAY_OF_YEAR;
1034		strp = getnum(strp, &rulep->r_day, 0, DAYSPERLYEAR - 1);
1035	} else	return NULL;		/* invalid format */
1036	if (strp == NULL)
1037		return NULL;
1038	if (*strp == '/') {
1039		/*
1040		** Time specified.
1041		*/
1042		++strp;
1043		strp = getoffset(strp, &rulep->r_time);
1044	} else	rulep->r_time = 2 * SECSPERHOUR;	/* default = 2:00:00 */
1045	return strp;
1046}
1047
1048/*
1049** Given a year, a rule, and the offset from UT at the time that rule takes
1050** effect, calculate the year-relative time that rule takes effect.
1051*/
1052
1053static int_fast32_t
1054transtime(const int year, register const struct rule *const rulep,
1055	  const int_fast32_t offset)
1056{
1057	register bool	leapyear;
1058	register int_fast32_t value;
1059	register int	i;
1060	int		d, m1, yy0, yy1, yy2, dow;
1061
1062	leapyear = isleap(year);
1063	switch (rulep->r_type) {
1064
1065	case JULIAN_DAY:
1066		/*
1067		** Jn - Julian day, 1 == January 1, 60 == March 1 even in leap
1068		** years.
1069		** In non-leap years, or if the day number is 59 or less, just
1070		** add SECSPERDAY times the day number-1 to the time of
1071		** January 1, midnight, to get the day.
1072		*/
1073		value = (rulep->r_day - 1) * SECSPERDAY;
1074		if (leapyear && rulep->r_day >= 60)
1075			value += SECSPERDAY;
1076		break;
1077
1078	case DAY_OF_YEAR:
1079		/*
1080		** n - day of year.
1081		** Just add SECSPERDAY times the day number to the time of
1082		** January 1, midnight, to get the day.
1083		*/
1084		value = rulep->r_day * SECSPERDAY;
1085		break;
1086
1087	case MONTH_NTH_DAY_OF_WEEK:
1088		/*
1089		** Mm.n.d - nth "dth day" of month m.
1090		*/
1091
1092		/*
1093		** Use Zeller's Congruence to get day-of-week of first day of
1094		** month.
1095		*/
1096		m1 = (rulep->r_mon + 9) % 12 + 1;
1097		yy0 = (rulep->r_mon <= 2) ? (year - 1) : year;
1098		yy1 = yy0 / 100;
1099		yy2 = yy0 % 100;
1100		dow = ((26 * m1 - 2) / 10 +
1101			1 + yy2 + yy2 / 4 + yy1 / 4 - 2 * yy1) % 7;
1102		if (dow < 0)
1103			dow += DAYSPERWEEK;
1104
1105		/*
1106		** "dow" is the day-of-week of the first day of the month. Get
1107		** the day-of-month (zero-origin) of the first "dow" day of the
1108		** month.
1109		*/
1110		d = rulep->r_day - dow;
1111		if (d < 0)
1112			d += DAYSPERWEEK;
1113		for (i = 1; i < rulep->r_week; ++i) {
1114			if (d + DAYSPERWEEK >=
1115				mon_lengths[leapyear][rulep->r_mon - 1])
1116					break;
1117			d += DAYSPERWEEK;
1118		}
1119
1120		/*
1121		** "d" is the day-of-month (zero-origin) of the day we want.
1122		*/
1123		value = d * SECSPERDAY;
1124		for (i = 0; i < rulep->r_mon - 1; ++i)
1125			value += mon_lengths[leapyear][i] * SECSPERDAY;
1126		break;
1127
1128	default: unreachable();
1129	}
1130
1131	/*
1132	** "value" is the year-relative time of 00:00:00 UT on the day in
1133	** question. To get the year-relative time of the specified local
1134	** time on that day, add the transition time and the current offset
1135	** from UT.
1136	*/
1137	return value + rulep->r_time + offset;
1138}
1139
1140/*
1141** Given a POSIX.1-2017-style TZ string, fill in the rule tables as
1142** appropriate.
1143*/
1144
1145static bool
1146tzparse(const char *name, struct state *sp, struct state const *basep)
1147{
1148	const char *			stdname;
1149	const char *			dstname;
1150	int_fast32_t			stdoffset;
1151	int_fast32_t			dstoffset;
1152	register char *			cp;
1153	register bool			load_ok;
1154	ptrdiff_t stdlen, dstlen, charcnt;
1155	__time_t atlo = TIME_T_MIN, leaplo = TIME_T_MIN;
1156
1157	dstname = NULL; /* XXX gcc */
1158	stdname = name;
1159	if (*name == '<') {
1160	  name++;
1161	  stdname = name;
1162	  name = getqzname(name, '>');
1163	  if (*name != '>')
1164	    return false;
1165	  stdlen = name - stdname;
1166	  name++;
1167	} else {
1168	  name = getzname(name);
1169	  stdlen = name - stdname;
1170	}
1171	if (! (0 < stdlen && stdlen <= TZNAME_MAXIMUM))
1172	  return false;
1173	name = getoffset(name, &stdoffset);
1174	if (name == NULL)
1175	  return false;
1176	charcnt = stdlen + 1;
1177	if (basep) {
1178	  if (0 < basep->timecnt)
1179	    atlo = basep->ats[basep->timecnt - 1];
1180	  load_ok = false;
1181	  sp->leapcnt = basep->leapcnt;
1182	  memcpy(sp->lsis, basep->lsis, sp->leapcnt * sizeof *sp->lsis);
1183	} else {
1184	  load_ok = tzload(TZDEFRULES, sp, false) == 0;
1185	  if (!load_ok)
1186	    sp->leapcnt = 0;	/* So, we're off a little.  */
1187	}
1188	if (0 < sp->leapcnt)
1189	  leaplo = sp->lsis[sp->leapcnt - 1].ls_trans;
1190	sp->goback = sp->goahead = false;
1191	if (*name != '\0') {
1192		if (*name == '<') {
1193			dstname = ++name;
1194			name = getqzname(name, '>');
1195			if (*name != '>')
1196			  return false;
1197			dstlen = name - dstname;
1198			name++;
1199		} else {
1200			dstname = name;
1201			name = getzname(name);
1202			dstlen = name - dstname; /* length of DST abbr. */
1203		}
1204		if (! (0 < dstlen && dstlen <= TZNAME_MAXIMUM))
1205		  return false;
1206		charcnt += dstlen + 1;
1207		if (*name != '\0' && *name != ',' && *name != ';') {
1208			name = getoffset(name, &dstoffset);
1209			if (name == NULL)
1210			  return false;
1211		} else	dstoffset = stdoffset - SECSPERHOUR;
1212		if (*name == '\0' && !load_ok)
1213			name = TZDEFRULESTRING;
1214		if (*name == ',' || *name == ';') {
1215			struct rule	start;
1216			struct rule	end;
1217			register int	year;
1218			register int	timecnt;
1219			__time_t	janfirst;
1220			int_fast32_t janoffset = 0;
1221			int yearbeg, yearlim;
1222
1223			++name;
1224			if ((name = getrule(name, &start)) == NULL)
1225			  return false;
1226			if (*name++ != ',')
1227			  return false;
1228			if ((name = getrule(name, &end)) == NULL)
1229			  return false;
1230			if (*name != '\0')
1231			  return false;
1232			sp->typecnt = 2;	/* standard time and DST */
1233			/*
1234			** Two transitions per year, from EPOCH_YEAR forward.
1235			*/
1236			init_ttinfo(&sp->ttis[0], -stdoffset, false, 0);
1237			init_ttinfo(&sp->ttis[1], -dstoffset, true,
1238			    (int)(stdlen + 1));
1239			timecnt = 0;
1240			janfirst = 0;
1241			yearbeg = EPOCH_YEAR;
1242
1243			do {
1244			  int_fast32_t yearsecs
1245			    = year_lengths[isleap(yearbeg - 1)] * SECSPERDAY;
1246			  yearbeg--;
1247			  if (increment_overflow_time(&janfirst, -yearsecs)) {
1248			    janoffset = -yearsecs;
1249			    break;
1250			  }
1251			} while (atlo < janfirst
1252				 && EPOCH_YEAR - YEARSPERREPEAT / 2 < yearbeg);
1253
1254			for (;;) {
1255			  int_fast32_t yearsecs
1256			    = year_lengths[isleap(yearbeg)] * SECSPERDAY;
1257			  int yearbeg1 = yearbeg;
1258			  __time_t janfirst1 = janfirst;
1259			  if (increment_overflow_time(&janfirst1, yearsecs)
1260			      || increment_overflow(&yearbeg1, 1)
1261			      || atlo <= janfirst1)
1262			    break;
1263			  yearbeg = yearbeg1;
1264			  janfirst = janfirst1;
1265			}
1266
1267			yearlim = yearbeg;
1268			if (increment_overflow(&yearlim, years_of_observations))
1269			  yearlim = INT_MAX;
1270			for (year = yearbeg; year < yearlim; year++) {
1271				int_fast32_t
1272				  starttime = transtime(year, &start, stdoffset),
1273				  endtime = transtime(year, &end, dstoffset);
1274				int_fast32_t
1275				  yearsecs = (year_lengths[isleap(year)]
1276					      * SECSPERDAY);
1277				bool reversed = endtime < starttime;
1278				if (reversed) {
1279					int_fast32_t swap = starttime;
1280					starttime = endtime;
1281					endtime = swap;
1282				}
1283				if (reversed
1284				    || (starttime < endtime
1285					&& endtime - starttime < yearsecs)) {
1286					if (TZ_MAX_TIMES - 2 < timecnt)
1287						break;
1288					sp->ats[timecnt] = janfirst;
1289					if (! increment_overflow_time
1290					    (&sp->ats[timecnt],
1291					     janoffset + starttime)
1292					    && atlo <= sp->ats[timecnt])
1293					  sp->types[timecnt++] = !reversed;
1294					sp->ats[timecnt] = janfirst;
1295					if (! increment_overflow_time
1296					    (&sp->ats[timecnt],
1297					     janoffset + endtime)
1298					    && atlo <= sp->ats[timecnt]) {
1299					  sp->types[timecnt++] = reversed;
1300					}
1301				}
1302				if (endtime < leaplo) {
1303				  yearlim = year;
1304				  if (increment_overflow(&yearlim,
1305							 years_of_observations))
1306				    yearlim = INT_MAX;
1307				}
1308				if (increment_overflow_time
1309				    (&janfirst, janoffset + yearsecs))
1310					break;
1311				janoffset = 0;
1312			}
1313			sp->timecnt = timecnt;
1314			if (! timecnt) {
1315				sp->ttis[0] = sp->ttis[1];
1316				sp->typecnt = 1;	/* Perpetual DST.  */
1317			} else if (years_of_observations <= year - yearbeg)
1318				sp->goback = sp->goahead = true;
1319		} else {
1320			register int_fast32_t	theirstdoffset;
1321			register int_fast32_t	theirdstoffset;
1322			register int_fast32_t	theiroffset;
1323			register bool		isdst;
1324			register int		i;
1325			register int		j;
1326
1327			if (*name != '\0')
1328			  return false;
1329			/*
1330			** Initial values of theirstdoffset and theirdstoffset.
1331			*/
1332			theirstdoffset = 0;
1333			for (i = 0; i < sp->timecnt; ++i) {
1334				j = sp->types[i];
1335				if (!sp->ttis[j].tt_isdst) {
1336					theirstdoffset =
1337						- sp->ttis[j].tt_utoff;
1338					break;
1339				}
1340			}
1341			theirdstoffset = 0;
1342			for (i = 0; i < sp->timecnt; ++i) {
1343				j = sp->types[i];
1344				if (sp->ttis[j].tt_isdst) {
1345					theirdstoffset =
1346						- sp->ttis[j].tt_utoff;
1347					break;
1348				}
1349			}
1350			/*
1351			** Initially we're assumed to be in standard time.
1352			*/
1353			isdst = false;
1354			/*
1355			** Now juggle transition times and types
1356			** tracking offsets as you do.
1357			*/
1358			for (i = 0; i < sp->timecnt; ++i) {
1359				j = sp->types[i];
1360				sp->types[i] = sp->ttis[j].tt_isdst;
1361				if (sp->ttis[j].tt_ttisut) {
1362					/* No adjustment to transition time */
1363				} else {
1364					/*
1365					** If daylight saving time is in
1366					** effect, and the transition time was
1367					** not specified as standard time, add
1368					** the daylight saving time offset to
1369					** the transition time; otherwise, add
1370					** the standard time offset to the
1371					** transition time.
1372					*/
1373					/*
1374					** Transitions from DST to DDST
1375					** will effectively disappear since
1376					** POSIX.1-2017 provides for only one
1377					** DST offset.
1378					*/
1379					if (isdst && !sp->ttis[j].tt_ttisstd) {
1380						sp->ats[i] += (time_t)
1381						    (dstoffset - theirdstoffset);
1382					} else {
1383						sp->ats[i] += (time_t)
1384						    (stdoffset - theirstdoffset);
1385					}
1386				}
1387				theiroffset = -sp->ttis[j].tt_utoff;
1388				if (sp->ttis[j].tt_isdst)
1389					theirstdoffset = theiroffset;
1390				else	theirdstoffset = theiroffset;
1391			}
1392			/*
1393			** Finally, fill in ttis.
1394			*/
1395			init_ttinfo(&sp->ttis[0], -stdoffset, false, 0);
1396			init_ttinfo(&sp->ttis[1], -dstoffset, true,
1397			    (int)(stdlen + 1));
1398			sp->typecnt = 2;
1399		}
1400	} else {
1401		dstlen = 0;
1402		sp->typecnt = 1;		/* only standard time */
1403		sp->timecnt = 0;
1404		init_ttinfo(&sp->ttis[0], -stdoffset, false, 0);
1405		init_ttinfo(&sp->ttis[1], 0, false, 0);
1406	}
1407	sp->defaulttype = 0;
1408	sp->charcnt = (int)charcnt;
1409	cp = sp->chars;
1410	memcpy(cp, stdname, stdlen);
1411	cp += stdlen;
1412	*cp++ = '\0';
1413	if (dstlen != 0) {
1414		(void) memcpy(cp, dstname, dstlen);
1415		*(cp + dstlen) = '\0';
1416	}
1417	return true;
1418}
1419
1420static void
1421gmtload(struct state *const sp)
1422{
1423	if (tzload(etc_utc, sp, true) != 0)
1424	  (void)tzparse("UTC0", sp, NULL);
1425}
1426
1427/* Initialize *SP to a value appropriate for the TZ setting NAME.
1428   Return 0 on success, an errno value on failure.  */
1429static int
1430zoneinit(struct state *sp, char const *name)
1431{
1432  if (name && ! name[0]) {
1433    /*
1434    ** User wants it fast rather than right.
1435    */
1436    sp->leapcnt = 0;		/* so, we're off a little */
1437    sp->timecnt = 0;
1438    sp->typecnt = 1;
1439    sp->charcnt = 0;
1440    sp->goback = sp->goahead = false;
1441    init_ttinfo(&sp->ttis[0], 0, false, 0);
1442    strcpy(sp->chars, utc);
1443    sp->defaulttype = 0;
1444    return 0;
1445  } else {
1446    int err = tzload(name, sp, true);
1447    if (err != 0 && name && name[0] != ':' && tzparse(name, sp, NULL))
1448      err = 0;
1449    if (err == 0)
1450      err = scrub_abbrs(sp);
1451    return err;
1452  }
1453}
1454
1455static void
1456tzsetlcl(char const *name)
1457{
1458  struct state *sp = __lclptr;
1459  int lcl = name ? strlen(name) < sizeof lcl_TZname : -1;
1460  if (lcl < 0
1461      ? lcl_is_set < 0
1462      : 0 < lcl_is_set && strcmp(lcl_TZname, name) == 0)
1463    return;
1464
1465  if (! sp)
1466    __lclptr = sp = malloc(sizeof *__lclptr);
1467  if (sp) {
1468    if (zoneinit(sp, name) != 0)
1469      zoneinit(sp, "");
1470    if (0 < lcl)
1471      strcpy(lcl_TZname, name);
1472  }
1473  settzname();
1474  lcl_is_set = lcl;
1475}
1476
1477#ifdef STD_INSPIRED
1478void
1479tzsetwall(void)
1480{
1481	rwlock_wrlock(&__lcl_lock);
1482	tzsetlcl(NULL);
1483	rwlock_unlock(&__lcl_lock);
1484}
1485#endif
1486
1487void
1488tzset_unlocked(void)
1489{
1490	tzsetlcl(getenv("TZ"));
1491}
1492
1493void
1494tzset(void)
1495{
1496  rwlock_wrlock(&__lcl_lock);
1497  tzset_unlocked();
1498  rwlock_unlock(&__lcl_lock);
1499}
1500
1501static void
1502gmtcheck(void)
1503{
1504  static bool gmt_is_set;
1505  rwlock_wrlock(&__lcl_lock);
1506  if (! gmt_is_set) {
1507    gmtptr = malloc(sizeof *gmtptr);
1508    if (gmtptr)
1509      gmtload(gmtptr);
1510    gmt_is_set = true;
1511  }
1512  rwlock_unlock(&__lcl_lock);
1513}
1514
1515#if NETBSD_INSPIRED
1516
1517timezone_t
1518tzalloc(char const *name)
1519{
1520  timezone_t sp = malloc(sizeof *sp);
1521  if (sp) {
1522    int err = zoneinit(sp, name);
1523    if (err != 0) {
1524      free(sp);
1525      errno = err;
1526      return NULL;
1527    }
1528  } else if (/*CONSTCOND*/!HAVE_MALLOC_ERRNO)
1529    /*NOTREACHED*/
1530    errno = ENOMEM;
1531  return sp;
1532}
1533
1534void
1535tzfree(timezone_t sp)
1536{
1537  free(sp);
1538}
1539
1540/*
1541** NetBSD 6.1.4 has ctime_rz, but omit it because POSIX says ctime and
1542** ctime_r are obsolescent and have potential security problems that
1543** ctime_rz would share.  Callers can instead use localtime_rz + strftime.
1544**
1545** NetBSD 6.1.4 has tzgetname, but omit it because it doesn't work
1546** in zones with three or more time zone abbreviations.
1547** Callers can instead use localtime_rz + strftime.
1548*/
1549
1550#endif
1551
1552/*
1553** The easy way to behave "as if no library function calls" localtime
1554** is to not call it, so we drop its guts into "localsub", which can be
1555** freely called. (And no, the PANS doesn't require the above behavior,
1556** but it *is* desirable.)
1557**
1558** If successful and SETNAME is nonzero,
1559** set the applicable parts of tzname, timezone and altzone;
1560** however, it's OK to omit this step
1561** if the timezone is compatible with POSIX.1-2017
1562** since in that case tzset should have already done this step correctly.
1563** SETNAME's type is int_fast32_t for compatibility with gmtsub,
1564** but it is actually a boolean and its value should be 0 or 1.
1565*/
1566
1567/*ARGSUSED*/
1568static struct tm *
1569localsub(struct state const *sp, time_t const *timep, int_fast32_t setname,
1570	 struct tm *const tmp)
1571{
1572	register const struct ttinfo *	ttisp;
1573	register int			i;
1574	register struct tm *		result;
1575	const time_t			t = *timep;
1576
1577	if (sp == NULL) {
1578	  /* Don't bother to set tzname etc.; tzset has already done it.  */
1579	  return gmtsub(gmtptr, timep, 0, tmp);
1580	}
1581	if ((sp->goback && t < sp->ats[0]) ||
1582		(sp->goahead && t > sp->ats[sp->timecnt - 1])) {
1583			time_t newt;
1584			register __time_t	seconds;
1585			register time_t		years;
1586
1587			if (t < sp->ats[0])
1588				seconds = sp->ats[0] - t;
1589			else	seconds = t - sp->ats[sp->timecnt - 1];
1590			--seconds;
1591
1592			/* Beware integer overflow, as SECONDS might
1593			   be close to the maximum time_t.  */
1594			years = (time_t)(seconds / SECSPERREPEAT
1595			    * YEARSPERREPEAT);
1596			seconds = (time_t)(years * AVGSECSPERYEAR);
1597			years += YEARSPERREPEAT;
1598			if (t < sp->ats[0])
1599			  newt = (time_t)(t + seconds + SECSPERREPEAT);
1600			else
1601			  newt = (time_t)(t - seconds - SECSPERREPEAT);
1602
1603			if (newt < sp->ats[0] ||
1604				newt > sp->ats[sp->timecnt - 1]) {
1605				errno = EINVAL;
1606				return NULL;	/* "cannot happen" */
1607			}
1608			result = localsub(sp, &newt, setname, tmp);
1609			if (result) {
1610#if defined ckd_add && defined ckd_sub
1611				if (t < sp->ats[0]
1612				    ? ckd_sub(&result->tm_year,
1613					      result->tm_year, years)
1614				    : ckd_add(&result->tm_year,
1615					      result->tm_year, years))
1616				  return NULL;
1617#else
1618				register int_fast64_t newy;
1619
1620				newy = result->tm_year;
1621				if (t < sp->ats[0])
1622					newy -= years;
1623				else	newy += years;
1624				if (! (INT_MIN <= newy && newy <= INT_MAX)) {
1625					errno = EOVERFLOW;
1626					return NULL;
1627				}
1628				result->tm_year = (int)newy;
1629#endif
1630			}
1631			return result;
1632	}
1633	if (sp->timecnt == 0 || t < sp->ats[0]) {
1634		i = sp->defaulttype;
1635	} else {
1636		register int	lo = 1;
1637		register int	hi = sp->timecnt;
1638
1639		while (lo < hi) {
1640			register int	mid = (lo + hi) / 2;
1641
1642			if (t < sp->ats[mid])
1643				hi = mid;
1644			else	lo = mid + 1;
1645		}
1646		i = sp->types[lo - 1];
1647	}
1648	ttisp = &sp->ttis[i];
1649	/*
1650	** To get (wrong) behavior that's compatible with System V Release 2.0
1651	** you'd replace the statement below with
1652	**	t += ttisp->tt_utoff;
1653	**	timesub(&t, 0L, sp, tmp);
1654	*/
1655	result = timesub(&t, ttisp->tt_utoff, sp, tmp);
1656	if (result) {
1657	  result->tm_isdst = ttisp->tt_isdst;
1658#ifdef TM_ZONE
1659	  result->TM_ZONE = __UNCONST(&sp->chars[ttisp->tt_desigidx]);
1660#endif /* defined TM_ZONE */
1661	  if (setname)
1662	    update_tzname_etc(sp, ttisp);
1663	}
1664	return result;
1665}
1666
1667#if NETBSD_INSPIRED
1668
1669struct tm *
1670localtime_rz(struct state *__restrict sp, time_t const *__restrict timep,
1671	struct tm *__restrict tmp)
1672{
1673  return localsub(sp, timep, 0, tmp);
1674}
1675
1676#endif
1677
1678static struct tm *
1679localtime_tzset(time_t const *timep, struct tm *tmp, bool setname)
1680{
1681  rwlock_wrlock(&__lcl_lock);
1682  if (setname || !lcl_is_set)
1683    tzset_unlocked();
1684  tmp = localsub(__lclptr, timep, setname, tmp);
1685  rwlock_unlock(&__lcl_lock);
1686  return tmp;
1687}
1688
1689struct tm *
1690localtime(const time_t *timep)
1691{
1692#if !SUPPORT_C89
1693  static struct tm tm;
1694#endif
1695  return localtime_tzset(timep, &tm, true);
1696}
1697
1698struct tm *
1699localtime_r(const time_t *__restrict timep, struct tm *__restrict tmp)
1700{
1701  return localtime_tzset(timep, tmp, true);
1702}
1703
1704/*
1705** gmtsub is to gmtime as localsub is to localtime.
1706*/
1707
1708static struct tm *
1709gmtsub(ATTRIBUTE_MAYBE_UNUSED struct state const *sp, time_t const *timep,
1710       int_fast32_t offset, struct tm *tmp)
1711{
1712	register struct tm *	result;
1713
1714	result = timesub(timep, offset, gmtptr, tmp);
1715#ifdef TM_ZONE
1716	/*
1717	** Could get fancy here and deliver something such as
1718	** "+xx" or "-xx" if offset is non-zero,
1719	** but this is no time for a treasure hunt.
1720	*/
1721	if (result)
1722		result->TM_ZONE = offset ? __UNCONST(wildabbr) : gmtptr ?
1723		    gmtptr->chars : __UNCONST(utc);
1724#endif /* defined TM_ZONE */
1725	return result;
1726}
1727
1728/*
1729* Re-entrant version of gmtime.
1730*/
1731
1732struct tm *
1733gmtime_r(time_t const *__restrict timep, struct tm *__restrict tmp)
1734{
1735  gmtcheck();
1736  return gmtsub(NULL, timep, 0, tmp);
1737}
1738
1739struct tm *
1740gmtime(const time_t *timep)
1741{
1742#if !SUPPORT_C89
1743  static struct tm tm;
1744#endif
1745  return gmtime_r(timep, &tm);
1746}
1747
1748#if STD_INSPIRED
1749
1750/* This function is obsolescent and may disappear in future releases.
1751   Callers can instead use localtime_rz with a fixed-offset zone.  */
1752
1753struct tm *
1754offtime(const time_t *timep, long offset)
1755{
1756  gmtcheck();
1757
1758#if !SUPPORT_C89
1759  static struct tm tm;
1760#endif
1761  return gmtsub(gmtptr, timep, (int_fast32_t)offset, &tm);
1762}
1763
1764struct tm *
1765offtime_r(const time_t *timep, long offset, struct tm *tmp)
1766{
1767	gmtcheck();
1768	return gmtsub(NULL, timep, (int_fast32_t)offset, tmp);
1769}
1770
1771#endif /* STD_INSPIRED */
1772
1773#if TZ_TIME_T
1774
1775# if USG_COMPAT
1776#  define daylight 0
1777#  define timezone 0
1778# endif
1779# if !ALTZONE
1780#  define altzone 0
1781# endif
1782
1783/* Convert from the underlying system's time_t to the ersatz time_tz,
1784   which is called 'time_t' in this file.  Typically, this merely
1785   converts the time's integer width.  On some platforms, the system
1786   time is local time not UT, or uses some epoch other than the POSIX
1787   epoch.
1788
1789   Although this code appears to define a function named 'time' that
1790   returns time_t, the macros in private.h cause this code to actually
1791   define a function named 'tz_time' that returns tz_time_t.  The call
1792   to sys_time invokes the underlying system's 'time' function.  */
1793
1794time_t
1795time(time_t *p)
1796{
1797  __time_t r = sys_time(0);
1798  if (r != (time_t) -1) {
1799    int_fast32_t offset = EPOCH_LOCAL ? (daylight ? timezone : altzone) : 0;
1800    if (increment_overflow32(&offset, -EPOCH_OFFSET)
1801	|| increment_overflow_time(&r, offset)) {
1802      errno = EOVERFLOW;
1803      r = -1;
1804    }
1805  }
1806  if (p)
1807    *p = (time_t)r;
1808  return (time_t)r;
1809}
1810#endif
1811
1812/*
1813** Return the number of leap years through the end of the given year
1814** where, to make the math easy, the answer for year zero is defined as zero.
1815*/
1816
1817static time_t
1818leaps_thru_end_of_nonneg(time_t y)
1819{
1820  return y / 4 - y / 100 + y / 400;
1821}
1822
1823static time_t
1824leaps_thru_end_of(time_t y)
1825{
1826  return (y < 0
1827	  ? -1 - leaps_thru_end_of_nonneg(-1 - y)
1828	  : leaps_thru_end_of_nonneg(y));
1829}
1830
1831static struct tm *
1832timesub(const time_t *timep, int_fast32_t offset,
1833	const struct state *sp, struct tm *tmp)
1834{
1835	register const struct lsinfo *	lp;
1836	register time_t			tdays;
1837	register const int *		ip;
1838	register int_fast32_t		corr;
1839	register int			i;
1840	int_fast32_t idays, rem, dayoff, dayrem;
1841	time_t y;
1842
1843	/* If less than SECSPERMIN, the number of seconds since the
1844	   most recent positive leap second; otherwise, do not add 1
1845	   to localtime tm_sec because of leap seconds.  */
1846	__time_t secs_since_posleap = SECSPERMIN;
1847
1848	corr = 0;
1849	i = (sp == NULL) ? 0 : sp->leapcnt;
1850	while (--i >= 0) {
1851		lp = &sp->lsis[i];
1852		if (*timep >= lp->ls_trans) {
1853			corr = lp->ls_corr;
1854			if ((i == 0 ? 0 : lp[-1].ls_corr) < corr)
1855			  secs_since_posleap = *timep - lp->ls_trans;
1856			break;
1857		}
1858	}
1859
1860	/* Calculate the year, avoiding integer overflow even if
1861	   time_t is unsigned.  */
1862	tdays = (time_t)(*timep / SECSPERDAY);
1863	rem = (int)(*timep % SECSPERDAY);
1864	rem += offset % SECSPERDAY - corr % SECSPERDAY + 3 * SECSPERDAY;
1865	dayoff = offset / SECSPERDAY - corr / SECSPERDAY + rem / SECSPERDAY - 3;
1866	rem %= SECSPERDAY;
1867	/* y = (EPOCH_YEAR
1868	        + floor((tdays + dayoff) / DAYSPERREPEAT) * YEARSPERREPEAT),
1869	   sans overflow.  But calculate against 1570 (EPOCH_YEAR -
1870	   YEARSPERREPEAT) instead of against 1970 so that things work
1871	   for localtime values before 1970 when time_t is unsigned.  */
1872	dayrem = (int)(tdays % DAYSPERREPEAT);
1873	dayrem += dayoff % DAYSPERREPEAT;
1874	y = (time_t)(EPOCH_YEAR - YEARSPERREPEAT
1875	     + ((1 + dayoff / DAYSPERREPEAT + dayrem / DAYSPERREPEAT
1876		 - ((dayrem % DAYSPERREPEAT) < 0)
1877		 + tdays / DAYSPERREPEAT)
1878		* YEARSPERREPEAT));
1879	/* idays = (tdays + dayoff) mod DAYSPERREPEAT, sans overflow.  */
1880	idays = (int)(tdays % DAYSPERREPEAT);
1881	idays += (dayoff % DAYSPERREPEAT + 2 * DAYSPERREPEAT);
1882	idays %= DAYSPERREPEAT;
1883	/* Increase Y and decrease IDAYS until IDAYS is in range for Y.  */
1884	while (year_lengths[isleap(y)] <= idays) {
1885		int_fast32_t tdelta = idays / DAYSPERLYEAR;
1886		int_fast32_t ydelta = tdelta + !tdelta;
1887		time_t newy = (time_t)(y + ydelta);
1888		register int	leapdays;
1889		leapdays = (int)(leaps_thru_end_of(newy - 1) -
1890			leaps_thru_end_of(y - 1));
1891		idays -= ydelta * DAYSPERNYEAR;
1892		idays -= leapdays;
1893		y = newy;
1894	}
1895
1896#ifdef ckd_add
1897	if (ckd_add(&tmp->tm_year, y, -TM_YEAR_BASE)) {
1898	  errno = EOVERFLOW;
1899	  return NULL;
1900	}
1901#else
1902	if (!TYPE_SIGNED(time_t) && y < TM_YEAR_BASE) {
1903	  int signed_y = (int)y;
1904	  tmp->tm_year = signed_y - TM_YEAR_BASE;
1905	} else if ((!TYPE_SIGNED(time_t) || INT_MIN + TM_YEAR_BASE <= y)
1906		   && y - TM_YEAR_BASE <= INT_MAX)
1907	  tmp->tm_year = (int)(y - TM_YEAR_BASE);
1908	else {
1909	  errno = EOVERFLOW;
1910	  return NULL;
1911	}
1912#endif
1913	tmp->tm_yday = (int)idays;
1914	/*
1915	** The "extra" mods below avoid overflow problems.
1916	*/
1917	tmp->tm_wday = (int)(TM_WDAY_BASE
1918			+ ((tmp->tm_year % DAYSPERWEEK)
1919			   * (DAYSPERNYEAR % DAYSPERWEEK))
1920			+ leaps_thru_end_of(y - 1)
1921			- leaps_thru_end_of(TM_YEAR_BASE - 1)
1922			+ idays);
1923	tmp->tm_wday %= DAYSPERWEEK;
1924	if (tmp->tm_wday < 0)
1925		tmp->tm_wday += DAYSPERWEEK;
1926	tmp->tm_hour = (int) (rem / SECSPERHOUR);
1927	rem %= SECSPERHOUR;
1928	tmp->tm_min = (int)(rem / SECSPERMIN);
1929	tmp->tm_sec = (int)(rem % SECSPERMIN);
1930
1931	/* Use "... ??:??:60" at the end of the localtime minute containing
1932	   the second just before the positive leap second.  */
1933	tmp->tm_sec += secs_since_posleap <= tmp->tm_sec;
1934
1935	ip = mon_lengths[isleap(y)];
1936	for (tmp->tm_mon = 0; idays >= ip[tmp->tm_mon]; ++(tmp->tm_mon))
1937		idays -= ip[tmp->tm_mon];
1938	tmp->tm_mday = (int)(idays + 1);
1939	tmp->tm_isdst = 0;
1940#ifdef TM_GMTOFF
1941	tmp->TM_GMTOFF = offset;
1942#endif /* defined TM_GMTOFF */
1943	return tmp;
1944}
1945
1946/*
1947** Adapted from code provided by Robert Elz, who writes:
1948**	The "best" way to do mktime I think is based on an idea of Bob
1949**	Kridle's (so its said...) from a long time ago.
1950**	It does a binary search of the time_t space. Since time_t's are
1951**	just 32 bits, its a max of 32 iterations (even at 64 bits it
1952**	would still be very reasonable).
1953*/
1954
1955#ifndef WRONG
1956# define WRONG ((time_t)-1)
1957#endif /* !defined WRONG */
1958
1959/*
1960** Normalize logic courtesy Paul Eggert.
1961*/
1962
1963static bool
1964increment_overflow(int *ip, int j)
1965{
1966#ifdef ckd_add
1967	return ckd_add(ip, *ip, j);
1968#else
1969	register int const	i = *ip;
1970
1971	/*
1972	** If i >= 0 there can only be overflow if i + j > INT_MAX
1973	** or if j > INT_MAX - i; given i >= 0, INT_MAX - i cannot overflow.
1974	** If i < 0 there can only be overflow if i + j < INT_MIN
1975	** or if j < INT_MIN - i; given i < 0, INT_MIN - i cannot overflow.
1976	*/
1977	if ((i >= 0) ? (j > INT_MAX - i) : (j < INT_MIN - i))
1978		return true;
1979	*ip += j;
1980	return false;
1981#endif
1982}
1983
1984static bool
1985increment_overflow32(int_fast32_t *const lp, int const m)
1986{
1987#ifdef ckd_add
1988	return ckd_add(lp, *lp, m);
1989#else
1990	register int_fast32_t const	l = *lp;
1991
1992	if ((l >= 0) ? (m > INT_FAST32_MAX - l) : (m < INT_FAST32_MIN - l))
1993		return true;
1994	*lp += m;
1995	return false;
1996#endif
1997}
1998
1999static bool
2000increment_overflow_time(__time_t *tp, int_fast32_t j)
2001{
2002#ifdef ckd_add
2003	return ckd_add(tp, *tp, j);
2004#else
2005	/*
2006	** This is like
2007	** 'if (! (TIME_T_MIN <= *tp + j && *tp + j <= TIME_T_MAX)) ...',
2008	** except that it does the right thing even if *tp + j would overflow.
2009	*/
2010	if (! (j < 0
2011	       ? (TYPE_SIGNED(time_t) ? TIME_T_MIN - j <= *tp : -1 - j < *tp)
2012	       : *tp <= TIME_T_MAX - j))
2013		return true;
2014	*tp += j;
2015	return false;
2016#endif
2017}
2018
2019static bool
2020normalize_overflow(int *const tensptr, int *const unitsptr, const int base)
2021{
2022	register int	tensdelta;
2023
2024	tensdelta = (*unitsptr >= 0) ?
2025		(*unitsptr / base) :
2026		(-1 - (-1 - *unitsptr) / base);
2027	*unitsptr -= tensdelta * base;
2028	return increment_overflow(tensptr, tensdelta);
2029}
2030
2031static bool
2032normalize_overflow32(int_fast32_t *tensptr, int *unitsptr, int base)
2033{
2034	register int	tensdelta;
2035
2036	tensdelta = (*unitsptr >= 0) ?
2037		(*unitsptr / base) :
2038		(-1 - (-1 - *unitsptr) / base);
2039	*unitsptr -= tensdelta * base;
2040	return increment_overflow32(tensptr, tensdelta);
2041}
2042
2043static int
2044tmcomp(register const struct tm *const atmp,
2045       register const struct tm *const btmp)
2046{
2047	register int	result;
2048
2049	if (atmp->tm_year != btmp->tm_year)
2050		return atmp->tm_year < btmp->tm_year ? -1 : 1;
2051	if ((result = (atmp->tm_mon - btmp->tm_mon)) == 0 &&
2052		(result = (atmp->tm_mday - btmp->tm_mday)) == 0 &&
2053		(result = (atmp->tm_hour - btmp->tm_hour)) == 0 &&
2054		(result = (atmp->tm_min - btmp->tm_min)) == 0)
2055			result = atmp->tm_sec - btmp->tm_sec;
2056	return result;
2057}
2058
2059/* Copy to *DEST from *SRC.  Copy only the members needed for mktime,
2060   as other members might not be initialized.  */
2061static void
2062mktmcpy(struct tm *dest, struct tm const *src)
2063{
2064  dest->tm_sec = src->tm_sec;
2065  dest->tm_min = src->tm_min;
2066  dest->tm_hour = src->tm_hour;
2067  dest->tm_mday = src->tm_mday;
2068  dest->tm_mon = src->tm_mon;
2069  dest->tm_year = src->tm_year;
2070  dest->tm_isdst = src->tm_isdst;
2071#if defined TM_GMTOFF && ! UNINIT_TRAP
2072  dest->TM_GMTOFF = src->TM_GMTOFF;
2073#endif
2074}
2075
2076static time_t
2077time2sub(struct tm *const tmp,
2078	 struct tm *(*funcp)(struct state const *, time_t const *,
2079			     int_fast32_t, struct tm *),
2080	 struct state const *sp,
2081	 const int_fast32_t offset,
2082	 bool *okayp,
2083	 bool do_norm_secs)
2084{
2085	register int			dir;
2086	register int			i, j;
2087	register int			saved_seconds;
2088	register int_fast32_t		li;
2089	register time_t			lo;
2090	register time_t			hi;
2091#ifdef NO_ERROR_IN_DST_GAP
2092	time_t				ilo;
2093#endif
2094	int_fast32_t			y;
2095	time_t				newt;
2096	time_t				t;
2097	struct tm			yourtm, mytm;
2098
2099	*okayp = false;
2100	mktmcpy(&yourtm, tmp);
2101
2102#ifdef NO_ERROR_IN_DST_GAP
2103again:
2104#endif
2105	if (do_norm_secs) {
2106		if (normalize_overflow(&yourtm.tm_min, &yourtm.tm_sec,
2107		    SECSPERMIN))
2108			goto out_of_range;
2109	}
2110	if (normalize_overflow(&yourtm.tm_hour, &yourtm.tm_min, MINSPERHOUR))
2111		goto out_of_range;
2112	if (normalize_overflow(&yourtm.tm_mday, &yourtm.tm_hour, HOURSPERDAY))
2113		goto out_of_range;
2114	y = yourtm.tm_year;
2115	if (normalize_overflow32(&y, &yourtm.tm_mon, MONSPERYEAR))
2116		goto out_of_range;
2117	/*
2118	** Turn y into an actual year number for now.
2119	** It is converted back to an offset from TM_YEAR_BASE later.
2120	*/
2121	if (increment_overflow32(&y, TM_YEAR_BASE))
2122		goto out_of_range;
2123	while (yourtm.tm_mday <= 0) {
2124		if (increment_overflow32(&y, -1))
2125			goto out_of_range;
2126		li = y + (1 < yourtm.tm_mon);
2127		yourtm.tm_mday += year_lengths[isleap(li)];
2128	}
2129	while (yourtm.tm_mday > DAYSPERLYEAR) {
2130		li = y + (1 < yourtm.tm_mon);
2131		yourtm.tm_mday -= year_lengths[isleap(li)];
2132		if (increment_overflow32(&y, 1))
2133			goto out_of_range;
2134	}
2135	for ( ; ; ) {
2136		i = mon_lengths[isleap(y)][yourtm.tm_mon];
2137		if (yourtm.tm_mday <= i)
2138			break;
2139		yourtm.tm_mday -= i;
2140		if (++yourtm.tm_mon >= MONSPERYEAR) {
2141			yourtm.tm_mon = 0;
2142			if (increment_overflow32(&y, 1))
2143				goto out_of_range;
2144		}
2145	}
2146#ifdef ckd_add
2147	if (ckd_add(&yourtm.tm_year, y, -TM_YEAR_BASE))
2148	  return WRONG;
2149#else
2150	if (increment_overflow32(&y, -TM_YEAR_BASE))
2151		goto out_of_range;
2152	if (! (INT_MIN <= y && y <= INT_MAX))
2153		goto out_of_range;
2154	yourtm.tm_year = (int)y;
2155#endif
2156	if (yourtm.tm_sec >= 0 && yourtm.tm_sec < SECSPERMIN)
2157		saved_seconds = 0;
2158	else if (yourtm.tm_year + TM_YEAR_BASE < EPOCH_YEAR) {
2159		/*
2160		** We can't set tm_sec to 0, because that might push the
2161		** time below the minimum representable time.
2162		** Set tm_sec to 59 instead.
2163		** This assumes that the minimum representable time is
2164		** not in the same minute that a leap second was deleted from,
2165		** which is a safer assumption than using 58 would be.
2166		*/
2167		if (increment_overflow(&yourtm.tm_sec, 1 - SECSPERMIN))
2168			goto out_of_range;
2169		saved_seconds = yourtm.tm_sec;
2170		yourtm.tm_sec = SECSPERMIN - 1;
2171	} else {
2172		saved_seconds = yourtm.tm_sec;
2173		yourtm.tm_sec = 0;
2174	}
2175	/*
2176	** Do a binary search (this works whatever time_t's type is).
2177	*/
2178	lo = TIME_T_MIN;
2179	hi = TIME_T_MAX;
2180#ifdef NO_ERROR_IN_DST_GAP
2181	ilo = lo;
2182#endif
2183	for ( ; ; ) {
2184		t = lo / 2 + hi / 2;
2185		if (t < lo)
2186			t = lo;
2187		else if (t > hi)
2188			t = hi;
2189		if (! funcp(sp, &t, offset, &mytm)) {
2190			/*
2191			** Assume that t is too extreme to be represented in
2192			** a struct tm; arrange things so that it is less
2193			** extreme on the next pass.
2194			*/
2195			dir = (t > 0) ? 1 : -1;
2196		} else	dir = tmcomp(&mytm, &yourtm);
2197		if (dir != 0) {
2198			if (t == lo) {
2199				if (t == TIME_T_MAX)
2200					goto out_of_range;
2201				++t;
2202				++lo;
2203			} else if (t == hi) {
2204				if (t == TIME_T_MIN)
2205					goto out_of_range;
2206				--t;
2207				--hi;
2208			}
2209#ifdef NO_ERROR_IN_DST_GAP
2210			if (ilo != lo && lo - 1 == hi && yourtm.tm_isdst < 0 &&
2211			    do_norm_secs) {
2212				for (i = sp->typecnt - 1; i >= 0; --i) {
2213					for (j = sp->typecnt - 1; j >= 0; --j) {
2214						time_t off;
2215						if (sp->ttis[j].tt_isdst ==
2216						    sp->ttis[i].tt_isdst)
2217							continue;
2218						if (ttunspecified(sp, j))
2219							continue;
2220						off = sp->ttis[j].tt_utoff -
2221						    sp->ttis[i].tt_utoff;
2222						yourtm.tm_sec += off < 0 ?
2223						    -off : off;
2224						goto again;
2225					}
2226				}
2227			}
2228#endif
2229			if (lo > hi)
2230				goto invalid;
2231			if (dir > 0)
2232				hi = t;
2233			else	lo = t;
2234			continue;
2235		}
2236#if defined TM_GMTOFF && ! UNINIT_TRAP
2237		if (mytm.TM_GMTOFF != yourtm.TM_GMTOFF
2238		    && (yourtm.TM_GMTOFF < 0
2239			? (-SECSPERDAY <= yourtm.TM_GMTOFF
2240			   && (mytm.TM_GMTOFF <=
2241			       /*CONSTCOND*/
2242			       (min(INT_FAST32_MAX, LONG_MAX)
2243				+ yourtm.TM_GMTOFF)))
2244			: (yourtm.TM_GMTOFF <= SECSPERDAY
2245			       /*CONSTCOND*/
2246			   && ((max(INT_FAST32_MIN, LONG_MIN)
2247				+ yourtm.TM_GMTOFF)
2248			       <= mytm.TM_GMTOFF)))) {
2249		  /* MYTM matches YOURTM except with the wrong UT offset.
2250		     YOURTM.TM_GMTOFF is plausible, so try it instead.
2251		     It's OK if YOURTM.TM_GMTOFF contains uninitialized data,
2252		     since the guess gets checked.  */
2253		  __time_t altt = t;
2254		  int_fast32_t diff = (int_fast32_t)
2255		      (mytm.TM_GMTOFF - yourtm.TM_GMTOFF);
2256		  if (!increment_overflow_time(&altt, diff)) {
2257		    struct tm alttm;
2258		    time_t xaltt = (time_t)altt;
2259		    if (funcp(sp, &xaltt, offset, &alttm)
2260			&& alttm.tm_isdst == mytm.tm_isdst
2261			&& alttm.TM_GMTOFF == yourtm.TM_GMTOFF
2262			&& tmcomp(&alttm, &yourtm) == 0) {
2263		      t = xaltt;
2264		      mytm = alttm;
2265		    }
2266		  }
2267		}
2268#endif
2269		if (yourtm.tm_isdst < 0 || mytm.tm_isdst == yourtm.tm_isdst)
2270			break;
2271		/*
2272		** Right time, wrong type.
2273		** Hunt for right time, right type.
2274		** It's okay to guess wrong since the guess
2275		** gets checked.
2276		*/
2277		if (sp == NULL)
2278			goto invalid;
2279		for (i = sp->typecnt - 1; i >= 0; --i) {
2280			if (sp->ttis[i].tt_isdst != yourtm.tm_isdst)
2281				continue;
2282			for (j = sp->typecnt - 1; j >= 0; --j) {
2283				if (sp->ttis[j].tt_isdst == yourtm.tm_isdst)
2284					continue;
2285				newt = (time_t)(t + sp->ttis[j].tt_utoff -
2286				    sp->ttis[i].tt_utoff);
2287				if (! funcp(sp, &newt, offset, &mytm))
2288					continue;
2289				if (tmcomp(&mytm, &yourtm) != 0)
2290					continue;
2291				if (mytm.tm_isdst != yourtm.tm_isdst)
2292					continue;
2293				/*
2294				** We have a match.
2295				*/
2296				t = newt;
2297				goto label;
2298			}
2299		}
2300		goto invalid;
2301	}
2302label:
2303	newt = t + saved_seconds;
2304	if ((newt < t) != (saved_seconds < 0))
2305		goto out_of_range;
2306	t = newt;
2307	if (funcp(sp, &t, offset, tmp)) {
2308		*okayp = true;
2309		return t;
2310	}
2311out_of_range:
2312	errno = EOVERFLOW;
2313	return WRONG;
2314invalid:
2315	errno = EINVAL;
2316	return WRONG;
2317}
2318
2319static time_t
2320time2(struct tm * const	tmp,
2321      struct tm *(*funcp)(struct state const *, time_t const *,
2322			  int_fast32_t, struct tm *),
2323      struct state const *sp,
2324      const int_fast32_t offset,
2325      bool *okayp)
2326{
2327	time_t	t;
2328
2329	/*
2330	** First try without normalization of seconds
2331	** (in case tm_sec contains a value associated with a leap second).
2332	** If that fails, try with normalization of seconds.
2333	*/
2334	t = time2sub(tmp, funcp, sp, offset, okayp, false);
2335	return *okayp ? t : time2sub(tmp, funcp, sp, offset, okayp, true);
2336}
2337
2338static time_t
2339time1(struct tm *const tmp,
2340      struct tm *(*funcp)(struct state const *, time_t const *,
2341			  int_fast32_t, struct tm *),
2342      struct state const *sp,
2343      const int_fast32_t offset)
2344{
2345	register time_t			t;
2346	register int			samei, otheri;
2347	register int			sameind, otherind;
2348	register int			i;
2349	register int			nseen;
2350	int				save_errno;
2351	char				seen[TZ_MAX_TYPES];
2352	unsigned char			types[TZ_MAX_TYPES];
2353	bool				okay;
2354
2355	if (tmp == NULL) {
2356		errno = EINVAL;
2357		return WRONG;
2358	}
2359	if (tmp->tm_isdst > 1)
2360		tmp->tm_isdst = 1;
2361	save_errno = errno;
2362	t = time2(tmp, funcp, sp, offset, &okay);
2363	if (okay) {
2364		errno = save_errno;
2365		return t;
2366	}
2367	if (tmp->tm_isdst < 0)
2368#ifdef PCTS
2369		/*
2370		** POSIX Conformance Test Suite code courtesy Grant Sullivan.
2371		*/
2372		tmp->tm_isdst = 0;	/* reset to std and try again */
2373#else
2374		return t;
2375#endif /* !defined PCTS */
2376	/*
2377	** We're supposed to assume that somebody took a time of one type
2378	** and did some math on it that yielded a "struct tm" that's bad.
2379	** We try to divine the type they started from and adjust to the
2380	** type they need.
2381	*/
2382	if (sp == NULL) {
2383		errno = EINVAL;
2384		return WRONG;
2385	}
2386	for (i = 0; i < sp->typecnt; ++i)
2387		seen[i] = false;
2388	nseen = 0;
2389	for (i = sp->timecnt - 1; i >= 0; --i)
2390		if (!seen[sp->types[i]] && !ttunspecified(sp, sp->types[i])) {
2391			seen[sp->types[i]] = true;
2392			types[nseen++] = sp->types[i];
2393		}
2394	for (sameind = 0; sameind < nseen; ++sameind) {
2395		samei = types[sameind];
2396		if (sp->ttis[samei].tt_isdst != tmp->tm_isdst)
2397			continue;
2398		for (otherind = 0; otherind < nseen; ++otherind) {
2399			otheri = types[otherind];
2400			if (sp->ttis[otheri].tt_isdst == tmp->tm_isdst)
2401				continue;
2402			tmp->tm_sec += (int)(sp->ttis[otheri].tt_utoff
2403					- sp->ttis[samei].tt_utoff);
2404			tmp->tm_isdst = !tmp->tm_isdst;
2405			t = time2(tmp, funcp, sp, offset, &okay);
2406			if (okay) {
2407				errno = save_errno;
2408				return t;
2409			}
2410			tmp->tm_sec -= (int)(sp->ttis[otheri].tt_utoff
2411					- sp->ttis[samei].tt_utoff);
2412			tmp->tm_isdst = !tmp->tm_isdst;
2413		}
2414	}
2415	errno = EOVERFLOW;
2416	return WRONG;
2417}
2418
2419static time_t
2420mktime_tzname(timezone_t sp, struct tm *tmp, bool setname)
2421{
2422  if (sp)
2423    return time1(tmp, localsub, sp, setname);
2424  else {
2425    gmtcheck();
2426    return time1(tmp, gmtsub, gmtptr, 0);
2427  }
2428}
2429
2430#if NETBSD_INSPIRED
2431
2432time_t
2433mktime_z(struct state *__restrict sp, struct tm *__restrict tmp)
2434{
2435  return mktime_tzname(sp, tmp, false);
2436}
2437
2438#endif
2439
2440time_t
2441mktime(struct tm *tmp)
2442{
2443  time_t t;
2444
2445  rwlock_wrlock(&__lcl_lock);
2446  tzset_unlocked();
2447  t = mktime_tzname(__lclptr, tmp, true);
2448  rwlock_unlock(&__lcl_lock);
2449  return t;
2450}
2451
2452#if STD_INSPIRED
2453/* This function is obsolescent and may disapper in future releases.
2454   Callers can instead use mktime.  */
2455time_t
2456timelocal_z(const timezone_t sp, struct tm *const tmp)
2457{
2458	if (tmp != NULL)
2459		tmp->tm_isdst = -1;	/* in case it wasn't initialized */
2460	return mktime_z(sp, tmp);
2461}
2462
2463time_t
2464timelocal(struct tm *tmp)
2465{
2466	if (tmp != NULL)
2467		tmp->tm_isdst = -1;	/* in case it wasn't initialized */
2468	return mktime(tmp);
2469}
2470#endif
2471
2472#ifndef EXTERN_TIMEOFF
2473# ifndef timeoff
2474#  define timeoff my_timeoff /* Don't collide with OpenBSD 7.4 <time.h>.  */
2475# endif
2476# define EXTERN_TIMEOFF static
2477#endif
2478
2479/* This function is obsolescent and may disapper in future releases.
2480   Callers can instead use mktime_z with a fixed-offset zone.  */
2481EXTERN_TIMEOFF time_t
2482timeoff(struct tm *tmp, long offset)
2483{
2484  if (tmp)
2485    tmp->tm_isdst = 0;
2486  gmtcheck();
2487  return time1(tmp, gmtsub, gmtptr, (int_fast32_t)offset);
2488}
2489
2490time_t
2491timegm(struct tm *tmp)
2492{
2493  time_t t;
2494  struct tm tmcpy;
2495  mktmcpy(&tmcpy, tmp);
2496  tmcpy.tm_wday = -1;
2497  t = timeoff(&tmcpy, 0);
2498  if (0 <= tmcpy.tm_wday)
2499    *tmp = tmcpy;
2500  return t;
2501}
2502
2503static int_fast32_t
2504leapcorr(struct state const *sp, __time_t t)
2505{
2506	register struct lsinfo const *	lp;
2507	register int			i;
2508
2509	i = sp->leapcnt;
2510	while (--i >= 0) {
2511		lp = &sp->lsis[i];
2512		if (t >= lp->ls_trans)
2513			return lp->ls_corr;
2514	}
2515	return 0;
2516}
2517
2518/* NETBSD_INSPIRED_EXTERN functions are exported to callers if
2519   NETBSD_INSPIRED is defined, and are private otherwise.  */
2520# if NETBSD_INSPIRED
2521#  define NETBSD_INSPIRED_EXTERN
2522# else
2523#  define NETBSD_INSPIRED_EXTERN static
2524# endif
2525
2526/*
2527** IEEE Std 1003.1 (POSIX) says that 536457599
2528** shall correspond to "Wed Dec 31 23:59:59 UTC 1986", which
2529** is not the case if we are accounting for leap seconds.
2530** So, we provide the following conversion routines for use
2531** when exchanging timestamps with POSIX conforming systems.
2532*/
2533
2534NETBSD_INSPIRED_EXTERN time_t
2535time2posix_z(timezone_t sp, time_t t)
2536{
2537  return (time_t)(t - leapcorr(sp, t));
2538}
2539
2540time_t
2541time2posix(time_t t)
2542{
2543  rwlock_wrlock(&__lcl_lock);
2544  if (!lcl_is_set)
2545    tzset_unlocked();
2546  if (__lclptr)
2547    t = (time_t)(t - leapcorr(__lclptr, t));
2548  rwlock_unlock(&__lcl_lock);
2549  return t;
2550}
2551
2552/*
2553** XXX--is the below the right way to conditionalize??
2554*/
2555
2556#if STD_INSPIRED
2557
2558NETBSD_INSPIRED_EXTERN time_t
2559posix2time_z(timezone_t sp, time_t t)
2560{
2561	time_t	x;
2562	time_t	y;
2563	/*
2564	** For a positive leap second hit, the result
2565	** is not unique. For a negative leap second
2566	** hit, the corresponding time doesn't exist,
2567	** so we return an adjacent second.
2568	*/
2569	x = (time_t)(t + leapcorr(sp, t));
2570	y = (time_t)(x - leapcorr(sp, x));
2571	if (y < t) {
2572		do {
2573			x++;
2574			y = (time_t)(x - leapcorr(sp, x));
2575		} while (y < t);
2576		x -= y != t;
2577	} else if (y > t) {
2578		do {
2579			--x;
2580			y = (time_t)(x - leapcorr(sp, x));
2581		} while (y > t);
2582		x += y != t;
2583	}
2584	return x;
2585}
2586
2587time_t
2588posix2time(time_t t)
2589{
2590  rwlock_wrlock(&__lcl_lock);
2591  if (!lcl_is_set)
2592    tzset_unlocked();
2593  if (__lclptr)
2594    t = posix2time_z(__lclptr, t);
2595  rwlock_unlock(&__lcl_lock);
2596  return t;
2597}
2598
2599#endif /* defined STD_INSPIRED */
2600