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