Home | History | Annotate | Line # | Download | only in time
      1 /*	$NetBSD: localtime.c,v 1.147 2025/01/31 22:08:18 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.147 2025/01/31 22:08:18 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 #include "namespace.h"
     27 #include <assert.h>
     28 #define LOCALTIME_IMPLEMENTATION
     29 #include "private.h"
     30 
     31 #include "tzfile.h"
     32 #include <fcntl.h>
     33 
     34 #if defined(__weak_alias)
     35 __weak_alias(daylight,_daylight)
     36 __weak_alias(tzname,_tzname)
     37 #endif
     38 
     39 #if HAVE_SYS_STAT_H
     40 # include <sys/stat.h>
     41 #endif
     42 #if !defined S_ISREG && defined S_IFREG
     43 /* Ancient UNIX or recent MS-Windows.  */
     44 # define S_ISREG(mode) (((mode) & S_IFMT) == S_IFREG)
     45 #endif
     46 
     47 #ifdef __NetBSD__
     48 #define lock() (rwlock_wrlock(&__lcl_lock), 0)
     49 #define unlock() rwlock_unlock(&__lcl_lock)
     50 #else
     51 #if defined THREAD_SAFE && THREAD_SAFE
     52 # include <pthread.h>
     53 static pthread_mutex_t locallock = PTHREAD_MUTEX_INITIALIZER;
     54 static int lock(void) { return pthread_mutex_lock(&locallock); }
     55 static void unlock(void) { pthread_mutex_unlock(&locallock); }
     56 #else
     57 static int lock(void) { return 0; }
     58 static void unlock(void) { }
     59 #endif
     60 #endif
     61 
     62 /* Unless intptr_t is missing, pacify gcc -Wcast-qual on char const * exprs.
     63    Use this carefully, as the casts disable type checking.
     64    This is a macro so that it can be used in static initializers.  */
     65 #ifdef INTPTR_MAX
     66 # define UNCONST(a) ((char *) (intptr_t) (a))
     67 #else
     68 # define UNCONST(a) ((char *) (a))
     69 #endif
     70 
     71 /* A signed type wider than int, so that we can add 1900 + tm_mon/12 to tm_year
     72    without overflow.  The static_assert checks that it is indeed wider
     73    than int; if this fails on your platform please let us know.  */
     74 #if INT_MAX < LONG_MAX
     75 typedef long iinntt;
     76 # define IINNTT_MIN LONG_MIN
     77 # define IINNTT_MAX LONG_MAX
     78 #elif INT_MAX < LLONG_MAX
     79 typedef long long iinntt;
     80 # define IINNTT_MIN LLONG_MIN
     81 # define IINNTT_MAX LLONG_MAX
     82 #else
     83 typedef intmax_t iinntt;
     84 # define IINNTT_MIN INTMAX_MIN
     85 # define IINNTT_MAX INTMAX_MAX
     86 #endif
     87 /*CONSTCOND*/
     88 static_assert(IINNTT_MIN < INT_MIN && INT_MAX < IINNTT_MAX);
     89 
     90 /* On platforms where offtime or mktime might overflow,
     91    strftime.c defines USE_TIMEX_T to be true and includes us.
     92    This tells us to #define time_t to an internal type timex_t that is
     93    wide enough so that strftime %s never suffers from integer overflow,
     94    and to #define offtime (if TM_GMTOFF is defined) or mktime (otherwise)
     95    to a static function that returns the redefined time_t.
     96    It also tells us to define only data and code needed
     97    to support the offtime or mktime variant.  */
     98 #ifndef USE_TIMEX_T
     99 # define USE_TIMEX_T false
    100 #endif
    101 #if USE_TIMEX_T
    102 # undef TIME_T_MIN
    103 # undef TIME_T_MAX
    104 # undef time_t
    105 # define time_t timex_t
    106 # if MKTIME_FITS_IN(LONG_MIN, LONG_MAX)
    107 typedef long timex_t;
    108 # define TIME_T_MIN LONG_MIN
    109 # define TIME_T_MAX LONG_MAX
    110 # elif MKTIME_FITS_IN(LLONG_MIN, LLONG_MAX)
    111 typedef long long timex_t;
    112 # define TIME_T_MIN LLONG_MIN
    113 # define TIME_T_MAX LLONG_MAX
    114 # else
    115 typedef intmax_t timex_t;
    116 # define TIME_T_MIN INTMAX_MIN
    117 # define TIME_T_MAX INTMAX_MAX
    118 # endif
    119 
    120 # ifdef TM_GMTOFF
    121 #  undef timeoff
    122 #  define timeoff timex_timeoff
    123 #  undef EXTERN_TIMEOFF
    124 # else
    125 #  undef mktime
    126 #  define mktime timex_mktime
    127 # endif
    128 #endif
    129 
    130 #ifndef TZ_ABBR_CHAR_SET
    131 # define TZ_ABBR_CHAR_SET \
    132 	"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789 :+-._"
    133 #endif /* !defined TZ_ABBR_CHAR_SET */
    134 
    135 #ifndef TZ_ABBR_ERR_CHAR
    136 # define TZ_ABBR_ERR_CHAR '_'
    137 #endif /* !defined TZ_ABBR_ERR_CHAR */
    138 
    139 /* Port to platforms that lack some O_* flags.  Unless otherwise
    140    specified, the flags are standardized by POSIX.  */
    141 
    142 #ifndef O_BINARY
    143 # define O_BINARY 0 /* MS-Windows */
    144 #endif
    145 #ifndef O_CLOEXEC
    146 # define O_CLOEXEC 0
    147 #endif
    148 #ifndef O_CLOFORK
    149 # define O_CLOFORK 0
    150 #endif
    151 #ifndef O_IGNORE_CTTY
    152 # define O_IGNORE_CTTY 0 /* GNU/Hurd */
    153 #endif
    154 #ifndef O_NOCTTY
    155 # define O_NOCTTY 0
    156 #endif
    157 
    158 #ifndef WILDABBR
    159 /*
    160 ** Someone might make incorrect use of a time zone abbreviation:
    161 **	1.	They might reference tzname[0] before calling tzset (explicitly
    162 **		or implicitly).
    163 **	2.	They might reference tzname[1] before calling tzset (explicitly
    164 **		or implicitly).
    165 **	3.	They might reference tzname[1] after setting to a time zone
    166 **		in which Daylight Saving Time is never observed.
    167 **	4.	They might reference tzname[0] after setting to a time zone
    168 **		in which Standard Time is never observed.
    169 **	5.	They might reference tm.TM_ZONE after calling offtime.
    170 ** What's best to do in the above cases is open to debate;
    171 ** for now, we just set things up so that in any of the five cases
    172 ** WILDABBR is used. Another possibility: initialize tzname[0] to the
    173 ** string "tzname[0] used before set", and similarly for the other cases.
    174 ** And another: initialize tzname[0] to "ERA", with an explanation in the
    175 ** manual page of what this "time zone abbreviation" means (doing this so
    176 ** that tzname[0] has the "normal" length of three characters).
    177 */
    178 # define WILDABBR "   "
    179 #endif /* !defined WILDABBR */
    180 
    181 static const char	wildabbr[] = WILDABBR;
    182 
    183 static char const etc_utc[] = "Etc/UTC";
    184 
    185 #if !USE_TIMEX_T || defined TM_ZONE || !defined TM_GMTOFF
    186 static char const *utc = etc_utc + sizeof "Etc/" - 1;
    187 #endif
    188 
    189 /*
    190 ** The DST rules to use if TZ has no rules and we can't load TZDEFRULES.
    191 ** Default to US rules as of 2017-05-07.
    192 ** POSIX does not specify the default DST rules;
    193 ** for historical reasons, US rules are a common default.
    194 */
    195 #ifndef TZDEFRULESTRING
    196 # define TZDEFRULESTRING ",M3.2.0,M11.1.0"
    197 #endif
    198 
    199 typedef int_fast64_t __time_t;
    200 
    201 /* Limit to time zone abbreviation length in proleptic TZ strings.
    202    This is distinct from TZ_MAX_CHARS, which limits TZif file contents.
    203    It defaults to 254, not 255, so that desigidx_type can be an unsigned char.
    204    unsigned char suffices for TZif files, so the only reason to increase
    205    TZNAME_MAXIMUM is to support TZ strings specifying abbreviations
    206    longer than 254 bytes.  There is little reason to do that, though,
    207    as strings that long are hardly "abbreviations".  */
    208 #ifndef TZNAME_MAXIMUM
    209 # define TZNAME_MAXIMUM 254
    210 #endif
    211 
    212 #if TZNAME_MAXIMUM < UCHAR_MAX
    213 typedef unsigned char desigidx_type;
    214 #elif TZNAME_MAXIMUM < INT_MAX
    215 typedef int desigidx_type;
    216 #elif TZNAME_MAXIMUM < PTRDIFF_MAX
    217 typedef ptrdiff_t desigidx_type;
    218 #else
    219 # error "TZNAME_MAXIMUM too large"
    220 #endif
    221 
    222 struct ttinfo {				/* time type information */
    223 	int_least32_t	tt_utoff;	/* UT offset in seconds */
    224 	desigidx_type	tt_desigidx;	/* abbreviation list index */
    225 	bool		tt_isdst;	/* used to set tm_isdst */
    226 	bool		tt_ttisstd;	/* transition is std time */
    227 	bool		tt_ttisut;	/* transition is UT */
    228 };
    229 
    230 struct lsinfo {				/* leap second information */
    231 	__time_t	ls_trans;	/* transition time */
    232 	int_fast32_t	ls_corr;	/* correction to apply */
    233 };
    234 
    235 /* This abbreviation means local time is unspecified.  */
    236 static char const UNSPEC[] = "-00";
    237 
    238 /* How many extra bytes are needed at the end of struct state's chars array.
    239    This needs to be at least 1 for null termination in case the input
    240    data isn't properly terminated, and it also needs to be big enough
    241    for ttunspecified to work without crashing.  */
    242 enum { CHARS_EXTRA = max(sizeof UNSPEC, 2) - 1 };
    243 
    244 #define state __state
    245 /* A representation of the contents of a TZif file.  Ideally this
    246    would have no size limits; the following sizes should suffice for
    247    practical use.  This struct should not be too large, as instances
    248    are put on the stack and stacks are relatively small on some platforms.
    249    See tzfile.h for more about the sizes.  */
    250 struct state {
    251 	int		leapcnt;
    252 	int		timecnt;
    253 	int		typecnt;
    254 	int		charcnt;
    255 	bool		goback;
    256 	bool		goahead;
    257 	__time_t	ats[TZ_MAX_TIMES];
    258 	unsigned char	types[TZ_MAX_TIMES];
    259 	struct ttinfo	ttis[TZ_MAX_TYPES];
    260 	/*CONSTCOND*/
    261 	char chars[max(max(TZ_MAX_CHARS + CHARS_EXTRA, sizeof "UTC"),
    262 		       2 * (TZNAME_MAXIMUM + 1))];
    263 	struct lsinfo	lsis[TZ_MAX_LEAPS];
    264 };
    265 
    266 enum r_type {
    267   JULIAN_DAY,		/* Jn = Julian day */
    268   DAY_OF_YEAR,		/* n = day of year */
    269   MONTH_NTH_DAY_OF_WEEK	/* Mm.n.d = month, week, day of week */
    270 };
    271 
    272 struct rule {
    273 	enum r_type	r_type;		/* type of rule */
    274 	int		r_day;		/* day number of rule */
    275 	int		r_week;		/* week number of rule */
    276 	int		r_mon;		/* month number of rule */
    277 	int_fast32_t	r_time;		/* transition time of rule */
    278 };
    279 
    280 static struct tm *gmtsub(struct state const *, time_t const *, int_fast32_t,
    281 			 struct tm *);
    282 static bool increment_overflow(int *, int);
    283 static bool increment_overflow_time(__time_t *, int_fast32_t);
    284 static int_fast32_t leapcorr(struct state const *, __time_t);
    285 static struct tm *timesub(time_t const *, int_fast32_t, struct state const *,
    286 			  struct tm *);
    287 static bool tzparse(char const *, struct state *, struct state const *);
    288 
    289 #ifndef ALL_STATE
    290 static struct state *  gmtptr;
    291 #else
    292 static struct state	gmtmem;
    293 static struct state *const gmtptr = &gmtmem;
    294 #endif
    295 
    296 #ifndef TZ_STRLEN_MAX
    297 # define TZ_STRLEN_MAX 255
    298 #endif /* !defined TZ_STRLEN_MAX */
    299 
    300 #if !USE_TIMEX_T || !defined TM_GMTOFF
    301 static char		lcl_TZname[TZ_STRLEN_MAX + 1];
    302 static int		lcl_is_set;
    303 #endif
    304 
    305 
    306 #if !defined(__LIBC12_SOURCE__)
    307 # ifndef ALL_STATE
    308 struct state * __lclptr;
    309 # else
    310 static struct state	lclmem;
    311 struct state *const __lclptr = &lclmem;
    312 # endif
    313 # ifdef _REENTRANT
    314 rwlock_t __lcl_lock = RWLOCK_INITIALIZER;
    315 # endif
    316 #endif
    317 
    318 /*
    319 ** Section 4.12.3 of X3.159-1989 requires that
    320 **	Except for the strftime function, these functions [asctime,
    321 **	ctime, gmtime, localtime] return values in one of two static
    322 **	objects: a broken-down time structure and an array of char.
    323 ** Thanks to Paul Eggert for noting this.
    324 **
    325 ** Although this requirement was removed in C99 it is still present in POSIX.
    326 ** Follow the requirement if SUPPORT_C89, even though this is more likely to
    327 ** trigger latent bugs in programs.
    328 */
    329 
    330 #if !USE_TIMEX_T
    331 
    332 # if SUPPORT_C89
    333 static struct tm	tm;
    334 # endif
    335 
    336 # if 2 <= HAVE_TZNAME + TZ_TIME_T || defined(__NetBSD__)
    337 #  if !defined(__LIBC12_SOURCE__)
    338 __aconst char *tzname[2] = {
    339 	(__aconst char *) UNCONST(wildabbr),
    340 	(__aconst char *) UNCONST(wildabbr),
    341 };
    342 #  else
    343 
    344 extern __aconst char *	tzname[2];
    345 
    346 #  endif /* __LIBC12_SOURCE__ */
    347 # endif
    348 
    349 # if 2 <= USG_COMPAT + TZ_TIME_T || defined(__NetBSD__)
    350 #  if !defined(__LIBC12_SOURCE__)
    351 long 			timezone = 0;
    352 int			daylight = 0;
    353 #  endif /* __LIBC12_SOURCE__ */
    354 # endif /* 2<= USG_COMPAT + TZ_TIME_T */
    355 
    356 # if 2 <= ALTZONE + TZ_TIME_T
    357 long			altzone = 0;
    358 # endif /* 2 <= ALTZONE + TZ_TIME_T */
    359 #endif
    360 
    361 /* Initialize *S to a value based on UTOFF, ISDST, and DESIGIDX.  */
    362 static void
    363 init_ttinfo(struct ttinfo *s, int_fast32_t utoff, bool isdst,
    364 	    desigidx_type desigidx)
    365 {
    366   s->tt_utoff = (int_least32_t)utoff;
    367   s->tt_isdst = isdst;
    368   s->tt_desigidx = desigidx;
    369   s->tt_ttisstd = false;
    370   s->tt_ttisut = false;
    371 }
    372 
    373 /* Return true if SP's time type I does not specify local time.  */
    374 static bool
    375 ttunspecified(struct state const *sp, int i)
    376 {
    377   char const *abbr = &sp->chars[sp->ttis[i].tt_desigidx];
    378   /* memcmp is likely faster than strcmp, and is safe due to CHARS_EXTRA.  */
    379   return memcmp(abbr, UNSPEC, sizeof UNSPEC) == 0;
    380 }
    381 
    382 static int_fast32_t
    383 detzcode(const char *const codep)
    384 {
    385 	register int_fast32_t	result;
    386 	register int		i;
    387 	int_fast32_t one = 1;
    388 	int_fast32_t halfmaxval = one << (32 - 2);
    389 	int_fast32_t maxval = halfmaxval - 1 + halfmaxval;
    390 	int_fast32_t minval = -1 - maxval;
    391 
    392 	result = codep[0] & 0x7f;
    393 	for (i = 1; i < 4; ++i)
    394 		result = (result << 8) | (codep[i] & 0xff);
    395 
    396 	if (codep[0] & 0x80) {
    397 	  /* Do two's-complement negation even on non-two's-complement machines.
    398 	     If the result would be minval - 1, return minval.  */
    399 	  result -= !TWOS_COMPLEMENT(int_fast32_t) && result != 0;
    400 	  result += minval;
    401 	}
    402 	return result;
    403 }
    404 
    405 static int_fast64_t
    406 detzcode64(const char *const codep)
    407 {
    408 	register int_fast64_t result;
    409 	register int	i;
    410 	int_fast64_t one = 1;
    411 	int_fast64_t halfmaxval = one << (64 - 2);
    412 	int_fast64_t maxval = halfmaxval - 1 + halfmaxval;
    413 	int_fast64_t minval = -TWOS_COMPLEMENT(int_fast64_t) - maxval;
    414 
    415 	result = codep[0] & 0x7f;
    416 	for (i = 1; i < 8; ++i)
    417 		result = (result << 8) | (codep[i] & 0xff);
    418 
    419 	if (codep[0] & 0x80) {
    420 	  /* Do two's-complement negation even on non-two's-complement machines.
    421 	     If the result would be minval - 1, return minval.  */
    422 	  result -= !TWOS_COMPLEMENT(int_fast64_t) && result != 0;
    423 	  result += minval;
    424 	}
    425 	return result;
    426 }
    427 
    428 #include <stdio.h>
    429 
    430 const char *
    431 tzgetname(const timezone_t sp, int isdst)
    432 {
    433 	int i;
    434 	const char *name = NULL;
    435 	for (i = 0; i < sp->typecnt; ++i) {
    436 		const struct ttinfo *const ttisp = &sp->ttis[i];
    437 		if (ttisp->tt_isdst == isdst)
    438 			name = &sp->chars[ttisp->tt_desigidx];
    439 	}
    440 	if (name != NULL)
    441 		return name;
    442 	errno = ESRCH;
    443 	return NULL;
    444 }
    445 
    446 long
    447 tzgetgmtoff(const timezone_t sp, int isdst)
    448 {
    449 	int i;
    450 	long l = -1;
    451 	for (i = 0; i < sp->typecnt; ++i) {
    452 		const struct ttinfo *const ttisp = &sp->ttis[i];
    453 
    454 		if (ttisp->tt_isdst == isdst) {
    455 			l = ttisp->tt_utoff;
    456 		}
    457 	}
    458 	if (l == -1)
    459 		errno = ESRCH;
    460 	return l;
    461 }
    462 
    463 #if !USE_TIMEX_T || !defined TM_GMTOFF
    464 
    465 static void
    466 update_tzname_etc(struct state const *sp, struct ttinfo const *ttisp)
    467 {
    468 # if HAVE_TZNAME
    469   tzname[ttisp->tt_isdst] = UNCONST(&sp->chars[ttisp->tt_desigidx]);
    470 # endif
    471 # if USG_COMPAT
    472   if (!ttisp->tt_isdst)
    473     timezone = - ttisp->tt_utoff;
    474 # endif
    475 # if ALTZONE
    476   if (ttisp->tt_isdst)
    477     altzone = - ttisp->tt_utoff;
    478 # endif
    479 }
    480 
    481 /* If STDDST_MASK indicates that SP's TYPE provides useful info,
    482    update tzname, timezone, and/or altzone and return STDDST_MASK,
    483    diminished by the provided info if it is a specified local time.
    484    Otherwise, return STDDST_MASK.  See settzname for STDDST_MASK.  */
    485 static int
    486 may_update_tzname_etc(int stddst_mask, struct state *sp, int type)
    487 {
    488   struct ttinfo *ttisp = &sp->ttis[type];
    489   int this_bit = 1 << ttisp->tt_isdst;
    490   if (stddst_mask & this_bit) {
    491     update_tzname_etc(sp, ttisp);
    492     if (!ttunspecified(sp, type))
    493       return stddst_mask & ~this_bit;
    494   }
    495   return stddst_mask;
    496 }
    497 
    498 static void
    499 settzname(void)
    500 {
    501 	register timezone_t const	sp = __lclptr;
    502 	register int			i;
    503 
    504 	/* If STDDST_MASK & 1 we need info about a standard time.
    505 	   If STDDST_MASK & 2 we need info about a daylight saving time.
    506 	   When STDDST_MASK becomes zero we can stop looking.  */
    507 	int stddst_mask = 0;
    508 
    509 # if HAVE_TZNAME
    510 	tzname[0] = tzname[1] = UNCONST(sp ? wildabbr : utc);
    511 	stddst_mask = 3;
    512 # endif
    513 # if USG_COMPAT
    514 	timezone = 0;
    515 	stddst_mask = 3;
    516 # endif
    517 # if ALTZONE
    518 	altzone = 0;
    519 	stddst_mask |= 2;
    520 # endif
    521 	/*
    522 	** And to get the latest time zone abbreviations into tzname. . .
    523 	*/
    524 	if (sp) {
    525 	  for (i = sp->timecnt - 1; stddst_mask && 0 <= i; i--)
    526 	    stddst_mask = may_update_tzname_etc(stddst_mask, sp, sp->types[i]);
    527 	  for (i = sp->typecnt - 1; stddst_mask && 0 <= i; i--)
    528 	    stddst_mask = may_update_tzname_etc(stddst_mask, sp, i);
    529 	}
    530 
    531 # if USG_COMPAT
    532 	daylight = (unsigned int)stddst_mask >> 1 ^ 1;
    533 # endif
    534 }
    535 
    536 /* Replace bogus characters in time zone abbreviations.
    537    Return 0 on success, an errno value if a time zone abbreviation is
    538    too long.  */
    539 static int
    540 scrub_abbrs(struct state *sp)
    541 {
    542 	int i;
    543 
    544 	/* Reject overlong abbreviations.  */
    545 	for (i = 0; i < sp->charcnt - (TZNAME_MAXIMUM + 1); ) {
    546 	  int len = (int)strlen(&sp->chars[i]);
    547 	  if (TZNAME_MAXIMUM < len)
    548 	    return EOVERFLOW;
    549 	  i += len + 1;
    550 	}
    551 
    552 	/* Replace bogus characters.  */
    553 	for (i = 0; i < sp->charcnt; ++i)
    554 		if (strchr(TZ_ABBR_CHAR_SET, sp->chars[i]) == NULL)
    555 			sp->chars[i] = TZ_ABBR_ERR_CHAR;
    556 
    557 	return 0;
    558 }
    559 
    560 #endif
    561 
    562 /* Input buffer for data read from a compiled tz file.  */
    563 union input_buffer {
    564   /* The first part of the buffer, interpreted as a header.  */
    565   struct tzhead tzhead;
    566 
    567   /* The entire buffer.  Ideally this would have no size limits;
    568      the following should suffice for practical use.  */
    569   char buf[2 * sizeof(struct tzhead) + 2 * sizeof(struct state)
    570 	   + 4 * TZ_MAX_TIMES];
    571 };
    572 
    573 /* TZDIR with a trailing '/' rather than a trailing '\0'.  */
    574 static char const tzdirslash[sizeof TZDIR] = TZDIR "/";
    575 
    576 /* Local storage needed for 'tzloadbody'.  */
    577 union local_storage {
    578   /* The results of analyzing the file's contents after it is opened.  */
    579   struct file_analysis {
    580     /* The input buffer.  */
    581     union input_buffer u;
    582 
    583     /* A temporary state used for parsing a TZ string in the file.  */
    584     struct state st;
    585   } u;
    586 
    587   /* The name of the file to be opened.  Ideally this would have no
    588      size limits, to support arbitrarily long Zone names.
    589      Limiting Zone names to 1024 bytes should suffice for practical use.
    590      However, there is no need for this to be smaller than struct
    591      file_analysis as that struct is allocated anyway, as the other
    592      union member.  */
    593   char fullname[max(sizeof(struct file_analysis), sizeof tzdirslash + 1024)];
    594 };
    595 
    596 /* These tzload flags can be ORed together, and fit into 'char'.  */
    597 enum { TZLOAD_FROMENV = 1 }; /* The TZ string came from the environment.  */
    598 enum { TZLOAD_TZSTRING = 2 }; /* Read any newline-surrounded TZ string.  */
    599 
    600 /* Load tz data from the file named NAME into *SP.  Respect TZLOADFLAGS.
    601    Use *LSP for temporary storage.  Return 0 on
    602    success, an errno value on failure.  */
    603 static int
    604 tzloadbody(char const *name, struct state *sp, char tzloadflags,
    605 	   union local_storage *lsp)
    606 {
    607 	register int			i;
    608 	register int			fid;
    609 	register int			stored;
    610 	register ssize_t		nread;
    611 	register bool doaccess;
    612 	register union input_buffer *up = &lsp->u.u;
    613 	register size_t tzheadsize = sizeof(struct tzhead);
    614 
    615 	sp->goback = sp->goahead = false;
    616 
    617 	if (! name) {
    618 		name = TZDEFAULT;
    619 		if (! name)
    620 		  return EINVAL;
    621 	}
    622 
    623 	if (name[0] == ':')
    624 		++name;
    625 #ifdef SUPPRESS_TZDIR
    626 	/* Do not prepend TZDIR.  This is intended for specialized
    627 	   applications only, due to its security implications.  */
    628 	doaccess = true;
    629 #else
    630 	doaccess = name[0] == '/';
    631 #endif
    632 	if (!doaccess) {
    633 		char const *dot;
    634 		if (sizeof lsp->fullname - sizeof tzdirslash <= strlen(name))
    635 		  return ENAMETOOLONG;
    636 
    637 		/* Create a string "TZDIR/NAME".  Using sprintf here
    638 		   would pull in stdio (and would fail if the
    639 		   resulting string length exceeded INT_MAX!).  */
    640 		memcpy(lsp->fullname, tzdirslash, sizeof tzdirslash);
    641 		strcpy(lsp->fullname + sizeof tzdirslash, name);
    642 
    643 		/* Set doaccess if NAME contains a ".." file name
    644 		   component, as such a name could read a file outside
    645 		   the TZDIR virtual subtree.  */
    646 		for (dot = name; (dot = strchr(dot, '.')); dot++)
    647 		  if ((dot == name || dot[-1] == '/') && dot[1] == '.'
    648 		      && (dot[2] == '/' || !dot[2])) {
    649 		    doaccess = true;
    650 		    break;
    651 		  }
    652 
    653 		name = lsp->fullname;
    654 	}
    655 	if (doaccess && (tzloadflags & TZLOAD_FROMENV)) {
    656 	  /* Check for security violations and for devices whose mere
    657 	     opening could have unwanted side effects.  Although these
    658 	     checks are racy, they're better than nothing and there is
    659 	     no portable way to fix the races.  */
    660 	  if (access(name, R_OK) < 0)
    661 	    return errno;
    662 #if 0 /* handle with O_REGULAR instead */
    663 #ifdef S_ISREG
    664 	  {
    665 	    struct stat st;
    666 	    if (stat(name, &st) < 0)
    667 	      return errno;
    668 	    if (!S_ISREG(st.st_mode))
    669 	      return EINVAL;
    670 	  }
    671 #endif
    672 #endif
    673 	}
    674 	fid = open(name, (O_RDONLY | O_BINARY | O_CLOEXEC | O_CLOFORK
    675 			  | O_IGNORE_CTTY | O_NOCTTY | O_REGULAR));
    676 	if (fid < 0)
    677 	  return errno;
    678 
    679 	nread = read(fid, up->buf, sizeof up->buf);
    680 	if (nread < (ssize_t)tzheadsize) {
    681 	  int err = nread < 0 ? errno : EINVAL;
    682 	  close(fid);
    683 	  return err;
    684 	}
    685 	if (close(fid) < 0)
    686 	  return errno;
    687 	for (stored = 4; stored <= 8; stored *= 2) {
    688 	    char version = up->tzhead.tzh_version[0];
    689 	    bool skip_datablock = stored == 4 && version;
    690 	    int_fast32_t datablock_size;
    691 	    int_fast32_t ttisstdcnt = detzcode(up->tzhead.tzh_ttisstdcnt);
    692 	    int_fast32_t ttisutcnt = detzcode(up->tzhead.tzh_ttisutcnt);
    693 	    int_fast64_t prevtr = -1;
    694 	    int_fast32_t prevcorr = 0;
    695 	    int_fast32_t leapcnt = detzcode(up->tzhead.tzh_leapcnt);
    696 	    int_fast32_t timecnt = detzcode(up->tzhead.tzh_timecnt);
    697 	    int_fast32_t typecnt = detzcode(up->tzhead.tzh_typecnt);
    698 	    int_fast32_t charcnt = detzcode(up->tzhead.tzh_charcnt);
    699 	    char const *p = up->buf + tzheadsize;
    700 	    /* Although tzfile(5) currently requires typecnt to be nonzero,
    701 	       support future formats that may allow zero typecnt
    702 	       in files that have a TZ string and no transitions.  */
    703 	    if (! (0 <= leapcnt && leapcnt < TZ_MAX_LEAPS
    704 		   && 0 <= typecnt && typecnt < TZ_MAX_TYPES
    705 		   && 0 <= timecnt && timecnt < TZ_MAX_TIMES
    706 		   && 0 <= charcnt && charcnt < TZ_MAX_CHARS
    707 		   && 0 <= ttisstdcnt && ttisstdcnt < TZ_MAX_TYPES
    708 		   && 0 <= ttisutcnt && ttisutcnt < TZ_MAX_TYPES))
    709 	      return EINVAL;
    710 	    datablock_size
    711 		    = (timecnt * stored		/* ats */
    712 		       + timecnt		/* types */
    713 		       + typecnt * 6		/* ttinfos */
    714 		       + charcnt		/* chars */
    715 		       + leapcnt * (stored + 4)	/* lsinfos */
    716 		       + ttisstdcnt		/* ttisstds */
    717 		       + ttisutcnt);		/* ttisuts */
    718 	    if (nread < (ssize_t)(tzheadsize + datablock_size))
    719 	      return EINVAL;
    720 	    if (skip_datablock)
    721 		p += datablock_size;
    722 	    else {
    723 		if (! ((ttisstdcnt == typecnt || ttisstdcnt == 0)
    724 		       && (ttisutcnt == typecnt || ttisutcnt == 0)))
    725 		  return EINVAL;
    726 
    727 		sp->leapcnt = (int)leapcnt;
    728 		sp->timecnt = (int)timecnt;
    729 		sp->typecnt = (int)typecnt;
    730 		sp->charcnt = (int)charcnt;
    731 
    732 		/* Read transitions, discarding those out of time_t range.
    733 		   But pretend the last transition before TIME_T_MIN
    734 		   occurred at TIME_T_MIN.  */
    735 		timecnt = 0;
    736 		for (i = 0; i < sp->timecnt; ++i) {
    737 			int_fast64_t at
    738 			  = stored == 4 ? detzcode(p) : detzcode64(p);
    739 			sp->types[i] = at <= TIME_T_MAX;
    740 			if (sp->types[i]) {
    741 			  time_t attime
    742 			    = ((TYPE_SIGNED(time_t) ? at < TIME_T_MIN : at < 0)
    743 			       ? TIME_T_MIN : (time_t)at);
    744 			  if (timecnt && attime <= sp->ats[timecnt - 1]) {
    745 			    if (attime < sp->ats[timecnt - 1])
    746 			      return EINVAL;
    747 			    sp->types[i - 1] = 0;
    748 			    timecnt--;
    749 			  }
    750 			  sp->ats[timecnt++] = attime;
    751 			}
    752 			p += stored;
    753 		}
    754 
    755 		timecnt = 0;
    756 		for (i = 0; i < sp->timecnt; ++i) {
    757 			unsigned char typ = *p++;
    758 			if (sp->typecnt <= typ)
    759 			  return EINVAL;
    760 			if (sp->types[i])
    761 				sp->types[timecnt++] = typ;
    762 		}
    763 		sp->timecnt = (int)timecnt;
    764 		for (i = 0; i < sp->typecnt; ++i) {
    765 			register struct ttinfo *	ttisp;
    766 			unsigned char isdst, desigidx;
    767 
    768 			ttisp = &sp->ttis[i];
    769 			ttisp->tt_utoff = (int_least32_t)detzcode(p);
    770 			p += 4;
    771 			isdst = *p++;
    772 			if (! (isdst < 2))
    773 			  return EINVAL;
    774 			ttisp->tt_isdst = isdst;
    775 			desigidx = *p++;
    776 			if (! (desigidx < sp->charcnt))
    777 			  return EINVAL;
    778 			ttisp->tt_desigidx = desigidx;
    779 		}
    780 		for (i = 0; i < sp->charcnt; ++i)
    781 			sp->chars[i] = *p++;
    782 		/* Ensure '\0'-terminated, and make it safe to call
    783 		   ttunspecified later.  */
    784 		memset(&sp->chars[i], 0, CHARS_EXTRA);
    785 
    786 		/* Read leap seconds, discarding those out of time_t range.  */
    787 		leapcnt = 0;
    788 		for (i = 0; i < sp->leapcnt; ++i) {
    789 		  int_fast64_t tr = stored == 4 ? detzcode(p) : detzcode64(p);
    790 		  int_fast32_t corr = detzcode(p + stored);
    791 		  p += stored + 4;
    792 
    793 		  /* Leap seconds cannot occur before the Epoch,
    794 		     or out of order.  */
    795 		  if (tr <= prevtr)
    796 		    return EINVAL;
    797 
    798 		  /* To avoid other botches in this code, each leap second's
    799 		     correction must differ from the previous one's by 1
    800 		     second or less, except that the first correction can be
    801 		     any value; these requirements are more generous than
    802 		     RFC 9636, to allow future RFC extensions.  */
    803 		  if (! (i == 0
    804 			 || (prevcorr < corr
    805 			     ? corr == prevcorr + 1
    806 			     : (corr == prevcorr
    807 				|| corr == prevcorr - 1))))
    808 		    return EINVAL;
    809 		  prevtr = tr;
    810 		  prevcorr = corr;
    811 
    812 		  if (tr <= TIME_T_MAX) {
    813 		    sp->lsis[leapcnt].ls_trans = (time_t)tr;
    814 		    sp->lsis[leapcnt].ls_corr = corr;
    815 		    leapcnt++;
    816 		  }
    817 		}
    818 		sp->leapcnt = (int)leapcnt;
    819 
    820 		for (i = 0; i < sp->typecnt; ++i) {
    821 			register struct ttinfo *	ttisp;
    822 
    823 			ttisp = &sp->ttis[i];
    824 			if (ttisstdcnt == 0)
    825 				ttisp->tt_ttisstd = false;
    826 			else {
    827 				if (*p != true && *p != false)
    828 				  return EINVAL;
    829 				ttisp->tt_ttisstd = *p++;
    830 			}
    831 		}
    832 		for (i = 0; i < sp->typecnt; ++i) {
    833 			register struct ttinfo *	ttisp;
    834 
    835 			ttisp = &sp->ttis[i];
    836 			if (ttisutcnt == 0)
    837 				ttisp->tt_ttisut = false;
    838 			else {
    839 				if (*p != true && *p != false)
    840 						return EINVAL;
    841 				ttisp->tt_ttisut = *p++;
    842 			}
    843 		}
    844 	    }
    845 
    846 	    nread -= p - up->buf;
    847 	    memmove(up->buf, p, (size_t)nread);
    848 
    849 	    /* If this is an old file, we're done.  */
    850 	    if (!version)
    851 	      break;
    852 	}
    853 	if ((tzloadflags & TZLOAD_TZSTRING) && nread > 2 &&
    854 		up->buf[0] == '\n' && up->buf[nread - 1] == '\n' &&
    855 		sp->typecnt + 2 <= TZ_MAX_TYPES) {
    856 			struct state	*ts = &lsp->u.st;
    857 
    858 			up->buf[nread - 1] = '\0';
    859 			if (tzparse(&up->buf[1], ts, sp)) {
    860 
    861 			  /* Attempt to reuse existing abbreviations.
    862 			     Without this, America/Anchorage would be right on
    863 			     the edge after 2037 when TZ_MAX_CHARS is 50, as
    864 			     sp->charcnt equals 40 (for LMT AST AWT APT AHST
    865 			     AHDT YST AKDT AKST) and ts->charcnt equals 10
    866 			     (for AKST AKDT).  Reusing means sp->charcnt can
    867 			     stay 40 in this example.  */
    868 			  int gotabbr = 0;
    869 			  int charcnt = sp->charcnt;
    870 			  for (i = 0; i < ts->typecnt; i++) {
    871 			    char *tsabbr = ts->chars + ts->ttis[i].tt_desigidx;
    872 			    int j;
    873 			    for (j = 0; j < charcnt; j++)
    874 			      if (strcmp(sp->chars + j, tsabbr) == 0) {
    875 				ts->ttis[i].tt_desigidx = j;
    876 				gotabbr++;
    877 				break;
    878 			      }
    879 			    if (! (j < charcnt)) {
    880 			      size_t tsabbrlen = strlen(tsabbr);
    881 			      if (j + tsabbrlen < TZ_MAX_CHARS) {
    882 				strcpy(sp->chars + j, tsabbr);
    883 				charcnt = (int)(j + tsabbrlen + 1);
    884 				ts->ttis[i].tt_desigidx = j;
    885 				gotabbr++;
    886 			      }
    887 			    }
    888 			  }
    889 			  if (gotabbr == ts->typecnt) {
    890 			    sp->charcnt = charcnt;
    891 
    892 			    /* Ignore any trailing, no-op transitions generated
    893 			       by zic as they don't help here and can run afoul
    894 			       of bugs in zic 2016j or earlier.  */
    895 			    while (1 < sp->timecnt
    896 				   && (sp->types[sp->timecnt - 1]
    897 				       == sp->types[sp->timecnt - 2]))
    898 			      sp->timecnt--;
    899 
    900 			    sp->goahead = ts->goahead;
    901 
    902 			    for (i = 0; i < ts->timecnt; i++) {
    903 			      __time_t t = ts->ats[i];
    904 			      if (increment_overflow_time(&t, leapcorr(sp, t))
    905 				  || (0 < sp->timecnt
    906 				      && t <= sp->ats[sp->timecnt - 1]))
    907 				continue;
    908 			      if (TZ_MAX_TIMES <= sp->timecnt) {
    909 				sp->goahead = false;
    910 				break;
    911 			      }
    912 			      sp->ats[sp->timecnt] = t;
    913 			      sp->types[sp->timecnt] = (sp->typecnt
    914 							+ ts->types[i]);
    915 			      sp->timecnt++;
    916 			    }
    917 			    for (i = 0; i < ts->typecnt; i++)
    918 			      sp->ttis[sp->typecnt++] = ts->ttis[i];
    919 			  }
    920 			}
    921 	}
    922 	if (sp->typecnt == 0)
    923 	  return EINVAL;
    924 
    925 	return 0;
    926 }
    927 
    928 /* Load tz data from the file named NAME into *SP.  Respect TZLOADFLAGS.
    929    Return 0 on success, an errno value on failure.  */
    930 static int
    931 tzload(char const *name, struct state *sp, char tzloadflags)
    932 {
    933 #ifdef ALL_STATE
    934   union local_storage *lsp = malloc(sizeof *lsp);
    935   if (!lsp) {
    936     return /*CONSTCOND*/HAVE_MALLOC_ERRNO ? errno : ENOMEM;
    937   } else {
    938     int err = tzloadbody(name, sp, tzloadflags, lsp);
    939     free(lsp);
    940     return err;
    941   }
    942 #else
    943   union local_storage ls;
    944   return tzloadbody(name, sp, tzloadflags, &ls);
    945 #endif
    946 }
    947 
    948 static const int	mon_lengths[2][MONSPERYEAR] = {
    949 	{ 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 },
    950 	{ 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }
    951 };
    952 
    953 static const int	year_lengths[2] = {
    954 	DAYSPERNYEAR, DAYSPERLYEAR
    955 };
    956 
    957 /* Is C an ASCII digit?  */
    958 static bool
    959 is_digit(char c)
    960 {
    961   return '0' <= c && c <= '9';
    962 }
    963 
    964 /*
    965 ** Given a pointer into a timezone string, scan until a character that is not
    966 ** a valid character in a time zone abbreviation is found.
    967 ** Return a pointer to that character.
    968 */
    969 
    970 ATTRIBUTE_PURE_114833 static const char *
    971 getzname(register const char *strp)
    972 {
    973 	register char	c;
    974 
    975 	while ((c = *strp) != '\0' && !is_digit(c) && c != ',' && c != '-' &&
    976 		c != '+')
    977 			++strp;
    978 	return strp;
    979 }
    980 
    981 /*
    982 ** Given a pointer into an extended timezone string, scan until the ending
    983 ** delimiter of the time zone abbreviation is located.
    984 ** Return a pointer to the delimiter.
    985 **
    986 ** As with getzname above, the legal character set is actually quite
    987 ** restricted, with other characters producing undefined results.
    988 ** We don't do any checking here; checking is done later in common-case code.
    989 */
    990 
    991 ATTRIBUTE_PURE_114833 static const char *
    992 getqzname(register const char *strp, const int delim)
    993 {
    994 	register int	c;
    995 
    996 	while ((c = *strp) != '\0' && c != delim)
    997 		++strp;
    998 	return strp;
    999 }
   1000 
   1001 /*
   1002 ** Given a pointer into a timezone string, extract a number from that string.
   1003 ** Check that the number is within a specified range; if it is not, return
   1004 ** NULL.
   1005 ** Otherwise, return a pointer to the first character not part of the number.
   1006 */
   1007 
   1008 static const char *
   1009 getnum(register const char *strp, int *const nump, const int min, const int max)
   1010 {
   1011 	register char	c;
   1012 	register int	num;
   1013 
   1014 	if (strp == NULL || !is_digit(c = *strp)) {
   1015 		errno = EINVAL;
   1016 		return NULL;
   1017 	}
   1018 	num = 0;
   1019 	do {
   1020 		num = num * 10 + (c - '0');
   1021 		if (num > max) {
   1022 			errno = EOVERFLOW;
   1023 			return NULL;	/* illegal value */
   1024 		}
   1025 		c = *++strp;
   1026 	} while (is_digit(c));
   1027 	if (num < min) {
   1028 		errno = EINVAL;
   1029 		return NULL;		/* illegal value */
   1030 	}
   1031 	*nump = num;
   1032 	return strp;
   1033 }
   1034 
   1035 /*
   1036 ** Given a pointer into a timezone string, extract a number of seconds,
   1037 ** in hh[:mm[:ss]] form, from the string.
   1038 ** If any error occurs, return NULL.
   1039 ** Otherwise, return a pointer to the first character not part of the number
   1040 ** of seconds.
   1041 */
   1042 
   1043 static const char *
   1044 getsecs(register const char *strp, int_fast32_t *const secsp)
   1045 {
   1046 	int	num;
   1047 	int_fast32_t secsperhour = SECSPERHOUR;
   1048 
   1049 	/*
   1050 	** 'HOURSPERDAY * DAYSPERWEEK - 1' allows quasi-POSIX rules like
   1051 	** "M10.4.6/26", which does not conform to POSIX,
   1052 	** but which specifies the equivalent of
   1053 	** "02:00 on the first Sunday on or after 23 Oct".
   1054 	*/
   1055 	strp = getnum(strp, &num, 0, HOURSPERDAY * DAYSPERWEEK - 1);
   1056 	if (strp == NULL)
   1057 		return NULL;
   1058 	*secsp = num * secsperhour;
   1059 	if (*strp == ':') {
   1060 		++strp;
   1061 		strp = getnum(strp, &num, 0, MINSPERHOUR - 1);
   1062 		if (strp == NULL)
   1063 			return NULL;
   1064 		*secsp += num * SECSPERMIN;
   1065 		if (*strp == ':') {
   1066 			++strp;
   1067 			/* 'SECSPERMIN' allows for leap seconds.  */
   1068 			strp = getnum(strp, &num, 0, SECSPERMIN);
   1069 			if (strp == NULL)
   1070 				return NULL;
   1071 			*secsp += num;
   1072 		}
   1073 	}
   1074 	return strp;
   1075 }
   1076 
   1077 /*
   1078 ** Given a pointer into a timezone string, extract an offset, in
   1079 ** [+-]hh[:mm[:ss]] form, from the string.
   1080 ** If any error occurs, return NULL.
   1081 ** Otherwise, return a pointer to the first character not part of the time.
   1082 */
   1083 
   1084 static const char *
   1085 getoffset(register const char *strp, int_fast32_t *const offsetp)
   1086 {
   1087 	register bool neg = false;
   1088 
   1089 	if (*strp == '-') {
   1090 		neg = true;
   1091 		++strp;
   1092 	} else if (*strp == '+')
   1093 		++strp;
   1094 	strp = getsecs(strp, offsetp);
   1095 	if (strp == NULL)
   1096 		return NULL;		/* illegal time */
   1097 	if (neg)
   1098 		*offsetp = -*offsetp;
   1099 	return strp;
   1100 }
   1101 
   1102 /*
   1103 ** Given a pointer into a timezone string, extract a rule in the form
   1104 ** date[/time]. See POSIX Base Definitions section 8.3 variable TZ
   1105 ** for the format of "date" and "time".
   1106 ** If a valid rule is not found, return NULL.
   1107 ** Otherwise, return a pointer to the first character not part of the rule.
   1108 */
   1109 
   1110 static const char *
   1111 getrule(const char *strp, register struct rule *const rulep)
   1112 {
   1113 	if (*strp == 'J') {
   1114 		/*
   1115 		** Julian day.
   1116 		*/
   1117 		rulep->r_type = JULIAN_DAY;
   1118 		++strp;
   1119 		strp = getnum(strp, &rulep->r_day, 1, DAYSPERNYEAR);
   1120 	} else if (*strp == 'M') {
   1121 		/*
   1122 		** Month, week, day.
   1123 		*/
   1124 		rulep->r_type = MONTH_NTH_DAY_OF_WEEK;
   1125 		++strp;
   1126 		strp = getnum(strp, &rulep->r_mon, 1, MONSPERYEAR);
   1127 		if (strp == NULL)
   1128 			return NULL;
   1129 		if (*strp++ != '.')
   1130 			return NULL;
   1131 		strp = getnum(strp, &rulep->r_week, 1, 5);
   1132 		if (strp == NULL)
   1133 			return NULL;
   1134 		if (*strp++ != '.')
   1135 			return NULL;
   1136 		strp = getnum(strp, &rulep->r_day, 0, DAYSPERWEEK - 1);
   1137 	} else if (is_digit(*strp)) {
   1138 		/*
   1139 		** Day of year.
   1140 		*/
   1141 		rulep->r_type = DAY_OF_YEAR;
   1142 		strp = getnum(strp, &rulep->r_day, 0, DAYSPERLYEAR - 1);
   1143 	} else	return NULL;		/* invalid format */
   1144 	if (strp == NULL)
   1145 		return NULL;
   1146 	if (*strp == '/') {
   1147 		/*
   1148 		** Time specified.
   1149 		*/
   1150 		++strp;
   1151 		strp = getoffset(strp, &rulep->r_time);
   1152 	} else	rulep->r_time = 2 * SECSPERHOUR;	/* default = 2:00:00 */
   1153 	return strp;
   1154 }
   1155 
   1156 /*
   1157 ** Given a year, a rule, and the offset from UT at the time that rule takes
   1158 ** effect, calculate the year-relative time that rule takes effect.
   1159 */
   1160 
   1161 static int_fast32_t
   1162 transtime(const int year, register const struct rule *const rulep,
   1163 	  const int_fast32_t offset)
   1164 {
   1165 	register bool	leapyear;
   1166 	register int_fast32_t value;
   1167 	register int	i;
   1168 	int		d, m1, yy0, yy1, yy2, dow;
   1169 
   1170 	leapyear = isleap(year);
   1171 	switch (rulep->r_type) {
   1172 
   1173 	case JULIAN_DAY:
   1174 		/*
   1175 		** Jn - Julian day, 1 == January 1, 60 == March 1 even in leap
   1176 		** years.
   1177 		** In non-leap years, or if the day number is 59 or less, just
   1178 		** add SECSPERDAY times the day number-1 to the time of
   1179 		** January 1, midnight, to get the day.
   1180 		*/
   1181 		value = (rulep->r_day - 1) * SECSPERDAY;
   1182 		if (leapyear && rulep->r_day >= 60)
   1183 			value += SECSPERDAY;
   1184 		break;
   1185 
   1186 	case DAY_OF_YEAR:
   1187 		/*
   1188 		** n - day of year.
   1189 		** Just add SECSPERDAY times the day number to the time of
   1190 		** January 1, midnight, to get the day.
   1191 		*/
   1192 		value = rulep->r_day * SECSPERDAY;
   1193 		break;
   1194 
   1195 	case MONTH_NTH_DAY_OF_WEEK:
   1196 		/*
   1197 		** Mm.n.d - nth "dth day" of month m.
   1198 		*/
   1199 
   1200 		/*
   1201 		** Use Zeller's Congruence to get day-of-week of first day of
   1202 		** month.
   1203 		*/
   1204 		m1 = (rulep->r_mon + 9) % 12 + 1;
   1205 		yy0 = (rulep->r_mon <= 2) ? (year - 1) : year;
   1206 		yy1 = yy0 / 100;
   1207 		yy2 = yy0 % 100;
   1208 		dow = ((26 * m1 - 2) / 10 +
   1209 			1 + yy2 + yy2 / 4 + yy1 / 4 - 2 * yy1) % 7;
   1210 		if (dow < 0)
   1211 			dow += DAYSPERWEEK;
   1212 
   1213 		/*
   1214 		** "dow" is the day-of-week of the first day of the month. Get
   1215 		** the day-of-month (zero-origin) of the first "dow" day of the
   1216 		** month.
   1217 		*/
   1218 		d = rulep->r_day - dow;
   1219 		if (d < 0)
   1220 			d += DAYSPERWEEK;
   1221 		for (i = 1; i < rulep->r_week; ++i) {
   1222 			if (d + DAYSPERWEEK >=
   1223 				mon_lengths[leapyear][rulep->r_mon - 1])
   1224 					break;
   1225 			d += DAYSPERWEEK;
   1226 		}
   1227 
   1228 		/*
   1229 		** "d" is the day-of-month (zero-origin) of the day we want.
   1230 		*/
   1231 		value = d * SECSPERDAY;
   1232 		for (i = 0; i < rulep->r_mon - 1; ++i)
   1233 			value += mon_lengths[leapyear][i] * SECSPERDAY;
   1234 		break;
   1235 
   1236 	default: unreachable();
   1237 	}
   1238 
   1239 	/*
   1240 	** "value" is the year-relative time of 00:00:00 UT on the day in
   1241 	** question. To get the year-relative time of the specified local
   1242 	** time on that day, add the transition time and the current offset
   1243 	** from UT.
   1244 	*/
   1245 	return value + rulep->r_time + offset;
   1246 }
   1247 
   1248 /*
   1249 ** Given a POSIX.1 proleptic TZ string, fill in the rule tables as
   1250 ** appropriate.
   1251 */
   1252 
   1253 static bool
   1254 tzparse(const char *name, struct state *sp, struct state const *basep)
   1255 {
   1256 	const char *			stdname;
   1257 	const char *			dstname;
   1258 	int_fast32_t			stdoffset;
   1259 	int_fast32_t			dstoffset;
   1260 	register char *			cp;
   1261 	register bool			load_ok;
   1262 	ptrdiff_t stdlen, dstlen, charcnt;
   1263 	__time_t atlo = TIME_T_MIN, leaplo = TIME_T_MIN;
   1264 
   1265 	dstname = NULL; /* XXX gcc */
   1266 	stdname = name;
   1267 	if (*name == '<') {
   1268 	  name++;
   1269 	  stdname = name;
   1270 	  name = getqzname(name, '>');
   1271 	  if (*name != '>')
   1272 	    return false;
   1273 	  stdlen = name - stdname;
   1274 	  name++;
   1275 	} else {
   1276 	  name = getzname(name);
   1277 	  stdlen = name - stdname;
   1278 	}
   1279 	if (! (0 < stdlen && stdlen <= TZNAME_MAXIMUM))
   1280 	  return false;
   1281 	name = getoffset(name, &stdoffset);
   1282 	if (name == NULL)
   1283 	  return false;
   1284 	charcnt = stdlen + 1;
   1285 	if (basep) {
   1286 	  if (0 < basep->timecnt)
   1287 	    atlo = basep->ats[basep->timecnt - 1];
   1288 	  load_ok = false;
   1289 	  sp->leapcnt = basep->leapcnt;
   1290 	  memcpy(sp->lsis, basep->lsis, sp->leapcnt * sizeof *sp->lsis);
   1291 	} else {
   1292 	  load_ok = tzload(TZDEFRULES, sp, 0) == 0;
   1293 	  if (!load_ok)
   1294 	    sp->leapcnt = 0;	/* So, we're off a little.  */
   1295 	}
   1296 	if (0 < sp->leapcnt)
   1297 	  leaplo = sp->lsis[sp->leapcnt - 1].ls_trans;
   1298 	sp->goback = sp->goahead = false;
   1299 	if (*name != '\0') {
   1300 		if (*name == '<') {
   1301 			dstname = ++name;
   1302 			name = getqzname(name, '>');
   1303 			if (*name != '>')
   1304 			  return false;
   1305 			dstlen = name - dstname;
   1306 			name++;
   1307 		} else {
   1308 			dstname = name;
   1309 			name = getzname(name);
   1310 			dstlen = name - dstname; /* length of DST abbr. */
   1311 		}
   1312 		if (! (0 < dstlen && dstlen <= TZNAME_MAXIMUM))
   1313 		  return false;
   1314 		charcnt += dstlen + 1;
   1315 		if (*name != '\0' && *name != ',' && *name != ';') {
   1316 			name = getoffset(name, &dstoffset);
   1317 			if (name == NULL)
   1318 			  return false;
   1319 		} else	dstoffset = stdoffset - SECSPERHOUR;
   1320 		if (*name == '\0' && !load_ok)
   1321 			name = TZDEFRULESTRING;
   1322 		if (*name == ',' || *name == ';') {
   1323 			struct rule	start;
   1324 			struct rule	end;
   1325 			register int	year;
   1326 			register int	timecnt;
   1327 			__time_t	janfirst;
   1328 			int_fast32_t janoffset = 0;
   1329 			int yearbeg, yearlim;
   1330 
   1331 			++name;
   1332 			if ((name = getrule(name, &start)) == NULL)
   1333 			  return false;
   1334 			if (*name++ != ',')
   1335 			  return false;
   1336 			if ((name = getrule(name, &end)) == NULL)
   1337 			  return false;
   1338 			if (*name != '\0')
   1339 			  return false;
   1340 			sp->typecnt = 2;	/* standard time and DST */
   1341 			/*
   1342 			** Two transitions per year, from EPOCH_YEAR forward.
   1343 			*/
   1344 			init_ttinfo(&sp->ttis[0], -stdoffset, false, 0);
   1345 			init_ttinfo(&sp->ttis[1], -dstoffset, true,
   1346 			    (int)(stdlen + 1));
   1347 			timecnt = 0;
   1348 			janfirst = 0;
   1349 			yearbeg = EPOCH_YEAR;
   1350 
   1351 			do {
   1352 			  int_fast32_t yearsecs
   1353 			    = year_lengths[isleap(yearbeg - 1)] * SECSPERDAY;
   1354 			  __time_t janfirst1 = janfirst;
   1355 			  yearbeg--;
   1356 			  if (increment_overflow_time(&janfirst1, -yearsecs)) {
   1357 			    janoffset = -yearsecs;
   1358 			    break;
   1359 			  }
   1360 			  janfirst = janfirst1;
   1361 			} while (atlo < janfirst
   1362 				 && EPOCH_YEAR - YEARSPERREPEAT / 2 < yearbeg);
   1363 
   1364 			for (;;) {
   1365 			  int_fast32_t yearsecs
   1366 			    = year_lengths[isleap(yearbeg)] * SECSPERDAY;
   1367 			  int yearbeg1 = yearbeg;
   1368 			  __time_t janfirst1 = janfirst;
   1369 			  if (increment_overflow_time(&janfirst1, yearsecs)
   1370 			      || increment_overflow(&yearbeg1, 1)
   1371 			      || atlo <= janfirst1)
   1372 			    break;
   1373 			  yearbeg = yearbeg1;
   1374 			  janfirst = janfirst1;
   1375 			}
   1376 
   1377 			yearlim = yearbeg;
   1378 			if (increment_overflow(&yearlim, years_of_observations))
   1379 			  yearlim = INT_MAX;
   1380 			for (year = yearbeg; year < yearlim; year++) {
   1381 				int_fast32_t
   1382 				  starttime = transtime(year, &start, stdoffset),
   1383 				  endtime = transtime(year, &end, dstoffset);
   1384 				int_fast32_t
   1385 				  yearsecs = (year_lengths[isleap(year)]
   1386 					      * SECSPERDAY);
   1387 				bool reversed = endtime < starttime;
   1388 				if (reversed) {
   1389 					int_fast32_t swap = starttime;
   1390 					starttime = endtime;
   1391 					endtime = swap;
   1392 				}
   1393 				if (reversed
   1394 				    || (starttime < endtime
   1395 					&& endtime - starttime < yearsecs)) {
   1396 					if (TZ_MAX_TIMES - 2 < timecnt)
   1397 						break;
   1398 					sp->ats[timecnt] = janfirst;
   1399 					if (! increment_overflow_time
   1400 					    (&sp->ats[timecnt],
   1401 					     janoffset + starttime)
   1402 					    && atlo <= sp->ats[timecnt])
   1403 					  sp->types[timecnt++] = !reversed;
   1404 					sp->ats[timecnt] = janfirst;
   1405 					if (! increment_overflow_time
   1406 					    (&sp->ats[timecnt],
   1407 					     janoffset + endtime)
   1408 					    && atlo <= sp->ats[timecnt]) {
   1409 					  sp->types[timecnt++] = reversed;
   1410 					}
   1411 				}
   1412 				if (endtime < leaplo) {
   1413 				  yearlim = year;
   1414 				  if (increment_overflow(&yearlim,
   1415 							 years_of_observations))
   1416 				    yearlim = INT_MAX;
   1417 				}
   1418 				if (increment_overflow_time
   1419 				    (&janfirst, janoffset + yearsecs))
   1420 					break;
   1421 				janoffset = 0;
   1422 			}
   1423 			sp->timecnt = timecnt;
   1424 			if (! timecnt) {
   1425 				sp->ttis[0] = sp->ttis[1];
   1426 				sp->typecnt = 1;	/* Perpetual DST.  */
   1427 			} else if (years_of_observations <= year - yearbeg)
   1428 				sp->goback = sp->goahead = true;
   1429 		} else {
   1430 			register int_fast32_t	theirstdoffset;
   1431 			register int_fast32_t	theirdstoffset;
   1432 			register int_fast32_t	theiroffset;
   1433 			register bool		isdst;
   1434 			register int		i;
   1435 			register int		j;
   1436 
   1437 			if (*name != '\0')
   1438 			  return false;
   1439 			/*
   1440 			** Initial values of theirstdoffset and theirdstoffset.
   1441 			*/
   1442 			theirstdoffset = 0;
   1443 			for (i = 0; i < sp->timecnt; ++i) {
   1444 				j = sp->types[i];
   1445 				if (!sp->ttis[j].tt_isdst) {
   1446 					theirstdoffset =
   1447 						- sp->ttis[j].tt_utoff;
   1448 					break;
   1449 				}
   1450 			}
   1451 			theirdstoffset = 0;
   1452 			for (i = 0; i < sp->timecnt; ++i) {
   1453 				j = sp->types[i];
   1454 				if (sp->ttis[j].tt_isdst) {
   1455 					theirdstoffset =
   1456 						- sp->ttis[j].tt_utoff;
   1457 					break;
   1458 				}
   1459 			}
   1460 			/*
   1461 			** Initially we're assumed to be in standard time.
   1462 			*/
   1463 			isdst = false;
   1464 			/*
   1465 			** Now juggle transition times and types
   1466 			** tracking offsets as you do.
   1467 			*/
   1468 			for (i = 0; i < sp->timecnt; ++i) {
   1469 				j = sp->types[i];
   1470 				sp->types[i] = sp->ttis[j].tt_isdst;
   1471 				if (sp->ttis[j].tt_ttisut) {
   1472 					/* No adjustment to transition time */
   1473 				} else {
   1474 					/*
   1475 					** If daylight saving time is in
   1476 					** effect, and the transition time was
   1477 					** not specified as standard time, add
   1478 					** the daylight saving time offset to
   1479 					** the transition time; otherwise, add
   1480 					** the standard time offset to the
   1481 					** transition time.
   1482 					*/
   1483 					/*
   1484 					** Transitions from DST to DDST
   1485 					** will effectively disappear since
   1486 					** proleptic TZ strings have only one
   1487 					** DST offset.
   1488 					*/
   1489 					if (isdst && !sp->ttis[j].tt_ttisstd) {
   1490 						sp->ats[i] += (time_t)
   1491 						    (dstoffset - theirdstoffset);
   1492 					} else {
   1493 						sp->ats[i] += (time_t)
   1494 						    (stdoffset - theirstdoffset);
   1495 					}
   1496 				}
   1497 				theiroffset = -sp->ttis[j].tt_utoff;
   1498 				if (sp->ttis[j].tt_isdst)
   1499 					theirdstoffset = theiroffset;
   1500 				else	theirstdoffset = theiroffset;
   1501 			}
   1502 			/*
   1503 			** Finally, fill in ttis.
   1504 			*/
   1505 			init_ttinfo(&sp->ttis[0], -stdoffset, false, 0);
   1506 			init_ttinfo(&sp->ttis[1], -dstoffset, true,
   1507 			    (int)(stdlen + 1));
   1508 			sp->typecnt = 2;
   1509 		}
   1510 	} else {
   1511 		dstlen = 0;
   1512 		sp->typecnt = 1;		/* only standard time */
   1513 		sp->timecnt = 0;
   1514 		init_ttinfo(&sp->ttis[0], -stdoffset, false, 0);
   1515 		init_ttinfo(&sp->ttis[1], 0, false, 0);
   1516 	}
   1517 	sp->charcnt = (int)charcnt;
   1518 	cp = sp->chars;
   1519 	memcpy(cp, stdname, stdlen);
   1520 	cp += stdlen;
   1521 	*cp++ = '\0';
   1522 	if (dstlen != 0) {
   1523 		(void) memcpy(cp, dstname, dstlen);
   1524 		*(cp + dstlen) = '\0';
   1525 	}
   1526 	return true;
   1527 }
   1528 
   1529 static void
   1530 gmtload(struct state *const sp)
   1531 {
   1532 	if (tzload(etc_utc, sp, TZLOAD_TZSTRING) != 0)
   1533 	  (void)tzparse("UTC0", sp, NULL);
   1534 }
   1535 
   1536 #if !USE_TIMEX_T || !defined TM_GMTOFF
   1537 
   1538 /* Initialize *SP to a value appropriate for the TZ setting NAME.
   1539    Respect TZLOADFLAGS.
   1540    Return 0 on success, an errno value on failure.  */
   1541 static int
   1542 zoneinit(struct state *sp, char const *name, char tzloadflags)
   1543 {
   1544   if (name && ! name[0]) {
   1545     /*
   1546     ** User wants it fast rather than right.
   1547     */
   1548     sp->leapcnt = 0;		/* so, we're off a little */
   1549     sp->timecnt = 0;
   1550     sp->typecnt = 1;
   1551     sp->charcnt = 0;
   1552     sp->goback = sp->goahead = false;
   1553     init_ttinfo(&sp->ttis[0], 0, false, 0);
   1554     strcpy(sp->chars, utc);
   1555     return 0;
   1556   } else {
   1557     int err = tzload(name, sp, tzloadflags);
   1558     if (err != 0 && name && name[0] != ':' && tzparse(name, sp, NULL))
   1559       err = 0;
   1560     if (err == 0)
   1561       err = scrub_abbrs(sp);
   1562     return err;
   1563   }
   1564 }
   1565 
   1566 static void
   1567 tzsetlcl(char const *name)
   1568 {
   1569   struct state *sp = __lclptr;
   1570   int lcl = name ? strlen(name) < sizeof lcl_TZname : -1;
   1571   if (lcl < 0
   1572       ? lcl_is_set < 0
   1573       : 0 < lcl_is_set && strcmp(lcl_TZname, name) == 0)
   1574     return;
   1575 
   1576 # ifndef ALL_STATE
   1577   if (! sp)
   1578     __lclptr = sp = malloc(sizeof *__lclptr);
   1579 # endif
   1580   if (sp) {
   1581     if (zoneinit(sp, name, TZLOAD_FROMENV | TZLOAD_TZSTRING) != 0) {
   1582       zoneinit(sp, "", 0);
   1583       strcpy(sp->chars, UNSPEC);
   1584     }
   1585     if (0 < lcl)
   1586       strcpy(lcl_TZname, name);
   1587   }
   1588   settzname();
   1589   lcl_is_set = lcl;
   1590 }
   1591 #endif
   1592 
   1593 #if !USE_TIMEX_T
   1594 void
   1595 tzset(void)
   1596 {
   1597   if (lock() != 0)
   1598     return;
   1599   tzset_unlocked();
   1600   unlock();
   1601 }
   1602 
   1603 #ifdef STD_INSPIRED
   1604 void
   1605 tzsetwall(void)
   1606 {
   1607 	if (lock() != 0)
   1608 		return;
   1609 	tzsetlcl(NULL);
   1610 	unlock();
   1611 }
   1612 #endif
   1613 
   1614 void
   1615 tzset_unlocked(void)
   1616 {
   1617 	tzsetlcl(getenv("TZ"));
   1618 }
   1619 #endif
   1620 
   1621 static void
   1622 gmtcheck(void)
   1623 {
   1624   static bool gmt_is_set;
   1625   if (lock() != 0)
   1626     return;
   1627   if (! gmt_is_set) {
   1628 #ifdef ALL_STATE
   1629     gmtptr = malloc(sizeof *gmtptr);
   1630 #endif
   1631     if (gmtptr)
   1632       gmtload(gmtptr);
   1633     gmt_is_set = true;
   1634   }
   1635   unlock();
   1636 }
   1637 
   1638 #if NETBSD_INSPIRED && !USE_TIMEX_T
   1639 
   1640 timezone_t
   1641 tzalloc(char const *name)
   1642 {
   1643   timezone_t sp = malloc(sizeof *sp);
   1644   if (sp) {
   1645     int err = zoneinit(sp, name, TZLOAD_TZSTRING);
   1646     if (err != 0) {
   1647       free(sp);
   1648       errno = err;
   1649       return NULL;
   1650     }
   1651   } else if (/*CONSTCOND*/!HAVE_MALLOC_ERRNO)
   1652     /*NOTREACHED*/
   1653     errno = ENOMEM;
   1654   return sp;
   1655 }
   1656 
   1657 void
   1658 tzfree(timezone_t sp)
   1659 {
   1660   free(sp);
   1661 }
   1662 
   1663 /*
   1664 ** NetBSD 6.1.4 has ctime_rz, but omit it because C23 deprecates ctime and
   1665 ** POSIX.1-2024 removes ctime_r.  Both have potential security problems that
   1666 ** ctime_rz would share.  Callers can instead use localtime_rz + strftime.
   1667 **
   1668 ** NetBSD 6.1.4 has tzgetname, but omit it because it doesn't work
   1669 ** in zones with three or more time zone abbreviations.
   1670 ** Callers can instead use localtime_rz + strftime.
   1671 */
   1672 
   1673 #endif
   1674 
   1675 #if !USE_TIMEX_T || !defined TM_GMTOFF
   1676 
   1677 /*
   1678 ** The easy way to behave "as if no library function calls" localtime
   1679 ** is to not call it, so we drop its guts into "localsub", which can be
   1680 ** freely called. (And no, the PANS doesn't require the above behavior,
   1681 ** but it *is* desirable.)
   1682 **
   1683 ** If successful and SETNAME is nonzero,
   1684 ** set the applicable parts of tzname, timezone and altzone;
   1685 ** however, it's OK to omit this step for proleptic TZ strings
   1686 ** since in that case tzset should have already done this step correctly.
   1687 ** SETNAME's type is int_fast32_t for compatibility with gmtsub,
   1688 ** but it is actually a boolean and its value should be 0 or 1.
   1689 */
   1690 
   1691 /*ARGSUSED*/
   1692 static struct tm *
   1693 localsub(struct state const *sp, time_t const *timep, int_fast32_t setname,
   1694 	 struct tm *const tmp)
   1695 {
   1696 	register const struct ttinfo *	ttisp;
   1697 	register int			i;
   1698 	register struct tm *		result;
   1699 	const time_t			t = *timep;
   1700 
   1701 	if (sp == NULL) {
   1702 	  /* Don't bother to set tzname etc.; tzset has already done it.  */
   1703 	  return gmtsub(gmtptr, timep, 0, tmp);
   1704 	}
   1705 	if ((sp->goback && t < sp->ats[0]) ||
   1706 		(sp->goahead && t > sp->ats[sp->timecnt - 1])) {
   1707 			time_t newt;
   1708 			register __time_t	seconds;
   1709 			register time_t		years;
   1710 
   1711 			if (t < sp->ats[0])
   1712 				seconds = sp->ats[0] - t;
   1713 			else	seconds = t - sp->ats[sp->timecnt - 1];
   1714 			--seconds;
   1715 
   1716 			/* Beware integer overflow, as SECONDS might
   1717 			   be close to the maximum time_t.  */
   1718 			years = (time_t)(seconds / SECSPERREPEAT
   1719 			    * YEARSPERREPEAT);
   1720 			seconds = (time_t)(years * AVGSECSPERYEAR);
   1721 			years += YEARSPERREPEAT;
   1722 			if (t < sp->ats[0])
   1723 			  newt = (time_t)(t + seconds + SECSPERREPEAT);
   1724 			else
   1725 			  newt = (time_t)(t - seconds - SECSPERREPEAT);
   1726 
   1727 			if (newt < sp->ats[0] ||
   1728 				newt > sp->ats[sp->timecnt - 1]) {
   1729 				errno = EINVAL;
   1730 				return NULL;	/* "cannot happen" */
   1731 			}
   1732 			result = localsub(sp, &newt, setname, tmp);
   1733 			if (result) {
   1734 # if defined ckd_add && defined ckd_sub
   1735 				if (t < sp->ats[0]
   1736 				    ? ckd_sub(&result->tm_year,
   1737 					      result->tm_year, years)
   1738 				    : ckd_add(&result->tm_year,
   1739 					      result->tm_year, years))
   1740 				  return NULL;
   1741 # else
   1742 				register int_fast64_t newy;
   1743 
   1744 				newy = result->tm_year;
   1745 				if (t < sp->ats[0])
   1746 					newy -= years;
   1747 				else	newy += years;
   1748 				if (! (INT_MIN <= newy && newy <= INT_MAX)) {
   1749 					errno = EOVERFLOW;
   1750 					return NULL;
   1751 				}
   1752 				result->tm_year = (int)newy;
   1753 # endif
   1754 			}
   1755 			return result;
   1756 	}
   1757 	if (sp->timecnt == 0 || t < sp->ats[0]) {
   1758 		i = 0;
   1759 	} else {
   1760 		register int	lo = 1;
   1761 		register int	hi = sp->timecnt;
   1762 
   1763 		while (lo < hi) {
   1764 			register int	mid = (lo + hi) / 2;
   1765 
   1766 			if (t < sp->ats[mid])
   1767 				hi = mid;
   1768 			else	lo = mid + 1;
   1769 		}
   1770 		i = sp->types[lo - 1];
   1771 	}
   1772 	ttisp = &sp->ttis[i];
   1773 	/*
   1774 	** To get (wrong) behavior that's compatible with System V Release 2.0
   1775 	** you'd replace the statement below with
   1776 	**	t += ttisp->tt_utoff;
   1777 	**	timesub(&t, 0L, sp, tmp);
   1778 	*/
   1779 	result = timesub(&t, ttisp->tt_utoff, sp, tmp);
   1780 	if (result) {
   1781 	  result->tm_isdst = ttisp->tt_isdst;
   1782 # ifdef TM_ZONE
   1783 	  result->TM_ZONE = UNCONST(&sp->chars[ttisp->tt_desigidx]);
   1784 # endif
   1785 	  if (setname)
   1786 	    update_tzname_etc(sp, ttisp);
   1787 	}
   1788 	return result;
   1789 }
   1790 #endif
   1791 
   1792 #if !USE_TIMEX_T
   1793 
   1794 # if NETBSD_INSPIRED
   1795 struct tm *
   1796 localtime_rz(struct state *__restrict sp, time_t const *__restrict timep,
   1797 	struct tm *__restrict tmp)
   1798 {
   1799   return localsub(sp, timep, 0, tmp);
   1800 }
   1801 # endif
   1802 
   1803 static struct tm *
   1804 localtime_tzset(time_t const *timep, struct tm *tmp, bool setname)
   1805 {
   1806   int err = lock();
   1807   if (err) {
   1808     errno = err;
   1809     return NULL;
   1810   }
   1811   if (setname || !lcl_is_set)
   1812     tzset_unlocked();
   1813   tmp = localsub(__lclptr, timep, setname, tmp);
   1814   unlock();
   1815   return tmp;
   1816 }
   1817 
   1818 struct tm *
   1819 localtime(const time_t *timep)
   1820 {
   1821 # if !SUPPORT_C89
   1822   static struct tm tm;
   1823 # endif
   1824   return localtime_tzset(timep, &tm, true);
   1825 }
   1826 
   1827 struct tm *
   1828 localtime_r(const time_t *__restrict timep, struct tm *__restrict tmp)
   1829 {
   1830   return localtime_tzset(timep, tmp, false);
   1831 }
   1832 #endif
   1833 
   1834 /*
   1835 ** gmtsub is to gmtime as localsub is to localtime.
   1836 */
   1837 
   1838 static struct tm *
   1839 gmtsub(ATTRIBUTE_MAYBE_UNUSED struct state const *sp, time_t const *timep,
   1840        int_fast32_t offset, struct tm *tmp)
   1841 {
   1842 	register struct tm *	result;
   1843 
   1844 	result = timesub(timep, offset, gmtptr, tmp);
   1845 #ifdef TM_ZONE
   1846 	/*
   1847 	** Could get fancy here and deliver something such as
   1848 	** "+xx" or "-xx" if offset is non-zero,
   1849 	** but this is no time for a treasure hunt.
   1850 	*/
   1851 	if (result)
   1852 		result->TM_ZONE = UNCONST(offset ? wildabbr : gmtptr ?
   1853 		    gmtptr->chars : utc);
   1854 #endif /* defined TM_ZONE */
   1855 	return result;
   1856 }
   1857 
   1858 #if !USE_TIMEX_T
   1859 
   1860 /*
   1861 * Re-entrant version of gmtime.
   1862 */
   1863 
   1864 struct tm *
   1865 gmtime_r(time_t const *__restrict timep, struct tm *__restrict tmp)
   1866 {
   1867   gmtcheck();
   1868   return gmtsub(NULL, timep, 0, tmp);
   1869 }
   1870 
   1871 struct tm *
   1872 gmtime(const time_t *timep)
   1873 {
   1874 # if !SUPPORT_C89
   1875   static struct tm tm;
   1876 # endif
   1877   return gmtime_r(timep, &tm);
   1878 }
   1879 
   1880 # if STD_INSPIRED
   1881 
   1882 /* This function is obsolescent and may disappear in future releases.
   1883    Callers can instead use localtime_rz with a fixed-offset zone.  */
   1884 
   1885 struct tm *
   1886 offtime(const time_t *timep, long offset)
   1887 {
   1888   gmtcheck();
   1889 
   1890 #  if !SUPPORT_C89
   1891   static struct tm tm;
   1892 #  endif
   1893   return gmtsub(gmtptr, timep, (int_fast32_t)offset, &tm);
   1894 }
   1895 
   1896 struct tm *
   1897 offtime_r(const time_t *timep, long offset, struct tm *tmp)
   1898 {
   1899 	gmtcheck();
   1900 	return gmtsub(NULL, timep, (int_fast32_t)offset, tmp);
   1901 }
   1902 
   1903 # endif
   1904 #endif
   1905 
   1906 /*
   1907 ** Return the number of leap years through the end of the given year
   1908 ** where, to make the math easy, the answer for year zero is defined as zero.
   1909 */
   1910 
   1911 static time_t
   1912 leaps_thru_end_of_nonneg(time_t y)
   1913 {
   1914   return y / 4 - y / 100 + y / 400;
   1915 }
   1916 
   1917 static time_t
   1918 leaps_thru_end_of(time_t y)
   1919 {
   1920   return (y < 0
   1921 	  ? -1 - leaps_thru_end_of_nonneg(-1 - y)
   1922 	  : leaps_thru_end_of_nonneg(y));
   1923 }
   1924 
   1925 static struct tm *
   1926 timesub(const time_t *timep, int_fast32_t offset,
   1927 	const struct state *sp, struct tm *tmp)
   1928 {
   1929 	register const struct lsinfo *	lp;
   1930 	register time_t			tdays;
   1931 	register const int *		ip;
   1932 	register int_fast32_t		corr;
   1933 	register int			i;
   1934 	int_fast32_t idays, rem, dayoff, dayrem;
   1935 	time_t y;
   1936 
   1937 	/* If less than SECSPERMIN, the number of seconds since the
   1938 	   most recent positive leap second; otherwise, do not add 1
   1939 	   to localtime tm_sec because of leap seconds.  */
   1940 	__time_t secs_since_posleap = SECSPERMIN;
   1941 
   1942 	corr = 0;
   1943 	i = (sp == NULL) ? 0 : sp->leapcnt;
   1944 	while (--i >= 0) {
   1945 		lp = &sp->lsis[i];
   1946 		if (*timep >= lp->ls_trans) {
   1947 			corr = lp->ls_corr;
   1948 			if ((i == 0 ? 0 : lp[-1].ls_corr) < corr)
   1949 			  secs_since_posleap = *timep - lp->ls_trans;
   1950 			break;
   1951 		}
   1952 	}
   1953 
   1954 	/* Calculate the year, avoiding integer overflow even if
   1955 	   time_t is unsigned.  */
   1956 	tdays = (time_t)(*timep / SECSPERDAY);
   1957 	rem = (int)(*timep % SECSPERDAY);
   1958 	rem += offset % SECSPERDAY - corr % SECSPERDAY + 3 * SECSPERDAY;
   1959 	dayoff = offset / SECSPERDAY - corr / SECSPERDAY + rem / SECSPERDAY - 3;
   1960 	rem %= SECSPERDAY;
   1961 	/* y = (EPOCH_YEAR
   1962 		+ floor((tdays + dayoff) / DAYSPERREPEAT) * YEARSPERREPEAT),
   1963 	   sans overflow.  But calculate against 1570 (EPOCH_YEAR -
   1964 	   YEARSPERREPEAT) instead of against 1970 so that things work
   1965 	   for localtime values before 1970 when time_t is unsigned.  */
   1966 	dayrem = (int)(tdays % DAYSPERREPEAT);
   1967 	dayrem += dayoff % DAYSPERREPEAT;
   1968 	y = (time_t)(EPOCH_YEAR - YEARSPERREPEAT
   1969 	     + ((1 + dayoff / DAYSPERREPEAT + dayrem / DAYSPERREPEAT
   1970 		 - ((dayrem % DAYSPERREPEAT) < 0)
   1971 		 + tdays / DAYSPERREPEAT)
   1972 		* YEARSPERREPEAT));
   1973 	/* idays = (tdays + dayoff) mod DAYSPERREPEAT, sans overflow.  */
   1974 	idays = (int)(tdays % DAYSPERREPEAT);
   1975 	idays += (dayoff % DAYSPERREPEAT + 2 * DAYSPERREPEAT);
   1976 	idays %= DAYSPERREPEAT;
   1977 	/* Increase Y and decrease IDAYS until IDAYS is in range for Y.  */
   1978 	while (year_lengths[isleap(y)] <= idays) {
   1979 		int_fast32_t tdelta = idays / DAYSPERLYEAR;
   1980 		int_fast32_t ydelta = tdelta + !tdelta;
   1981 		time_t newy = (time_t)(y + ydelta);
   1982 		register int	leapdays;
   1983 		leapdays = (int)(leaps_thru_end_of(newy - 1) -
   1984 			leaps_thru_end_of(y - 1));
   1985 		idays -= ydelta * DAYSPERNYEAR;
   1986 		idays -= leapdays;
   1987 		y = newy;
   1988 	}
   1989 
   1990 #ifdef ckd_add
   1991 	if (ckd_add(&tmp->tm_year, y, -TM_YEAR_BASE)) {
   1992 	  errno = EOVERFLOW;
   1993 	  return NULL;
   1994 	}
   1995 #else
   1996 	if (!TYPE_SIGNED(time_t) && y < TM_YEAR_BASE) {
   1997 	  int signed_y = (int)y;
   1998 	  tmp->tm_year = signed_y - TM_YEAR_BASE;
   1999 	} else if ((!TYPE_SIGNED(time_t) || INT_MIN + TM_YEAR_BASE <= y)
   2000 		   && y - TM_YEAR_BASE <= INT_MAX)
   2001 	  tmp->tm_year = (int)(y - TM_YEAR_BASE);
   2002 	else {
   2003 	  errno = EOVERFLOW;
   2004 	  return NULL;
   2005 	}
   2006 #endif
   2007 	tmp->tm_yday = (int)idays;
   2008 	/*
   2009 	** The "extra" mods below avoid overflow problems.
   2010 	*/
   2011 	tmp->tm_wday = (int)(TM_WDAY_BASE
   2012 			+ ((tmp->tm_year % DAYSPERWEEK)
   2013 			   * (DAYSPERNYEAR % DAYSPERWEEK))
   2014 			+ leaps_thru_end_of(y - 1)
   2015 			- leaps_thru_end_of(TM_YEAR_BASE - 1)
   2016 			+ idays);
   2017 	tmp->tm_wday %= DAYSPERWEEK;
   2018 	if (tmp->tm_wday < 0)
   2019 		tmp->tm_wday += DAYSPERWEEK;
   2020 	tmp->tm_hour = (int) (rem / SECSPERHOUR);
   2021 	rem %= SECSPERHOUR;
   2022 	tmp->tm_min = (int)(rem / SECSPERMIN);
   2023 	tmp->tm_sec = (int)(rem % SECSPERMIN);
   2024 
   2025 	/* Use "... ??:??:60" at the end of the localtime minute containing
   2026 	   the second just before the positive leap second.  */
   2027 	tmp->tm_sec += secs_since_posleap <= tmp->tm_sec;
   2028 
   2029 	ip = mon_lengths[isleap(y)];
   2030 	for (tmp->tm_mon = 0; idays >= ip[tmp->tm_mon]; ++(tmp->tm_mon))
   2031 		idays -= ip[tmp->tm_mon];
   2032 	tmp->tm_mday = (int)(idays + 1);
   2033 	tmp->tm_isdst = 0;
   2034 #ifdef TM_GMTOFF
   2035 	tmp->TM_GMTOFF = offset;
   2036 #endif /* defined TM_GMTOFF */
   2037 	return tmp;
   2038 }
   2039 
   2040 /*
   2041 ** Adapted from code provided by Robert Elz, who writes:
   2042 **	The "best" way to do mktime I think is based on an idea of Bob
   2043 **	Kridle's (so its said...) from a long time ago.
   2044 **	It does a binary search of the time_t space. Since time_t's are
   2045 **	just 32 bits, its a max of 32 iterations (even at 64 bits it
   2046 **	would still be very reasonable).
   2047 */
   2048 
   2049 #ifndef WRONG
   2050 # define WRONG ((time_t)-1)
   2051 #endif /* !defined WRONG */
   2052 
   2053 /*
   2054 ** Normalize logic courtesy Paul Eggert.
   2055 */
   2056 
   2057 static bool
   2058 increment_overflow(int *ip, int j)
   2059 {
   2060 #ifdef ckd_add
   2061 	return ckd_add(ip, *ip, j);
   2062 #else
   2063 	register int const	i = *ip;
   2064 
   2065 	/*
   2066 	** If i >= 0 there can only be overflow if i + j > INT_MAX
   2067 	** or if j > INT_MAX - i; given i >= 0, INT_MAX - i cannot overflow.
   2068 	** If i < 0 there can only be overflow if i + j < INT_MIN
   2069 	** or if j < INT_MIN - i; given i < 0, INT_MIN - i cannot overflow.
   2070 	*/
   2071 	if ((i >= 0) ? (j > INT_MAX - i) : (j < INT_MIN - i))
   2072 		return true;
   2073 	*ip += j;
   2074 	return false;
   2075 #endif
   2076 }
   2077 
   2078 static bool
   2079 increment_overflow_time_iinntt(time_t *tp, iinntt j)
   2080 {
   2081 #ifdef ckd_add
   2082   return ckd_add(tp, *tp, j);
   2083 #else
   2084   if (j < 0
   2085       ? (TYPE_SIGNED(time_t) ? *tp < TIME_T_MIN - j : *tp <= -1 - j)
   2086       : TIME_T_MAX - j < *tp)
   2087     return true;
   2088   *tp += j;
   2089   return false;
   2090 #endif
   2091 }
   2092 
   2093 static bool
   2094 increment_overflow_time(__time_t *tp, int_fast32_t j)
   2095 {
   2096 #ifdef ckd_add
   2097 	return ckd_add(tp, *tp, j);
   2098 #else
   2099 	/*
   2100 	** This is like
   2101 	** 'if (! (TIME_T_MIN <= *tp + j && *tp + j <= TIME_T_MAX)) ...',
   2102 	** except that it does the right thing even if *tp + j would overflow.
   2103 	*/
   2104 	if (! (j < 0
   2105 	       ? (TYPE_SIGNED(time_t) ? TIME_T_MIN - j <= *tp : -1 - j < *tp)
   2106 	       : *tp <= TIME_T_MAX - j))
   2107 		return true;
   2108 	*tp += j;
   2109 	return false;
   2110 #endif
   2111 }
   2112 
   2113 static int
   2114 tmcomp(register const struct tm *const atmp,
   2115        register const struct tm *const btmp)
   2116 {
   2117 	register int	result;
   2118 
   2119 	if (atmp->tm_year != btmp->tm_year)
   2120 		return atmp->tm_year < btmp->tm_year ? -1 : 1;
   2121 	if ((result = (atmp->tm_mon - btmp->tm_mon)) == 0 &&
   2122 		(result = (atmp->tm_mday - btmp->tm_mday)) == 0 &&
   2123 		(result = (atmp->tm_hour - btmp->tm_hour)) == 0 &&
   2124 		(result = (atmp->tm_min - btmp->tm_min)) == 0)
   2125 			result = atmp->tm_sec - btmp->tm_sec;
   2126 	return result;
   2127 }
   2128 
   2129 /* Copy to *DEST from *SRC.  Copy only the members needed for mktime,
   2130    as other members might not be initialized.  */
   2131 static void
   2132 mktmcpy(struct tm *dest, struct tm const *src)
   2133 {
   2134   dest->tm_sec = src->tm_sec;
   2135   dest->tm_min = src->tm_min;
   2136   dest->tm_hour = src->tm_hour;
   2137   dest->tm_mday = src->tm_mday;
   2138   dest->tm_mon = src->tm_mon;
   2139   dest->tm_year = src->tm_year;
   2140   dest->tm_isdst = src->tm_isdst;
   2141 #if defined TM_GMTOFF && ! UNINIT_TRAP
   2142   dest->TM_GMTOFF = src->TM_GMTOFF;
   2143 #endif
   2144 }
   2145 
   2146 static time_t
   2147 time2sub(struct tm *const tmp,
   2148 	 struct tm *(*funcp)(struct state const *, time_t const *,
   2149 			     int_fast32_t, struct tm *),
   2150 	 struct state const *sp,
   2151 	 const int_fast32_t offset,
   2152 	 bool *okayp,
   2153 	 bool do_norm_secs)
   2154 {
   2155 	register int			dir;
   2156 	register int			i, j;
   2157 	register time_t			lo;
   2158 	register time_t			hi;
   2159 #ifdef NO_ERROR_IN_DST_GAP
   2160 	time_t				ilo;
   2161 #endif
   2162 	iinntt y, mday, hour, min, saved_seconds;
   2163 	time_t				newt;
   2164 	time_t				t;
   2165 	struct tm			yourtm, mytm;
   2166 
   2167 	*okayp = false;
   2168 	mktmcpy(&yourtm, tmp);
   2169 
   2170 #ifdef NO_ERROR_IN_DST_GAP
   2171 again:
   2172 #endif
   2173 	min = yourtm.tm_min;
   2174 	if (do_norm_secs) {
   2175 	  min += yourtm.tm_sec / SECSPERMIN;
   2176 	  yourtm.tm_sec %= SECSPERMIN;
   2177 	  if (yourtm.tm_sec < 0) {
   2178 	    yourtm.tm_sec += SECSPERMIN;
   2179 	    min--;
   2180 	  }
   2181 	}
   2182 
   2183 	hour = yourtm.tm_hour;
   2184 	hour += min / MINSPERHOUR;
   2185 	yourtm.tm_min = min % MINSPERHOUR;
   2186 	if (yourtm.tm_min < 0) {
   2187 	  yourtm.tm_min += MINSPERHOUR;
   2188 	  hour--;
   2189 	}
   2190 
   2191 	mday = yourtm.tm_mday;
   2192 	mday += hour / HOURSPERDAY;
   2193 	yourtm.tm_hour = hour % HOURSPERDAY;
   2194 	if (yourtm.tm_hour < 0) {
   2195 	  yourtm.tm_hour += HOURSPERDAY;
   2196 	  mday--;
   2197 	}
   2198 	y = yourtm.tm_year;
   2199 	y += yourtm.tm_mon / MONSPERYEAR;
   2200 	yourtm.tm_mon %= MONSPERYEAR;
   2201 	if (yourtm.tm_mon < 0) {
   2202 	  yourtm.tm_mon += MONSPERYEAR;
   2203 	  y--;
   2204 	}
   2205 
   2206 	/*
   2207 	** Turn y into an actual year number for now.
   2208 	** It is converted back to an offset from TM_YEAR_BASE later.
   2209 	*/
   2210 	y += TM_YEAR_BASE;
   2211 
   2212 	while (mday <= 0) {
   2213 	  iinntt li = y - (yourtm.tm_mon <= 1);
   2214 	  mday += year_lengths[isleap(li)];
   2215 	  y--;
   2216 	}
   2217 	while (DAYSPERLYEAR < mday) {
   2218 	  iinntt li = y + (1 < yourtm.tm_mon);
   2219 	  mday -= year_lengths[isleap(li)];
   2220 	  y++;
   2221 	}
   2222 	yourtm.tm_mday = (int)mday;
   2223 	for ( ; ; ) {
   2224 		i = mon_lengths[isleap(y)][yourtm.tm_mon];
   2225 		if (yourtm.tm_mday <= i)
   2226 			break;
   2227 		yourtm.tm_mday -= i;
   2228 		if (++yourtm.tm_mon >= MONSPERYEAR) {
   2229 			yourtm.tm_mon = 0;
   2230 			y++;
   2231 		}
   2232 	}
   2233 #ifdef ckd_add
   2234 	if (ckd_add(&yourtm.tm_year, y, -TM_YEAR_BASE))
   2235 		goto out_of_range;
   2236 #else
   2237 	y -= TM_YEAR_BASE;
   2238 	if (! (INT_MIN <= y && y <= INT_MAX))
   2239 		goto out_of_range;
   2240 	yourtm.tm_year = (int)y;
   2241 #endif
   2242 	if (yourtm.tm_sec >= 0 && yourtm.tm_sec < SECSPERMIN)
   2243 		saved_seconds = 0;
   2244 	else if (yourtm.tm_year + TM_YEAR_BASE < EPOCH_YEAR) {
   2245 		/*
   2246 		** We can't set tm_sec to 0, because that might push the
   2247 		** time below the minimum representable time.
   2248 		** Set tm_sec to 59 instead.
   2249 		** This assumes that the minimum representable time is
   2250 		** not in the same minute that a leap second was deleted from,
   2251 		** which is a safer assumption than using 58 would be.
   2252 		*/
   2253  		saved_seconds = yourtm.tm_sec;
   2254 		saved_seconds -= SECSPERMIN - 1;
   2255 		yourtm.tm_sec = SECSPERMIN - 1;
   2256 	} else {
   2257 		saved_seconds = yourtm.tm_sec;
   2258 		yourtm.tm_sec = 0;
   2259 	}
   2260 	/*
   2261 	** Do a binary search (this works whatever time_t's type is).
   2262 	*/
   2263 	lo = TIME_T_MIN;
   2264 	hi = TIME_T_MAX;
   2265 #ifdef NO_ERROR_IN_DST_GAP
   2266 	ilo = lo;
   2267 #endif
   2268 	for ( ; ; ) {
   2269 		t = lo / 2 + hi / 2;
   2270 		if (t < lo)
   2271 			t = lo;
   2272 		else if (t > hi)
   2273 			t = hi;
   2274 		if (! funcp(sp, &t, offset, &mytm)) {
   2275 			/*
   2276 			** Assume that t is too extreme to be represented in
   2277 			** a struct tm; arrange things so that it is less
   2278 			** extreme on the next pass.
   2279 			*/
   2280 			dir = (t > 0) ? 1 : -1;
   2281 		} else	dir = tmcomp(&mytm, &yourtm);
   2282 		if (dir != 0) {
   2283 			if (t == lo) {
   2284 				if (t == TIME_T_MAX)
   2285 					goto out_of_range;
   2286 				++t;
   2287 				++lo;
   2288 			} else if (t == hi) {
   2289 				if (t == TIME_T_MIN)
   2290 					goto out_of_range;
   2291 				--t;
   2292 				--hi;
   2293 			}
   2294 #ifdef NO_ERROR_IN_DST_GAP
   2295 			if (ilo != lo && lo - 1 == hi && yourtm.tm_isdst < 0 &&
   2296 			    do_norm_secs) {
   2297 				for (i = sp->typecnt - 1; i >= 0; --i) {
   2298 					for (j = sp->typecnt - 1; j >= 0; --j) {
   2299 						time_t off;
   2300 						if (sp->ttis[j].tt_isdst ==
   2301 						    sp->ttis[i].tt_isdst)
   2302 							continue;
   2303 						if (ttunspecified(sp, j))
   2304 							continue;
   2305 						off = sp->ttis[j].tt_utoff -
   2306 						    sp->ttis[i].tt_utoff;
   2307 						yourtm.tm_sec += off < 0 ?
   2308 						    -off : off;
   2309 						goto again;
   2310 					}
   2311 				}
   2312 			}
   2313 #endif
   2314 			if (lo > hi)
   2315 				goto invalid;
   2316 			if (dir > 0)
   2317 				hi = t;
   2318 			else	lo = t;
   2319 			continue;
   2320 		}
   2321 #if defined TM_GMTOFF && ! UNINIT_TRAP
   2322 		if (mytm.TM_GMTOFF != yourtm.TM_GMTOFF
   2323 		    && (yourtm.TM_GMTOFF < 0
   2324 			? (-SECSPERDAY <= yourtm.TM_GMTOFF
   2325 			   && (mytm.TM_GMTOFF <=
   2326 			       /*CONSTCOND*/
   2327 			       (min(INT_FAST32_MAX, LONG_MAX)
   2328 				+ yourtm.TM_GMTOFF)))
   2329 			: (yourtm.TM_GMTOFF <= SECSPERDAY
   2330 			       /*CONSTCOND*/
   2331 			   && ((max(INT_FAST32_MIN, LONG_MIN)
   2332 				+ yourtm.TM_GMTOFF)
   2333 			       <= mytm.TM_GMTOFF)))) {
   2334 		  /* MYTM matches YOURTM except with the wrong UT offset.
   2335 		     YOURTM.TM_GMTOFF is plausible, so try it instead.
   2336 		     It's OK if YOURTM.TM_GMTOFF contains uninitialized data,
   2337 		     since the guess gets checked.  */
   2338 		  __time_t altt = t;
   2339 		  int_fast32_t diff = (int_fast32_t)
   2340 		      (mytm.TM_GMTOFF - yourtm.TM_GMTOFF);
   2341 		  if (!increment_overflow_time(&altt, diff)) {
   2342 		    struct tm alttm;
   2343 		    time_t xaltt = (time_t)altt;
   2344 		    if (funcp(sp, &xaltt, offset, &alttm)
   2345 			&& alttm.tm_isdst == mytm.tm_isdst
   2346 			&& alttm.TM_GMTOFF == yourtm.TM_GMTOFF
   2347 			&& tmcomp(&alttm, &yourtm) == 0) {
   2348 		      t = xaltt;
   2349 		      mytm = alttm;
   2350 		    }
   2351 		  }
   2352 		}
   2353 #endif
   2354 		if (yourtm.tm_isdst < 0 || mytm.tm_isdst == yourtm.tm_isdst)
   2355 			break;
   2356 		/*
   2357 		** Right time, wrong type.
   2358 		** Hunt for right time, right type.
   2359 		** It's okay to guess wrong since the guess
   2360 		** gets checked.
   2361 		*/
   2362 		if (sp == NULL)
   2363 			goto invalid;
   2364 		for (i = sp->typecnt - 1; i >= 0; --i) {
   2365 			if (sp->ttis[i].tt_isdst != yourtm.tm_isdst)
   2366 				continue;
   2367 			for (j = sp->typecnt - 1; j >= 0; --j) {
   2368 				if (sp->ttis[j].tt_isdst == yourtm.tm_isdst)
   2369 					continue;
   2370 				if (ttunspecified(sp, j))
   2371 				  continue;
   2372 				newt = (time_t)(t + sp->ttis[j].tt_utoff -
   2373 				    sp->ttis[i].tt_utoff);
   2374 				if (! funcp(sp, &newt, offset, &mytm))
   2375 					continue;
   2376 				if (tmcomp(&mytm, &yourtm) != 0)
   2377 					continue;
   2378 				if (mytm.tm_isdst != yourtm.tm_isdst)
   2379 					continue;
   2380 				/*
   2381 				** We have a match.
   2382 				*/
   2383 				t = newt;
   2384 				goto label;
   2385 			}
   2386 		}
   2387 		goto invalid;
   2388 	}
   2389 label:
   2390 	if (increment_overflow_time_iinntt(&t, saved_seconds))
   2391  		return WRONG;
   2392 	if (funcp(sp, &t, offset, tmp)) {
   2393 		*okayp = true;
   2394 		return t;
   2395 	}
   2396 out_of_range:
   2397 	errno = EOVERFLOW;
   2398 	return WRONG;
   2399 invalid:
   2400 	errno = EINVAL;
   2401 	return WRONG;
   2402 }
   2403 
   2404 static time_t
   2405 time2(struct tm * const	tmp,
   2406       struct tm *(*funcp)(struct state const *, time_t const *,
   2407 			  int_fast32_t, struct tm *),
   2408       struct state const *sp,
   2409       const int_fast32_t offset,
   2410       bool *okayp)
   2411 {
   2412 	time_t	t;
   2413 
   2414 	/*
   2415 	** First try without normalization of seconds
   2416 	** (in case tm_sec contains a value associated with a leap second).
   2417 	** If that fails, try with normalization of seconds.
   2418 	*/
   2419 	t = time2sub(tmp, funcp, sp, offset, okayp, false);
   2420 	return *okayp ? t : time2sub(tmp, funcp, sp, offset, okayp, true);
   2421 }
   2422 
   2423 static time_t
   2424 time1(struct tm *const tmp,
   2425       struct tm *(*funcp)(struct state const *, time_t const *,
   2426 			  int_fast32_t, struct tm *),
   2427       struct state const *sp,
   2428       const int_fast32_t offset)
   2429 {
   2430 	register time_t			t;
   2431 	register int			samei, otheri;
   2432 	register int			sameind, otherind;
   2433 	register int			i;
   2434 	register int			nseen;
   2435 	int				save_errno;
   2436 	char				seen[TZ_MAX_TYPES];
   2437 	unsigned char			types[TZ_MAX_TYPES];
   2438 	bool				okay;
   2439 
   2440 	if (tmp == NULL) {
   2441 		errno = EINVAL;
   2442 		return WRONG;
   2443 	}
   2444 	if (tmp->tm_isdst > 1)
   2445 		tmp->tm_isdst = 1;
   2446 	save_errno = errno;
   2447 	t = time2(tmp, funcp, sp, offset, &okay);
   2448 	if (okay) {
   2449 		errno = save_errno;
   2450 		return t;
   2451 	}
   2452 	if (tmp->tm_isdst < 0)
   2453 #ifdef PCTS
   2454 		/*
   2455 		** POSIX Conformance Test Suite code courtesy Grant Sullivan.
   2456 		*/
   2457 		tmp->tm_isdst = 0;	/* reset to std and try again */
   2458 #else
   2459 		return t;
   2460 #endif /* !defined PCTS */
   2461 	/*
   2462 	** We're supposed to assume that somebody took a time of one type
   2463 	** and did some math on it that yielded a "struct tm" that's bad.
   2464 	** We try to divine the type they started from and adjust to the
   2465 	** type they need.
   2466 	*/
   2467 	if (sp == NULL) {
   2468 		errno = EINVAL;
   2469 		return WRONG;
   2470 	}
   2471 	for (i = 0; i < sp->typecnt; ++i)
   2472 		seen[i] = false;
   2473 	nseen = 0;
   2474 	for (i = sp->timecnt - 1; i >= 0; --i)
   2475 		if (!seen[sp->types[i]] && !ttunspecified(sp, sp->types[i])) {
   2476 			seen[sp->types[i]] = true;
   2477 			types[nseen++] = sp->types[i];
   2478 		}
   2479 	for (sameind = 0; sameind < nseen; ++sameind) {
   2480 		samei = types[sameind];
   2481 		if (sp->ttis[samei].tt_isdst != tmp->tm_isdst)
   2482 			continue;
   2483 		for (otherind = 0; otherind < nseen; ++otherind) {
   2484 			otheri = types[otherind];
   2485 			if (sp->ttis[otheri].tt_isdst == tmp->tm_isdst)
   2486 				continue;
   2487 			tmp->tm_sec += (int)(sp->ttis[otheri].tt_utoff
   2488 					- sp->ttis[samei].tt_utoff);
   2489 			tmp->tm_isdst = !tmp->tm_isdst;
   2490 			t = time2(tmp, funcp, sp, offset, &okay);
   2491 			if (okay) {
   2492 				errno = save_errno;
   2493 				return t;
   2494 			}
   2495 			tmp->tm_sec -= (int)(sp->ttis[otheri].tt_utoff
   2496 					- sp->ttis[samei].tt_utoff);
   2497 			tmp->tm_isdst = !tmp->tm_isdst;
   2498 		}
   2499 	}
   2500 	errno = EOVERFLOW;
   2501 	return WRONG;
   2502 }
   2503 
   2504 #if !defined TM_GMTOFF || !USE_TIMEX_T
   2505 
   2506 static time_t
   2507 mktime_tzname(struct state *sp, struct tm *tmp, bool setname)
   2508 {
   2509   if (sp)
   2510     return time1(tmp, localsub, sp, setname);
   2511   else {
   2512     gmtcheck();
   2513     return time1(tmp, gmtsub, gmtptr, 0);
   2514   }
   2515 }
   2516 
   2517 # if USE_TIMEX_T
   2518 static
   2519 # endif
   2520 time_t
   2521 mktime(struct tm *tmp)
   2522 {
   2523   time_t t;
   2524   int err = lock();
   2525   if (err) {
   2526     errno = err;
   2527     return -1;
   2528   }
   2529   tzset_unlocked();
   2530   t = mktime_tzname(__lclptr, tmp, true);
   2531   unlock();
   2532   return t;
   2533 }
   2534 
   2535 #endif
   2536 
   2537 #if NETBSD_INSPIRED && !USE_TIMEX_T
   2538 time_t
   2539 mktime_z(struct state *restrict sp, struct tm *restrict tmp)
   2540 {
   2541   return mktime_tzname(sp, tmp, false);
   2542 }
   2543 #endif
   2544 
   2545 #if STD_INSPIRED && !USE_TIMEX_T
   2546 /* This function is obsolescent and may disappear in future releases.
   2547    Callers can instead use mktime.  */
   2548 time_t
   2549 timelocal_z(const timezone_t sp, struct tm *const tmp)
   2550 {
   2551 	if (tmp != NULL)
   2552 		tmp->tm_isdst = -1;	/* in case it wasn't initialized */
   2553 	return mktime_z(sp, tmp);
   2554 }
   2555 
   2556 time_t
   2557 timelocal(struct tm *tmp)
   2558 {
   2559 	if (tmp != NULL)
   2560 		tmp->tm_isdst = -1;	/* in case it wasn't initialized */
   2561 	return mktime(tmp);
   2562 }
   2563 #endif
   2564 
   2565 #if defined TM_GMTOFF || !USE_TIMEX_T
   2566 
   2567 # ifndef EXTERN_TIMEOFF
   2568 #  ifndef timeoff
   2569 #   define timeoff my_timeoff /* Don't collide with OpenBSD 7.4 <time.h>.  */
   2570 #  endif
   2571 #  define EXTERN_TIMEOFF static
   2572 # endif
   2573 
   2574 /* This function is obsolescent and may disappear in future releases.
   2575    Callers can instead use mktime_z with a fixed-offset zone.  */
   2576 EXTERN_TIMEOFF time_t
   2577 timeoff(struct tm *tmp, long offset)
   2578 {
   2579   if (tmp)
   2580     tmp->tm_isdst = 0;
   2581   gmtcheck();
   2582   return time1(tmp, gmtsub, gmtptr, (int_fast32_t)offset);
   2583 }
   2584 #endif
   2585 
   2586 #if !USE_TIMEX_T
   2587 time_t
   2588 timegm(struct tm *tmp)
   2589 {
   2590   time_t t;
   2591   struct tm tmcpy;
   2592   mktmcpy(&tmcpy, tmp);
   2593   tmcpy.tm_wday = -1;
   2594   t = timeoff(&tmcpy, 0);
   2595   if (0 <= tmcpy.tm_wday)
   2596     *tmp = tmcpy;
   2597   return t;
   2598 }
   2599 #endif
   2600 
   2601 static int_fast32_t
   2602 leapcorr(struct state const *sp, __time_t t)
   2603 {
   2604 	register struct lsinfo const *	lp;
   2605 	register int			i;
   2606 
   2607 	i = sp->leapcnt;
   2608 	while (--i >= 0) {
   2609 		lp = &sp->lsis[i];
   2610 		if (t >= lp->ls_trans)
   2611 			return lp->ls_corr;
   2612 	}
   2613 	return 0;
   2614 }
   2615 
   2616 /*
   2617 ** XXX--is the below the right way to conditionalize??
   2618 */
   2619 
   2620 #if !USE_TIMEX_T
   2621 # if STD_INSPIRED
   2622 
   2623 /* NETBSD_INSPIRED_EXTERN functions are exported to callers if
   2624    NETBSD_INSPIRED is defined, and are private otherwise.  */
   2625 #  if NETBSD_INSPIRED
   2626 #   define NETBSD_INSPIRED_EXTERN
   2627 #  else
   2628 #   define NETBSD_INSPIRED_EXTERN static
   2629 #  endif
   2630 
   2631 /*
   2632 ** IEEE Std 1003.1 (POSIX) says that 536457599
   2633 ** shall correspond to "Wed Dec 31 23:59:59 UTC 1986", which
   2634 ** is not the case if we are accounting for leap seconds.
   2635 ** So, we provide the following conversion routines for use
   2636 ** when exchanging timestamps with POSIX conforming systems.
   2637 */
   2638 
   2639 NETBSD_INSPIRED_EXTERN time_t
   2640 time2posix_z(struct state *sp, time_t t)
   2641 {
   2642   return (time_t)(t - leapcorr(sp, t));
   2643 }
   2644 
   2645 time_t
   2646 time2posix(time_t t)
   2647 {
   2648   int err = lock();
   2649   if (err) {
   2650     errno = err;
   2651     return -1;
   2652   }
   2653   if (!lcl_is_set)
   2654     tzset_unlocked();
   2655   if (__lclptr)
   2656     t = (time_t)(t - leapcorr(__lclptr, t));
   2657   unlock();
   2658   return t;
   2659 }
   2660 
   2661 NETBSD_INSPIRED_EXTERN time_t
   2662 posix2time_z(struct state *sp, time_t t)
   2663 {
   2664 	time_t	x;
   2665 	time_t	y;
   2666 	/*
   2667 	** For a positive leap second hit, the result
   2668 	** is not unique. For a negative leap second
   2669 	** hit, the corresponding time doesn't exist,
   2670 	** so we return an adjacent second.
   2671 	*/
   2672 	x = (time_t)(t + leapcorr(sp, t));
   2673 	y = (time_t)(x - leapcorr(sp, x));
   2674 	if (y < t) {
   2675 		do {
   2676 			x++;
   2677 			y = (time_t)(x - leapcorr(sp, x));
   2678 		} while (y < t);
   2679 		x -= y != t;
   2680 	} else if (y > t) {
   2681 		do {
   2682 			--x;
   2683 			y = (time_t)(x - leapcorr(sp, x));
   2684 		} while (y > t);
   2685 		x += y != t;
   2686 	}
   2687 	return x;
   2688 }
   2689 
   2690 time_t
   2691 posix2time(time_t t)
   2692 {
   2693   int err = lock();
   2694   if (err) {
   2695     errno = err;
   2696     return -1;
   2697   }
   2698   if (!lcl_is_set)
   2699     tzset_unlocked();
   2700   if (__lclptr)
   2701     t = posix2time_z(__lclptr, t);
   2702   unlock();
   2703   return t;
   2704 }
   2705 
   2706 # endif /* STD_INSPIRED */
   2707 
   2708 # if TZ_TIME_T
   2709 
   2710 #  if !USG_COMPAT
   2711 #   define timezone 0
   2712 #  endif
   2713 
   2714 /* Convert from the underlying system's time_t to the ersatz time_tz,
   2715    which is called 'time_t' in this file.  Typically, this merely
   2716    converts the time's integer width.  On some platforms, the system
   2717    time is local time not UT, or uses some epoch other than the POSIX
   2718    epoch.
   2719 
   2720    Although this code appears to define a function named 'time' that
   2721    returns time_t, the macros in private.h cause this code to actually
   2722    define a function named 'tz_time' that returns tz_time_t.  The call
   2723    to sys_time invokes the underlying system's 'time' function.  */
   2724 
   2725 time_t
   2726 time(time_t *p)
   2727 {
   2728   __time_t r = sys_time(0);
   2729   if (r != (time_t) -1) {
   2730     iinntt offset = EPOCH_LOCAL ? (daylight ? timezone : altzone) : 0;
   2731     if (offset < IINNTT_MIN + EPOCH_OFFSET
   2732 	|| increment_overflow_time_iinntt(&r, offset - EPOCH_OFFSET)) {
   2733       errno = EOVERFLOW;
   2734       r = -1;
   2735     }
   2736   }
   2737   if (p)
   2738     *p = (time_t)r;
   2739   return (time_t)r;
   2740 }
   2741 
   2742 # endif
   2743 #endif
   2744 
   2745