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