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