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