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