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