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