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