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