xref: /netbsd-src/lib/libc/time/localtime.c (revision d909946ca08dceb44d7d0f22ec9488679695d976)
1 /*	$NetBSD: localtime.c,v 1.103 2016/03/18 12:41:25 ginsbach 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.103 2016/03/18 12:41:25 ginsbach 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 	** "UT+xxxx" or "UT-xxxx" 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 /*
1609 ** Return the number of leap years through the end of the given year
1610 ** where, to make the math easy, the answer for year zero is defined as zero.
1611 */
1612 
1613 static int ATTRIBUTE_PURE
1614 leaps_thru_end_of(const int y)
1615 {
1616 	return (y >= 0) ? (y / 4 - y / 100 + y / 400) :
1617 		-(leaps_thru_end_of(-(y + 1)) + 1);
1618 }
1619 
1620 static struct tm *
1621 timesub(const time_t *timep, int_fast32_t offset,
1622     const struct state *sp, struct tm *tmp)
1623 {
1624 	const struct lsinfo *	lp;
1625 	time_t			tdays;
1626 	int			idays;	/* unsigned would be so 2003 */
1627 	int_fast64_t		rem;
1628 	int			y;
1629 	const int *		ip;
1630 	int_fast64_t		corr;
1631 	bool			hit;
1632 	int			i;
1633 
1634 	corr = 0;
1635 	hit = false;
1636 	i = (sp == NULL) ? 0 : sp->leapcnt;
1637 	while (--i >= 0) {
1638 		lp = &sp->lsis[i];
1639 		if (*timep >= lp->ls_trans) {
1640 			if (*timep == lp->ls_trans) {
1641 				hit = ((i == 0 && lp->ls_corr > 0) ||
1642 					lp->ls_corr > sp->lsis[i - 1].ls_corr);
1643 				if (hit)
1644 					while (i > 0 &&
1645 						sp->lsis[i].ls_trans ==
1646 						sp->lsis[i - 1].ls_trans + 1 &&
1647 						sp->lsis[i].ls_corr ==
1648 						sp->lsis[i - 1].ls_corr + 1) {
1649 							++hit;
1650 							--i;
1651 					}
1652 			}
1653 			corr = lp->ls_corr;
1654 			break;
1655 		}
1656 	}
1657 	y = EPOCH_YEAR;
1658 	tdays = (time_t)(*timep / SECSPERDAY);
1659 	rem = *timep % SECSPERDAY;
1660 	while (tdays < 0 || tdays >= year_lengths[isleap(y)]) {
1661 		int		newy;
1662 		time_t	tdelta;
1663 		int	idelta;
1664 		int	leapdays;
1665 
1666 		tdelta = tdays / DAYSPERLYEAR;
1667 		if (! ((! TYPE_SIGNED(time_t) || INT_MIN <= tdelta)
1668 		       && tdelta <= INT_MAX))
1669 			goto out_of_range;
1670 		_DIAGASSERT(__type_fit(int, tdelta));
1671 		idelta = (int)tdelta;
1672 		if (idelta == 0)
1673 			idelta = (tdays < 0) ? -1 : 1;
1674 		newy = y;
1675 		if (increment_overflow(&newy, idelta))
1676 			goto out_of_range;
1677 		leapdays = leaps_thru_end_of(newy - 1) -
1678 			leaps_thru_end_of(y - 1);
1679 		tdays -= ((time_t) newy - y) * DAYSPERNYEAR;
1680 		tdays -= leapdays;
1681 		y = newy;
1682 	}
1683 	/*
1684 	** Given the range, we can now fearlessly cast...
1685 	*/
1686 	idays = (int) tdays;
1687 	rem += offset - corr;
1688 	while (rem < 0) {
1689 		rem += SECSPERDAY;
1690 		--idays;
1691 	}
1692 	while (rem >= SECSPERDAY) {
1693 		rem -= SECSPERDAY;
1694 		++idays;
1695 	}
1696 	while (idays < 0) {
1697 		if (increment_overflow(&y, -1))
1698 			goto out_of_range;
1699 		idays += year_lengths[isleap(y)];
1700 	}
1701 	while (idays >= year_lengths[isleap(y)]) {
1702 		idays -= year_lengths[isleap(y)];
1703 		if (increment_overflow(&y, 1))
1704 			goto out_of_range;
1705 	}
1706 	tmp->tm_year = y;
1707 	if (increment_overflow(&tmp->tm_year, -TM_YEAR_BASE))
1708 		goto out_of_range;
1709 	tmp->tm_yday = idays;
1710 	/*
1711 	** The "extra" mods below avoid overflow problems.
1712 	*/
1713 	tmp->tm_wday = EPOCH_WDAY +
1714 		((y - EPOCH_YEAR) % DAYSPERWEEK) *
1715 		(DAYSPERNYEAR % DAYSPERWEEK) +
1716 		leaps_thru_end_of(y - 1) -
1717 		leaps_thru_end_of(EPOCH_YEAR - 1) +
1718 		idays;
1719 	tmp->tm_wday %= DAYSPERWEEK;
1720 	if (tmp->tm_wday < 0)
1721 		tmp->tm_wday += DAYSPERWEEK;
1722 	tmp->tm_hour = (int) (rem / SECSPERHOUR);
1723 	rem %= SECSPERHOUR;
1724 	tmp->tm_min = (int) (rem / SECSPERMIN);
1725 	/*
1726 	** A positive leap second requires a special
1727 	** representation. This uses "... ??:59:60" et seq.
1728 	*/
1729 	tmp->tm_sec = (int) (rem % SECSPERMIN) + hit;
1730 	ip = mon_lengths[isleap(y)];
1731 	for (tmp->tm_mon = 0; idays >= ip[tmp->tm_mon]; ++(tmp->tm_mon))
1732 		idays -= ip[tmp->tm_mon];
1733 	tmp->tm_mday = (int) (idays + 1);
1734 	tmp->tm_isdst = 0;
1735 #ifdef TM_GMTOFF
1736 	tmp->TM_GMTOFF = offset;
1737 #endif /* defined TM_GMTOFF */
1738 	return tmp;
1739 out_of_range:
1740 	errno = EOVERFLOW;
1741 	return NULL;
1742 }
1743 
1744 char *
1745 ctime(const time_t *timep)
1746 {
1747 /*
1748 ** Section 4.12.3.2 of X3.159-1989 requires that
1749 **	The ctime function converts the calendar time pointed to by timer
1750 **	to local time in the form of a string. It is equivalent to
1751 **		asctime(localtime(timer))
1752 */
1753 	struct tm *tmp = localtime(timep);
1754 	return tmp ? asctime(tmp) : NULL;
1755 }
1756 
1757 char *
1758 ctime_r(const time_t *timep, char *buf)
1759 {
1760 	struct tm mytm;
1761 	struct tm *tmp = localtime_r(timep, &mytm);
1762 	return tmp ? asctime_r(tmp, buf) : NULL;
1763 }
1764 
1765 char *
1766 ctime_rz(const timezone_t sp, const time_t * timep, char *buf)
1767 {
1768 	struct tm	mytm, *rtm;
1769 
1770 	rtm = localtime_rz(sp, timep, &mytm);
1771 	if (rtm == NULL)
1772 		return NULL;
1773 	return asctime_r(rtm, buf);
1774 }
1775 
1776 /*
1777 ** Adapted from code provided by Robert Elz, who writes:
1778 **	The "best" way to do mktime I think is based on an idea of Bob
1779 **	Kridle's (so its said...) from a long time ago.
1780 **	It does a binary search of the time_t space. Since time_t's are
1781 **	just 32 bits, its a max of 32 iterations (even at 64 bits it
1782 **	would still be very reasonable).
1783 */
1784 
1785 #ifndef WRONG
1786 #define WRONG	((time_t)-1)
1787 #endif /* !defined WRONG */
1788 
1789 /*
1790 ** Normalize logic courtesy Paul Eggert.
1791 */
1792 
1793 static bool
1794 increment_overflow(int *ip, int j)
1795 {
1796 	int const	i = *ip;
1797 
1798 	/*
1799 	** If i >= 0 there can only be overflow if i + j > INT_MAX
1800 	** or if j > INT_MAX - i; given i >= 0, INT_MAX - i cannot overflow.
1801 	** If i < 0 there can only be overflow if i + j < INT_MIN
1802 	** or if j < INT_MIN - i; given i < 0, INT_MIN - i cannot overflow.
1803 	*/
1804 	if ((i >= 0) ? (j > INT_MAX - i) : (j < INT_MIN - i))
1805 		return true;
1806 	*ip += j;
1807 	return false;
1808 }
1809 
1810 static bool
1811 increment_overflow32(int_fast32_t *const lp, int const m)
1812 {
1813 	int_fast32_t const l = *lp;
1814 
1815 	if ((l >= 0) ? (m > INT_FAST32_MAX - l) : (m < INT_FAST32_MIN - l))
1816 		return true;
1817 	*lp += m;
1818 	return false;
1819 }
1820 
1821 static bool
1822 increment_overflow_time(time_t *tp, int_fast32_t j)
1823 {
1824 	/*
1825 	** This is like
1826 	** 'if (! (time_t_min <= *tp + j && *tp + j <= time_t_max)) ...',
1827 	** except that it does the right thing even if *tp + j would overflow.
1828 	*/
1829 	if (! (j < 0
1830 	       ? (TYPE_SIGNED(time_t) ? time_t_min - j <= *tp : -1 - j < *tp)
1831 	       : *tp <= time_t_max - j))
1832 		return true;
1833 	*tp += j;
1834 	return false;
1835 }
1836 
1837 static bool
1838 normalize_overflow(int *const tensptr, int *const unitsptr, const int base)
1839 {
1840 	int	tensdelta;
1841 
1842 	tensdelta = (*unitsptr >= 0) ?
1843 		(*unitsptr / base) :
1844 		(-1 - (-1 - *unitsptr) / base);
1845 	*unitsptr -= tensdelta * base;
1846 	return increment_overflow(tensptr, tensdelta);
1847 }
1848 
1849 static bool
1850 normalize_overflow32(int_fast32_t *tensptr, int *unitsptr, int base)
1851 {
1852 	int	tensdelta;
1853 
1854 	tensdelta = (*unitsptr >= 0) ?
1855 		(*unitsptr / base) :
1856 		(-1 - (-1 - *unitsptr) / base);
1857 	*unitsptr -= tensdelta * base;
1858 	return increment_overflow32(tensptr, tensdelta);
1859 }
1860 
1861 static int
1862 tmcomp(const struct tm *const atmp,
1863        const struct tm *const btmp)
1864 {
1865 	int	result;
1866 
1867 	if (atmp->tm_year != btmp->tm_year)
1868 		return atmp->tm_year < btmp->tm_year ? -1 : 1;
1869 	if ((result = (atmp->tm_mon - btmp->tm_mon)) == 0 &&
1870 		(result = (atmp->tm_mday - btmp->tm_mday)) == 0 &&
1871 		(result = (atmp->tm_hour - btmp->tm_hour)) == 0 &&
1872 		(result = (atmp->tm_min - btmp->tm_min)) == 0)
1873 			result = atmp->tm_sec - btmp->tm_sec;
1874 	return result;
1875 }
1876 
1877 static time_t
1878 time2sub(struct tm *const tmp,
1879 	 struct tm *(*funcp)(struct state const *, time_t const *,
1880 			     int_fast32_t, struct tm *),
1881 	 struct state const *sp,
1882  	 const int_fast32_t offset,
1883 	 bool *okayp,
1884 	 bool do_norm_secs)
1885 {
1886 	int			dir;
1887 	int			i, j;
1888 	int			saved_seconds;
1889 	int_fast32_t		li;
1890 	time_t			lo;
1891 	time_t			hi;
1892 #ifdef NO_ERROR_IN_DST_GAP
1893 	time_t			ilo;
1894 #endif
1895 	int_fast32_t		y;
1896 	time_t			newt;
1897 	time_t			t;
1898 	struct tm		yourtm, mytm;
1899 
1900 	*okayp = false;
1901 	yourtm = *tmp;
1902 #ifdef NO_ERROR_IN_DST_GAP
1903 again:
1904 #endif
1905 	if (do_norm_secs) {
1906 		if (normalize_overflow(&yourtm.tm_min, &yourtm.tm_sec,
1907 		    SECSPERMIN))
1908 			goto out_of_range;
1909 	}
1910 	if (normalize_overflow(&yourtm.tm_hour, &yourtm.tm_min, MINSPERHOUR))
1911 		goto out_of_range;
1912 	if (normalize_overflow(&yourtm.tm_mday, &yourtm.tm_hour, HOURSPERDAY))
1913 		goto out_of_range;
1914 	y = yourtm.tm_year;
1915 	if (normalize_overflow32(&y, &yourtm.tm_mon, MONSPERYEAR))
1916 		goto out_of_range;
1917 	/*
1918 	** Turn y into an actual year number for now.
1919 	** It is converted back to an offset from TM_YEAR_BASE later.
1920 	*/
1921 	if (increment_overflow32(&y, TM_YEAR_BASE))
1922 		goto out_of_range;
1923 	while (yourtm.tm_mday <= 0) {
1924 		if (increment_overflow32(&y, -1))
1925 			goto out_of_range;
1926 		li = y + (1 < yourtm.tm_mon);
1927 		yourtm.tm_mday += year_lengths[isleap(li)];
1928 	}
1929 	while (yourtm.tm_mday > DAYSPERLYEAR) {
1930 		li = y + (1 < yourtm.tm_mon);
1931 		yourtm.tm_mday -= year_lengths[isleap(li)];
1932 		if (increment_overflow32(&y, 1))
1933 			goto out_of_range;
1934 	}
1935 	for ( ; ; ) {
1936 		i = mon_lengths[isleap(y)][yourtm.tm_mon];
1937 		if (yourtm.tm_mday <= i)
1938 			break;
1939 		yourtm.tm_mday -= i;
1940 		if (++yourtm.tm_mon >= MONSPERYEAR) {
1941 			yourtm.tm_mon = 0;
1942 			if (increment_overflow32(&y, 1))
1943 				goto out_of_range;
1944 		}
1945 	}
1946 	if (increment_overflow32(&y, -TM_YEAR_BASE))
1947 		goto out_of_range;
1948 	if (! (INT_MIN <= y && y <= INT_MAX))
1949 		goto out_of_range;
1950 	yourtm.tm_year = (int)y;
1951 	if (yourtm.tm_sec >= 0 && yourtm.tm_sec < SECSPERMIN)
1952 		saved_seconds = 0;
1953 	else if (y + TM_YEAR_BASE < EPOCH_YEAR) {
1954 		/*
1955 		** We can't set tm_sec to 0, because that might push the
1956 		** time below the minimum representable time.
1957 		** Set tm_sec to 59 instead.
1958 		** This assumes that the minimum representable time is
1959 		** not in the same minute that a leap second was deleted from,
1960 		** which is a safer assumption than using 58 would be.
1961 		*/
1962 		if (increment_overflow(&yourtm.tm_sec, 1 - SECSPERMIN))
1963 			goto out_of_range;
1964 		saved_seconds = yourtm.tm_sec;
1965 		yourtm.tm_sec = SECSPERMIN - 1;
1966 	} else {
1967 		saved_seconds = yourtm.tm_sec;
1968 		yourtm.tm_sec = 0;
1969 	}
1970 	/*
1971 	** Do a binary search (this works whatever time_t's type is).
1972 	*/
1973 	lo = time_t_min;
1974 	hi = time_t_max;
1975 #ifdef NO_ERROR_IN_DST_GAP
1976 	ilo = lo;
1977 #endif
1978 	for ( ; ; ) {
1979 		t = lo / 2 + hi / 2;
1980 		if (t < lo)
1981 			t = lo;
1982 		else if (t > hi)
1983 			t = hi;
1984 		if (! funcp(sp, &t, offset, &mytm)) {
1985 			/*
1986 			** Assume that t is too extreme to be represented in
1987 			** a struct tm; arrange things so that it is less
1988 			** extreme on the next pass.
1989 			*/
1990 			dir = (t > 0) ? 1 : -1;
1991 		} else	dir = tmcomp(&mytm, &yourtm);
1992 		if (dir != 0) {
1993 			if (t == lo) {
1994 				if (t == time_t_max)
1995 					goto out_of_range;
1996 				++t;
1997 				++lo;
1998 			} else if (t == hi) {
1999 				if (t == time_t_min)
2000 					goto out_of_range;
2001 				--t;
2002 				--hi;
2003 			}
2004 #ifdef NO_ERROR_IN_DST_GAP
2005 			if (ilo != lo && lo - 1 == hi && yourtm.tm_isdst < 0 &&
2006 			    do_norm_secs) {
2007 				for (i = sp->typecnt - 1; i >= 0; --i) {
2008 					for (j = sp->typecnt - 1; j >= 0; --j) {
2009 						time_t off;
2010 						if (sp->ttis[j].tt_isdst ==
2011 						    sp->ttis[i].tt_isdst)
2012 							continue;
2013 						off = sp->ttis[j].tt_gmtoff -
2014 						    sp->ttis[i].tt_gmtoff;
2015 						yourtm.tm_sec += off < 0 ?
2016 						    -off : off;
2017 						goto again;
2018 					}
2019 				}
2020 			}
2021 #endif
2022 			if (lo > hi)
2023 				goto invalid;
2024 			if (dir > 0)
2025 				hi = t;
2026 			else	lo = t;
2027 			continue;
2028 		}
2029 #if defined TM_GMTOFF && ! UNINIT_TRAP
2030 		if (mytm.TM_GMTOFF != yourtm.TM_GMTOFF
2031 		    && (yourtm.TM_GMTOFF < 0
2032 			? (-SECSPERDAY <= yourtm.TM_GMTOFF
2033 			   && (mytm.TM_GMTOFF <=
2034 			       (/*CONSTCOND*/SMALLEST (INT_FAST32_MAX, LONG_MAX)
2035 				+ yourtm.TM_GMTOFF)))
2036 			: (yourtm.TM_GMTOFF <= SECSPERDAY
2037 			   && ((/*CONSTCOND*/BIGGEST (INT_FAST32_MIN, LONG_MIN)
2038 				+ yourtm.TM_GMTOFF)
2039 			       <= mytm.TM_GMTOFF)))) {
2040 		  /* MYTM matches YOURTM except with the wrong UTC offset.
2041 		     YOURTM.TM_GMTOFF is plausible, so try it instead.
2042 		     It's OK if YOURTM.TM_GMTOFF contains uninitialized data,
2043 		     since the guess gets checked.  */
2044 		  time_t altt = t;
2045 		  int_fast32_t diff = (int_fast32_t)
2046 		      (mytm.TM_GMTOFF - yourtm.TM_GMTOFF);
2047 		  if (!increment_overflow_time(&altt, diff)) {
2048 		    struct tm alttm;
2049 		    if (! funcp(sp, &altt, offset, &alttm)
2050 			&& alttm.tm_isdst == mytm.tm_isdst
2051 			&& alttm.TM_GMTOFF == yourtm.TM_GMTOFF
2052 			&& tmcomp(&alttm, &yourtm)) {
2053 		      t = altt;
2054 		      mytm = alttm;
2055 		    }
2056 		  }
2057 		}
2058 #endif
2059 		if (yourtm.tm_isdst < 0 || mytm.tm_isdst == yourtm.tm_isdst)
2060 			break;
2061 		/*
2062 		** Right time, wrong type.
2063 		** Hunt for right time, right type.
2064 		** It's okay to guess wrong since the guess
2065 		** gets checked.
2066 		*/
2067 		if (sp == NULL)
2068 			goto invalid;
2069 		for (i = sp->typecnt - 1; i >= 0; --i) {
2070 			if (sp->ttis[i].tt_isdst != yourtm.tm_isdst)
2071 				continue;
2072 			for (j = sp->typecnt - 1; j >= 0; --j) {
2073 				if (sp->ttis[j].tt_isdst == yourtm.tm_isdst)
2074 					continue;
2075 				newt = (time_t)(t + sp->ttis[j].tt_gmtoff -
2076 				    sp->ttis[i].tt_gmtoff);
2077 				if (! funcp(sp, &newt, offset, &mytm))
2078 					continue;
2079 				if (tmcomp(&mytm, &yourtm) != 0)
2080 					continue;
2081 				if (mytm.tm_isdst != yourtm.tm_isdst)
2082 					continue;
2083 				/*
2084 				** We have a match.
2085 				*/
2086 				t = newt;
2087 				goto label;
2088 			}
2089 		}
2090 		goto invalid;
2091 	}
2092 label:
2093 	newt = t + saved_seconds;
2094 	if ((newt < t) != (saved_seconds < 0))
2095 		goto out_of_range;
2096 	t = newt;
2097 	if (funcp(sp, &t, offset, tmp)) {
2098 		*okayp = true;
2099 		return t;
2100 	}
2101 out_of_range:
2102 	errno = EOVERFLOW;
2103 	return WRONG;
2104 invalid:
2105 	errno = EINVAL;
2106 	return WRONG;
2107 }
2108 
2109 static time_t
2110 time2(struct tm * const	tmp,
2111       struct tm *(*funcp)(struct state const *, time_t const *,
2112 			  int_fast32_t, struct tm *),
2113       struct state const *sp,
2114       const int_fast32_t offset,
2115       bool *okayp)
2116 {
2117 	time_t	t;
2118 
2119 	/*
2120 	** First try without normalization of seconds
2121 	** (in case tm_sec contains a value associated with a leap second).
2122 	** If that fails, try with normalization of seconds.
2123 	*/
2124 	t = time2sub(tmp, funcp, sp, offset, okayp, false);
2125 	return *okayp ? t : time2sub(tmp, funcp, sp, offset, okayp, true);
2126 }
2127 
2128 static time_t
2129 time1(struct tm *const tmp,
2130       struct tm *(*funcp) (struct state const *, time_t const *,
2131 			   int_fast32_t, struct tm *),
2132       struct state const *sp,
2133       const int_fast32_t offset)
2134 {
2135 	time_t			t;
2136 	int			samei, otheri;
2137 	int			sameind, otherind;
2138 	int			i;
2139 	int			nseen;
2140 	int			save_errno;
2141 	char				seen[TZ_MAX_TYPES];
2142 	unsigned char			types[TZ_MAX_TYPES];
2143 	bool				okay;
2144 
2145 	if (tmp == NULL) {
2146 		errno = EINVAL;
2147 		return WRONG;
2148 	}
2149 	if (tmp->tm_isdst > 1)
2150 		tmp->tm_isdst = 1;
2151 	save_errno = errno;
2152 	t = time2(tmp, funcp, sp, offset, &okay);
2153 	if (okay) {
2154 		errno = save_errno;
2155 		return t;
2156 	}
2157 	if (tmp->tm_isdst < 0)
2158 #ifdef PCTS
2159 		/*
2160 		** POSIX Conformance Test Suite code courtesy Grant Sullivan.
2161 		*/
2162 		tmp->tm_isdst = 0;	/* reset to std and try again */
2163 #else
2164 		return t;
2165 #endif /* !defined PCTS */
2166 	/*
2167 	** We're supposed to assume that somebody took a time of one type
2168 	** and did some math on it that yielded a "struct tm" that's bad.
2169 	** We try to divine the type they started from and adjust to the
2170 	** type they need.
2171 	*/
2172 	if (sp == NULL) {
2173 		errno = EINVAL;
2174 		return WRONG;
2175 	}
2176 	for (i = 0; i < sp->typecnt; ++i)
2177 		seen[i] = false;
2178 	nseen = 0;
2179 	for (i = sp->timecnt - 1; i >= 0; --i)
2180 		if (!seen[sp->types[i]]) {
2181 			seen[sp->types[i]] = true;
2182 			types[nseen++] = sp->types[i];
2183 		}
2184 	for (sameind = 0; sameind < nseen; ++sameind) {
2185 		samei = types[sameind];
2186 		if (sp->ttis[samei].tt_isdst != tmp->tm_isdst)
2187 			continue;
2188 		for (otherind = 0; otherind < nseen; ++otherind) {
2189 			otheri = types[otherind];
2190 			if (sp->ttis[otheri].tt_isdst == tmp->tm_isdst)
2191 				continue;
2192 			tmp->tm_sec += (int)(sp->ttis[otheri].tt_gmtoff -
2193 					sp->ttis[samei].tt_gmtoff);
2194 			tmp->tm_isdst = !tmp->tm_isdst;
2195 			t = time2(tmp, funcp, sp, offset, &okay);
2196 			if (okay) {
2197 				errno = save_errno;
2198 				return t;
2199 			}
2200 			tmp->tm_sec -= (int)(sp->ttis[otheri].tt_gmtoff -
2201 					sp->ttis[samei].tt_gmtoff);
2202 			tmp->tm_isdst = !tmp->tm_isdst;
2203 		}
2204 	}
2205 	errno = EOVERFLOW;
2206 	return WRONG;
2207 }
2208 
2209 static time_t
2210 mktime_tzname(timezone_t sp, struct tm *tmp, bool setname)
2211 {
2212 	if (sp)
2213 		return time1(tmp, localsub, sp, setname);
2214 	else {
2215 		gmtcheck();
2216 		return time1(tmp, gmtsub, gmtptr, 0);
2217 	}
2218 }
2219 
2220 #if NETBSD_INSPIRED
2221 
2222 time_t
2223 mktime_z(timezone_t sp, struct tm *const tmp)
2224 {
2225 	return mktime_tzname(sp, tmp, false);
2226 }
2227 
2228 #endif
2229 
2230 time_t
2231 mktime(struct tm *tmp)
2232 {
2233 	time_t t;
2234 
2235 	rwlock_wrlock(&lcl_lock);
2236 	tzset_unlocked();
2237 	t = mktime_tzname(lclptr, tmp, true);
2238 	rwlock_unlock(&lcl_lock);
2239 	return t;
2240 }
2241 
2242 #ifdef STD_INSPIRED
2243 
2244 time_t
2245 timelocal_z(const timezone_t sp, struct tm *const tmp)
2246 {
2247 	if (tmp != NULL)
2248 		tmp->tm_isdst = -1;	/* in case it wasn't initialized */
2249 	return mktime_z(sp, tmp);
2250 }
2251 
2252 time_t
2253 timelocal(struct tm *tmp)
2254 {
2255 	if (tmp != NULL)
2256 		tmp->tm_isdst = -1;	/* in case it wasn't initialized */
2257 	return mktime(tmp);
2258 }
2259 
2260 time_t
2261 timegm(struct tm *tmp)
2262 {
2263 
2264 	return timeoff(tmp, 0);
2265 }
2266 
2267 time_t
2268 timeoff(struct tm *tmp, long offset)
2269 {
2270 	if (tmp)
2271 		tmp->tm_isdst = 0;
2272 	gmtcheck();
2273 	return time1(tmp, gmtsub, gmtptr, (int_fast32_t)offset);
2274 }
2275 
2276 #endif /* defined STD_INSPIRED */
2277 
2278 /*
2279 ** XXX--is the below the right way to conditionalize??
2280 */
2281 
2282 #ifdef STD_INSPIRED
2283 
2284 /*
2285 ** IEEE Std 1003.1-1988 (POSIX) legislates that 536457599
2286 ** shall correspond to "Wed Dec 31 23:59:59 UTC 1986", which
2287 ** is not the case if we are accounting for leap seconds.
2288 ** So, we provide the following conversion routines for use
2289 ** when exchanging timestamps with POSIX conforming systems.
2290 */
2291 
2292 static int_fast64_t
2293 leapcorr(const timezone_t sp, time_t t)
2294 {
2295 	struct lsinfo const * lp;
2296 	int		i;
2297 
2298 	i = sp->leapcnt;
2299 	while (--i >= 0) {
2300 		lp = &sp->lsis[i];
2301 		if (t >= lp->ls_trans)
2302 			return lp->ls_corr;
2303 	}
2304 	return 0;
2305 }
2306 
2307 NETBSD_INSPIRED_EXTERN time_t ATTRIBUTE_PURE
2308 time2posix_z(timezone_t sp, time_t t)
2309 {
2310 	return (time_t)(t - leapcorr(sp, t));
2311 }
2312 
2313 time_t
2314 time2posix(time_t t)
2315 {
2316 	rwlock_wrlock(&lcl_lock);
2317 	if (!lcl_is_set)
2318 		tzset_unlocked();
2319 	if (lclptr)
2320 		t = (time_t)(t - leapcorr(lclptr, t));
2321 	rwlock_unlock(&lcl_lock);
2322 	return t;
2323 }
2324 
2325 NETBSD_INSPIRED_EXTERN time_t ATTRIBUTE_PURE
2326 posix2time_z(timezone_t sp, time_t t)
2327 {
2328 	time_t	x;
2329 	time_t	y;
2330 
2331 	/*
2332 	** For a positive leap second hit, the result
2333 	** is not unique. For a negative leap second
2334 	** hit, the corresponding time doesn't exist,
2335 	** so we return an adjacent second.
2336 	*/
2337 	x = (time_t)(t + leapcorr(sp, t));
2338 	y = (time_t)(x - leapcorr(sp, x));
2339 	if (y < t) {
2340 		do {
2341 			x++;
2342 			y = (time_t)(x - leapcorr(sp, x));
2343 		} while (y < t);
2344 		x -= y != t;
2345 	} else if (y > t) {
2346 		do {
2347 			--x;
2348 			y = (time_t)(x - leapcorr(sp, x));
2349 		} while (y > t);
2350 		x += y != t;
2351 	}
2352 	return x;
2353 }
2354 
2355 time_t
2356 posix2time(time_t t)
2357 {
2358 	rwlock_wrlock(&lcl_lock);
2359 	if (!lcl_is_set)
2360 		tzset_unlocked();
2361 	if (lclptr)
2362 		t = posix2time_z(lclptr, t);
2363 	rwlock_unlock(&lcl_lock);
2364 	return t;
2365 }
2366 
2367 #endif /* defined STD_INSPIRED */
2368