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