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