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