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