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