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