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