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