1/*	$OpenBSD: localtime.c,v 1.66 2024/04/04 02:20:01 millert Exp $ */
2/*
3** This file is in the public domain, so clarified as of
4** 1996-06-05 by Arthur David Olson.
5*/
6
7/*
8** Leap second handling from Bradley White.
9** POSIX-style TZ environment variable handling from Guy Harris.
10*/
11
12#include <ctype.h>
13#include <errno.h>
14#include <fcntl.h>
15#include <stdint.h>
16#include <stdlib.h>
17#include <string.h>
18#include <unistd.h>
19
20#include "private.h"
21#include "tzfile.h"
22#include "thread_private.h"
23
24#ifndef TZ_ABBR_MAX_LEN
25#define TZ_ABBR_MAX_LEN	16
26#endif /* !defined TZ_ABBR_MAX_LEN */
27
28#ifndef TZ_ABBR_CHAR_SET
29#define TZ_ABBR_CHAR_SET \
30	"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789 :+-._"
31#endif /* !defined TZ_ABBR_CHAR_SET */
32
33#ifndef TZ_ABBR_ERR_CHAR
34#define TZ_ABBR_ERR_CHAR	'_'
35#endif /* !defined TZ_ABBR_ERR_CHAR */
36
37#ifndef WILDABBR
38/*
39** Someone might make incorrect use of a time zone abbreviation:
40**	1.	They might reference tzname[0] before calling tzset (explicitly
41**		or implicitly).
42**	2.	They might reference tzname[1] before calling tzset (explicitly
43**		or implicitly).
44**	3.	They might reference tzname[1] after setting to a time zone
45**		in which Daylight Saving Time is never observed.
46**	4.	They might reference tzname[0] after setting to a time zone
47**		in which Standard Time is never observed.
48**	5.	They might reference tm.tm_zone after calling offtime.
49** What's best to do in the above cases is open to debate;
50** for now, we just set things up so that in any of the five cases
51** WILDABBR is used. Another possibility: initialize tzname[0] to the
52** string "tzname[0] used before set", and similarly for the other cases.
53** And another: initialize tzname[0] to "ERA", with an explanation in the
54** manual page of what this "time zone abbreviation" means (doing this so
55** that tzname[0] has the "normal" length of three characters).
56*/
57#define WILDABBR	"   "
58#endif /* !defined WILDABBR */
59
60static char		wildabbr[] = WILDABBR;
61
62static const char	gmt[] = "GMT";
63
64/*
65** The DST rules to use if TZ has no rules and we can't load TZDEFRULES.
66** We default to US rules as of 1999-08-17.
67** POSIX 1003.1 section 8.1.1 says that the default DST rules are
68** implementation dependent; for historical reasons, US rules are a
69** common default.
70*/
71#ifndef TZDEFRULESTRING
72#define TZDEFRULESTRING ",M4.1.0,M10.5.0"
73#endif /* !defined TZDEFDST */
74
75struct ttinfo {				/* time type information */
76	long		tt_gmtoff;	/* UTC offset in seconds */
77	int		tt_isdst;	/* used to set tm_isdst */
78	int		tt_abbrind;	/* abbreviation list index */
79	int		tt_ttisstd;	/* TRUE if transition is std time */
80	int		tt_ttisgmt;	/* TRUE if transition is UTC */
81};
82
83struct lsinfo {				/* leap second information */
84	time_t		ls_trans;	/* transition time */
85	long		ls_corr;	/* correction to apply */
86};
87
88#define BIGGEST(a, b)	(((a) > (b)) ? (a) : (b))
89
90#ifdef TZNAME_MAX
91#define MY_TZNAME_MAX	TZNAME_MAX
92#endif /* defined TZNAME_MAX */
93#ifndef TZNAME_MAX
94#define MY_TZNAME_MAX	255
95#endif /* !defined TZNAME_MAX */
96
97struct state {
98	int		leapcnt;
99	int		timecnt;
100	int		typecnt;
101	int		charcnt;
102	int		goback;
103	int		goahead;
104	time_t		ats[TZ_MAX_TIMES];
105	unsigned char	types[TZ_MAX_TIMES];
106	struct ttinfo	ttis[TZ_MAX_TYPES];
107	char		chars[BIGGEST(BIGGEST(TZ_MAX_CHARS + 1, sizeof gmt),
108			    (2 * (MY_TZNAME_MAX + 1)))];
109	struct lsinfo	lsis[TZ_MAX_LEAPS];
110};
111
112struct rule {
113	int		r_type;		/* type of rule--see below */
114	int		r_day;		/* day number of rule */
115	int		r_week;		/* week number of rule */
116	int		r_mon;		/* month number of rule */
117	long		r_time;		/* transition time of rule */
118};
119
120#define JULIAN_DAY		0	/* Jn - Julian day */
121#define DAY_OF_YEAR		1	/* n - day of year */
122#define MONTH_NTH_DAY_OF_WEEK	2	/* Mm.n.d - month, week, day of week */
123
124/*
125** Prototypes for static functions.
126*/
127
128static long		detzcode(const char * codep);
129static time_t		detzcode64(const char * codep);
130static int		differ_by_repeat(time_t t1, time_t t0);
131static const char *	getzname(const char * strp);
132static const char *	getqzname(const char * strp, const int delim);
133static const char *	getnum(const char * strp, int * nump, int min,
134				int max);
135static const char *	getsecs(const char * strp, long * secsp);
136static const char *	getoffset(const char * strp, long * offsetp);
137static const char *	getrule(const char * strp, struct rule * rulep);
138static void		gmtload(struct state * sp);
139static struct tm *	gmtsub(const time_t * timep, long offset,
140				struct tm * tmp);
141static struct tm *	localsub(const time_t * timep, long offset,
142				struct tm * tmp);
143static int		increment_overflow(int * number, int delta);
144static int		leaps_thru_end_of(int y);
145static int		long_increment_overflow(long * number, int delta);
146static int		long_normalize_overflow(long * tensptr,
147				int * unitsptr, int base);
148static int		normalize_overflow(int * tensptr, int * unitsptr,
149				int base);
150static void		settzname(void);
151static time_t		time1(struct tm * tmp,
152				struct tm * (*funcp)(const time_t *,
153				long, struct tm *),
154				long offset);
155static time_t		time2(struct tm *tmp,
156				struct tm * (*funcp)(const time_t *,
157				long, struct tm*),
158				long offset, int * okayp);
159static time_t		time2sub(struct tm *tmp,
160				struct tm * (*funcp)(const time_t *,
161				long, struct tm*),
162				long offset, int * okayp, int do_norm_secs);
163static struct tm *	timesub(const time_t * timep, long offset,
164				const struct state * sp, struct tm * tmp);
165static int		tmcomp(const struct tm * atmp,
166				const struct tm * btmp);
167static time_t		transtime(time_t janfirst, int year,
168				const struct rule * rulep, long offset);
169static int		typesequiv(const struct state * sp, int a, int b);
170static int		tzload(const char * name, struct state * sp,
171				int doextend);
172static int		tzparse(const char * name, struct state * sp,
173				int lastditch);
174
175#ifdef STD_INSPIRED
176struct tm	*offtime(const time_t *, long);
177time_t		time2posix(time_t);
178time_t		posix2time(time_t);
179PROTO_DEPRECATED(offtime);
180PROTO_DEPRECATED(time2posix);
181PROTO_DEPRECATED(posix2time);
182#endif
183
184static struct state *	lclptr;
185static struct state *	gmtptr;
186
187
188#ifndef TZ_STRLEN_MAX
189#define TZ_STRLEN_MAX 255
190#endif /* !defined TZ_STRLEN_MAX */
191
192static int		lcl_is_set;
193static int		gmt_is_set;
194_THREAD_PRIVATE_MUTEX(lcl);
195_THREAD_PRIVATE_MUTEX(gmt);
196
197char *			tzname[2] = {
198	wildabbr,
199	wildabbr
200};
201#if 0
202DEF_WEAK(tzname);
203#endif
204
205/*
206** Section 4.12.3 of X3.159-1989 requires that
207**	Except for the strftime function, these functions [asctime,
208**	ctime, gmtime, localtime] return values in one of two static
209**	objects: a broken-down time structure and an array of char.
210** Thanks to Paul Eggert for noting this.
211*/
212
213static struct tm	tm;
214
215long			timezone = 0;
216int			daylight = 0;
217
218static long
219detzcode(const char *codep)
220{
221	long	result;
222	int	i;
223
224	result = (codep[0] & 0x80) ? ~0L : 0;
225	for (i = 0; i < 4; ++i)
226		result = (result << 8) | (codep[i] & 0xff);
227	return result;
228}
229
230static time_t
231detzcode64(const char *codep)
232{
233	time_t	result;
234	int	i;
235
236	result = (codep[0] & 0x80) ?  (~(int_fast64_t) 0) : 0;
237	for (i = 0; i < 8; ++i)
238		result = result * 256 + (codep[i] & 0xff);
239	return result;
240}
241
242static void
243settzname(void)
244{
245	struct state * const	sp = lclptr;
246	int			i;
247
248	tzname[0] = wildabbr;
249	tzname[1] = wildabbr;
250	daylight = 0;
251	timezone = 0;
252	if (sp == NULL) {
253		tzname[0] = tzname[1] = (char *)gmt;
254		return;
255	}
256	/*
257	** And to get the latest zone names into tzname. . .
258	*/
259	for (i = 0; i < sp->timecnt; ++i) {
260		const struct ttinfo *ttisp = &sp->ttis[sp->types[i]];
261
262		tzname[ttisp->tt_isdst] = &sp->chars[ttisp->tt_abbrind];
263		if (ttisp->tt_isdst)
264			daylight = 1;
265		if (!ttisp->tt_isdst)
266			timezone = -(ttisp->tt_gmtoff);
267	}
268	/*
269	** Finally, scrub the abbreviations.
270	** First, replace bogus characters.
271	*/
272	for (i = 0; i < sp->charcnt; ++i) {
273		if (strchr(TZ_ABBR_CHAR_SET, sp->chars[i]) == NULL)
274			sp->chars[i] = TZ_ABBR_ERR_CHAR;
275	}
276	/*
277	** Second, truncate long abbreviations.
278	*/
279	for (i = 0; i < sp->typecnt; ++i) {
280		const struct ttinfo *ttisp = &sp->ttis[i];
281		char *cp = &sp->chars[ttisp->tt_abbrind];
282
283		if (strlen(cp) > TZ_ABBR_MAX_LEN &&
284		    strcmp(cp, GRANDPARENTED) != 0)
285			*(cp + TZ_ABBR_MAX_LEN) = '\0';
286	}
287}
288
289static int
290differ_by_repeat(time_t t1, time_t t0)
291{
292	if (TYPE_BIT(time_t) - 1 < SECSPERREPEAT_BITS)
293		return 0;
294	return (int64_t)t1 - t0 == SECSPERREPEAT;
295}
296
297static int
298tzpath_ok(const char *name)
299{
300	/* Reject absolute paths that don't start with TZDIR.  */
301	if (name[0] == '/' && (strncmp(name, TZDIR, sizeof(TZDIR) - 1) != 0 ||
302	    name[sizeof(TZDIR) - 1] != '/'))
303		return 0;
304
305	/* Reject paths that contain "../". */
306	if (strstr(name, "../") != NULL)
307		return 0;
308
309	return 1;
310}
311
312static int
313open_tzfile(const char *name)
314{
315	char fullname[PATH_MAX];
316	int i;
317
318	if (name != NULL) {
319		/*
320		 * POSIX section 8 says that names starting with a ':' are
321		 * "implementation-defined".  We treat them as timezone paths.
322		 */
323		if (name[0] == ':')
324			name++;
325
326		/*
327		 * Ignore absolute paths that don't start with TZDIR
328		 * or that contain "../".
329		 */
330		if (!tzpath_ok(name))
331			name = NULL;
332	}
333
334	if (name == NULL) {
335		name = TZDEFAULT;
336	} else if (name[0] != '/') {
337		/* Time zone data path is relative to TZDIR. */
338		i = snprintf(fullname, sizeof(fullname), "%s/%s", TZDIR, name);
339		if (i < 0 || i >= sizeof(fullname)) {
340			errno = ENAMETOOLONG;
341			return -1;
342		}
343		name = fullname;
344	}
345
346	return open(name, O_RDONLY);
347}
348
349static int
350tzload(const char *name, struct state *sp, int doextend)
351{
352	const char *		p;
353	int			i;
354	int			fid;
355	int			stored;
356	int			nread;
357	typedef union {
358		struct tzhead	tzhead;
359		char		buf[2 * sizeof(struct tzhead) +
360				    2 * sizeof *sp +
361				    4 * TZ_MAX_TIMES];
362	} u_t;
363	u_t *			up;
364
365	up = calloc(1, sizeof *up);
366	if (up == NULL)
367		return -1;
368
369	sp->goback = sp->goahead = FALSE;
370
371	if ((fid = open_tzfile(name)) == -1) {
372		/* Could be a POSIX section 8-style TZ string. */
373		goto oops;
374	}
375
376	nread = read(fid, up->buf, sizeof up->buf);
377	if (close(fid) == -1 || nread <= 0)
378		goto oops;
379	for (stored = 4; stored <= 8; stored *= 2) {
380		int		ttisstdcnt;
381		int		ttisgmtcnt;
382
383		ttisstdcnt = (int) detzcode(up->tzhead.tzh_ttisstdcnt);
384		ttisgmtcnt = (int) detzcode(up->tzhead.tzh_ttisgmtcnt);
385		sp->leapcnt = (int) detzcode(up->tzhead.tzh_leapcnt);
386		sp->timecnt = (int) detzcode(up->tzhead.tzh_timecnt);
387		sp->typecnt = (int) detzcode(up->tzhead.tzh_typecnt);
388		sp->charcnt = (int) detzcode(up->tzhead.tzh_charcnt);
389		p = up->tzhead.tzh_charcnt + sizeof up->tzhead.tzh_charcnt;
390		if (sp->leapcnt < 0 || sp->leapcnt > TZ_MAX_LEAPS ||
391		    sp->typecnt <= 0 || sp->typecnt > TZ_MAX_TYPES ||
392		    sp->timecnt < 0 || sp->timecnt > TZ_MAX_TIMES ||
393		    sp->charcnt < 0 || sp->charcnt > TZ_MAX_CHARS ||
394		    (ttisstdcnt != sp->typecnt && ttisstdcnt != 0) ||
395		    (ttisgmtcnt != sp->typecnt && ttisgmtcnt != 0))
396			goto oops;
397		if (nread - (p - up->buf) <
398		    sp->timecnt * stored +		/* ats */
399		    sp->timecnt +			/* types */
400		    sp->typecnt * 6 +		/* ttinfos */
401		    sp->charcnt +			/* chars */
402		    sp->leapcnt * (stored + 4) +	/* lsinfos */
403		    ttisstdcnt +			/* ttisstds */
404		    ttisgmtcnt)			/* ttisgmts */
405			goto oops;
406		for (i = 0; i < sp->timecnt; ++i) {
407			sp->ats[i] = (stored == 4) ?
408			    detzcode(p) : detzcode64(p);
409			p += stored;
410		}
411		for (i = 0; i < sp->timecnt; ++i) {
412			sp->types[i] = (unsigned char) *p++;
413			if (sp->types[i] >= sp->typecnt)
414				goto oops;
415		}
416		for (i = 0; i < sp->typecnt; ++i) {
417			struct ttinfo *	ttisp;
418
419			ttisp = &sp->ttis[i];
420			ttisp->tt_gmtoff = detzcode(p);
421			p += 4;
422			ttisp->tt_isdst = (unsigned char) *p++;
423			if (ttisp->tt_isdst != 0 && ttisp->tt_isdst != 1)
424				goto oops;
425			ttisp->tt_abbrind = (unsigned char) *p++;
426			if (ttisp->tt_abbrind < 0 ||
427			    ttisp->tt_abbrind > sp->charcnt)
428				goto oops;
429		}
430		for (i = 0; i < sp->charcnt; ++i)
431			sp->chars[i] = *p++;
432		sp->chars[i] = '\0';	/* ensure '\0' at end */
433		for (i = 0; i < sp->leapcnt; ++i) {
434			struct lsinfo *	lsisp;
435
436			lsisp = &sp->lsis[i];
437			lsisp->ls_trans = (stored == 4) ?
438			    detzcode(p) : detzcode64(p);
439			p += stored;
440			lsisp->ls_corr = detzcode(p);
441			p += 4;
442		}
443		for (i = 0; i < sp->typecnt; ++i) {
444			struct ttinfo *	ttisp;
445
446			ttisp = &sp->ttis[i];
447			if (ttisstdcnt == 0)
448				ttisp->tt_ttisstd = FALSE;
449			else {
450				ttisp->tt_ttisstd = *p++;
451				if (ttisp->tt_ttisstd != TRUE &&
452				    ttisp->tt_ttisstd != FALSE)
453					goto oops;
454			}
455		}
456		for (i = 0; i < sp->typecnt; ++i) {
457			struct ttinfo *	ttisp;
458
459			ttisp = &sp->ttis[i];
460			if (ttisgmtcnt == 0)
461				ttisp->tt_ttisgmt = FALSE;
462			else {
463				ttisp->tt_ttisgmt = *p++;
464				if (ttisp->tt_ttisgmt != TRUE &&
465				    ttisp->tt_ttisgmt != FALSE)
466					goto oops;
467			}
468		}
469		/*
470		** Out-of-sort ats should mean we're running on a
471		** signed time_t system but using a data file with
472		** unsigned values (or vice versa).
473		*/
474		for (i = 0; i < sp->timecnt - 2; ++i)
475			if (sp->ats[i] > sp->ats[i + 1]) {
476				++i;
477				/*
478				** Ignore the end (easy).
479				*/
480				sp->timecnt = i;
481				break;
482			}
483		/*
484		** If this is an old file, we're done.
485		*/
486		if (up->tzhead.tzh_version[0] == '\0')
487			break;
488		nread -= p - up->buf;
489		for (i = 0; i < nread; ++i)
490			up->buf[i] = p[i];
491		/*
492		** If this is a narrow integer time_t system, we're done.
493		*/
494		if (stored >= sizeof(time_t))
495			break;
496	}
497	if (doextend && nread > 2 &&
498	    up->buf[0] == '\n' && up->buf[nread - 1] == '\n' &&
499	    sp->typecnt + 2 <= TZ_MAX_TYPES) {
500		struct state	ts;
501		int	result;
502
503		up->buf[nread - 1] = '\0';
504		result = tzparse(&up->buf[1], &ts, FALSE);
505		if (result == 0 && ts.typecnt == 2 &&
506		    sp->charcnt + ts.charcnt <= TZ_MAX_CHARS) {
507			for (i = 0; i < 2; ++i)
508				ts.ttis[i].tt_abbrind +=
509				    sp->charcnt;
510			for (i = 0; i < ts.charcnt; ++i)
511				sp->chars[sp->charcnt++] =
512				    ts.chars[i];
513			i = 0;
514			while (i < ts.timecnt &&
515			    ts.ats[i] <=
516			    sp->ats[sp->timecnt - 1])
517				++i;
518			while (i < ts.timecnt &&
519			    sp->timecnt < TZ_MAX_TIMES) {
520				sp->ats[sp->timecnt] =
521				    ts.ats[i];
522				sp->types[sp->timecnt] =
523				    sp->typecnt +
524				    ts.types[i];
525				++sp->timecnt;
526				++i;
527			}
528			sp->ttis[sp->typecnt++] = ts.ttis[0];
529			sp->ttis[sp->typecnt++] = ts.ttis[1];
530		}
531	}
532	if (sp->timecnt > 1) {
533		for (i = 1; i < sp->timecnt; ++i) {
534			if (typesequiv(sp, sp->types[i], sp->types[0]) &&
535			    differ_by_repeat(sp->ats[i], sp->ats[0])) {
536				sp->goback = TRUE;
537				break;
538			}
539		}
540		for (i = sp->timecnt - 2; i >= 0; --i) {
541			if (typesequiv(sp, sp->types[sp->timecnt - 1],
542			    sp->types[i]) &&
543			    differ_by_repeat(sp->ats[sp->timecnt - 1],
544			    sp->ats[i])) {
545				sp->goahead = TRUE;
546				break;
547			}
548		}
549	}
550	free(up);
551	return 0;
552oops:
553	free(up);
554	return -1;
555}
556
557static int
558typesequiv(const struct state *sp, int a, int b)
559{
560	int	result;
561
562	if (sp == NULL ||
563	    a < 0 || a >= sp->typecnt ||
564	    b < 0 || b >= sp->typecnt)
565		result = FALSE;
566	else {
567		const struct ttinfo *	ap = &sp->ttis[a];
568		const struct ttinfo *	bp = &sp->ttis[b];
569		result = ap->tt_gmtoff == bp->tt_gmtoff &&
570		    ap->tt_isdst == bp->tt_isdst &&
571		    ap->tt_ttisstd == bp->tt_ttisstd &&
572		    ap->tt_ttisgmt == bp->tt_ttisgmt &&
573		    strcmp(&sp->chars[ap->tt_abbrind],
574		    &sp->chars[bp->tt_abbrind]) == 0;
575	}
576	return result;
577}
578
579static const int	mon_lengths[2][MONSPERYEAR] = {
580	{ 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 },
581	{ 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }
582};
583
584static const int	year_lengths[2] = {
585	DAYSPERNYEAR, DAYSPERLYEAR
586};
587
588/*
589** Given a pointer into a time zone string, scan until a character that is not
590** a valid character in a zone name is found. Return a pointer to that
591** character.
592*/
593
594static const char *
595getzname(const char *strp)
596{
597	char	c;
598
599	while ((c = *strp) != '\0' && !isdigit((unsigned char)c) && c != ',' && c != '-' &&
600	    c != '+')
601		++strp;
602	return strp;
603}
604
605/*
606** Given a pointer into an extended time zone string, scan until the ending
607** delimiter of the zone name is located. Return a pointer to the delimiter.
608**
609** As with getzname above, the legal character set is actually quite
610** restricted, with other characters producing undefined results.
611** We don't do any checking here; checking is done later in common-case code.
612*/
613
614static const char *
615getqzname(const char *strp, const int delim)
616{
617	int	c;
618
619	while ((c = *strp) != '\0' && c != delim)
620		++strp;
621	return strp;
622}
623
624/*
625** Given a pointer into a time zone string, extract a number from that string.
626** Check that the number is within a specified range; if it is not, return
627** NULL.
628** Otherwise, return a pointer to the first character not part of the number.
629*/
630
631static const char *
632getnum(const char *strp, int *nump, int min, int max)
633{
634	char	c;
635	int	num;
636
637	if (strp == NULL || !isdigit((unsigned char)(c = *strp)))
638		return NULL;
639	num = 0;
640	do {
641		num = num * 10 + (c - '0');
642		if (num > max)
643			return NULL;	/* illegal value */
644		c = *++strp;
645	} while (isdigit((unsigned char)c));
646	if (num < min)
647		return NULL;		/* illegal value */
648	*nump = num;
649	return strp;
650}
651
652/*
653** Given a pointer into a time zone string, extract a number of seconds,
654** in hh[:mm[:ss]] form, from the string.
655** If any error occurs, return NULL.
656** Otherwise, return a pointer to the first character not part of the number
657** of seconds.
658*/
659
660static const char *
661getsecs(const char *strp, long *secsp)
662{
663	int	num;
664
665	/*
666	** `HOURSPERDAY * DAYSPERWEEK - 1' allows quasi-Posix rules like
667	** "M10.4.6/26", which does not conform to Posix,
668	** but which specifies the equivalent of
669	** ``02:00 on the first Sunday on or after 23 Oct''.
670	*/
671	strp = getnum(strp, &num, 0, HOURSPERDAY * DAYSPERWEEK - 1);
672	if (strp == NULL)
673		return NULL;
674	*secsp = num * (long) SECSPERHOUR;
675	if (*strp == ':') {
676		++strp;
677		strp = getnum(strp, &num, 0, MINSPERHOUR - 1);
678		if (strp == NULL)
679			return NULL;
680		*secsp += num * SECSPERMIN;
681		if (*strp == ':') {
682			++strp;
683			/* `SECSPERMIN' allows for leap seconds. */
684			strp = getnum(strp, &num, 0, SECSPERMIN);
685			if (strp == NULL)
686				return NULL;
687			*secsp += num;
688		}
689	}
690	return strp;
691}
692
693/*
694** Given a pointer into a time zone string, extract an offset, in
695** [+-]hh[:mm[:ss]] form, from the string.
696** If any error occurs, return NULL.
697** Otherwise, return a pointer to the first character not part of the time.
698*/
699
700static const char *
701getoffset(const char *strp, long *offsetp)
702{
703	int	neg = 0;
704
705	if (*strp == '-') {
706		neg = 1;
707		++strp;
708	} else if (*strp == '+')
709		++strp;
710	strp = getsecs(strp, offsetp);
711	if (strp == NULL)
712		return NULL;		/* illegal time */
713	if (neg)
714		*offsetp = -*offsetp;
715	return strp;
716}
717
718/*
719** Given a pointer into a time zone string, extract a rule in the form
720** date[/time]. See POSIX section 8 for the format of "date" and "time".
721** If a valid rule is not found, return NULL.
722** Otherwise, return a pointer to the first character not part of the rule.
723*/
724
725static const char *
726getrule(const char *strp, struct rule *rulep)
727{
728	if (*strp == 'J') {
729		/*
730		** Julian day.
731		*/
732		rulep->r_type = JULIAN_DAY;
733		++strp;
734		strp = getnum(strp, &rulep->r_day, 1, DAYSPERNYEAR);
735	} else if (*strp == 'M') {
736		/*
737		** Month, week, day.
738		*/
739		rulep->r_type = MONTH_NTH_DAY_OF_WEEK;
740		++strp;
741		strp = getnum(strp, &rulep->r_mon, 1, MONSPERYEAR);
742		if (strp == NULL)
743			return NULL;
744		if (*strp++ != '.')
745			return NULL;
746		strp = getnum(strp, &rulep->r_week, 1, 5);
747		if (strp == NULL)
748			return NULL;
749		if (*strp++ != '.')
750			return NULL;
751		strp = getnum(strp, &rulep->r_day, 0, DAYSPERWEEK - 1);
752	} else if (isdigit((unsigned char)*strp)) {
753		/*
754		** Day of year.
755		*/
756		rulep->r_type = DAY_OF_YEAR;
757		strp = getnum(strp, &rulep->r_day, 0, DAYSPERLYEAR - 1);
758	} else
759		return NULL;		/* invalid format */
760	if (strp == NULL)
761		return NULL;
762	if (*strp == '/') {
763		/*
764		** Time specified.
765		*/
766		++strp;
767		strp = getsecs(strp, &rulep->r_time);
768	} else
769		rulep->r_time = 2 * SECSPERHOUR;	/* default = 2:00:00 */
770	return strp;
771}
772
773/*
774** Given the Epoch-relative time of January 1, 00:00:00 UTC, in a year, the
775** year, a rule, and the offset from UTC at the time that rule takes effect,
776** calculate the Epoch-relative time that rule takes effect.
777*/
778
779static time_t
780transtime(time_t janfirst, int year, const struct rule *rulep, long offset)
781{
782	int	leapyear;
783	time_t	value;
784	int	i;
785	int		d, m1, yy0, yy1, yy2, dow;
786
787	value = 0;
788	leapyear = isleap(year);
789	switch (rulep->r_type) {
790
791	case JULIAN_DAY:
792		/*
793		** Jn - Julian day, 1 == January 1, 60 == March 1 even in leap
794		** years.
795		** In non-leap years, or if the day number is 59 or less, just
796		** add SECSPERDAY times the day number-1 to the time of
797		** January 1, midnight, to get the day.
798		*/
799		value = janfirst + (rulep->r_day - 1) * SECSPERDAY;
800		if (leapyear && rulep->r_day >= 60)
801			value += SECSPERDAY;
802		break;
803
804	case DAY_OF_YEAR:
805		/*
806		** n - day of year.
807		** Just add SECSPERDAY times the day number to the time of
808		** January 1, midnight, to get the day.
809		*/
810		value = janfirst + rulep->r_day * SECSPERDAY;
811		break;
812
813	case MONTH_NTH_DAY_OF_WEEK:
814		/*
815		** Mm.n.d - nth "dth day" of month m.
816		*/
817		value = janfirst;
818		for (i = 0; i < rulep->r_mon - 1; ++i)
819			value += mon_lengths[leapyear][i] * SECSPERDAY;
820
821		/*
822		** Use Zeller's Congruence to get day-of-week of first day of
823		** month.
824		*/
825		m1 = (rulep->r_mon + 9) % 12 + 1;
826		yy0 = (rulep->r_mon <= 2) ? (year - 1) : year;
827		yy1 = yy0 / 100;
828		yy2 = yy0 % 100;
829		dow = ((26 * m1 - 2) / 10 +
830		    1 + yy2 + yy2 / 4 + yy1 / 4 - 2 * yy1) % 7;
831		if (dow < 0)
832			dow += DAYSPERWEEK;
833
834		/*
835		** "dow" is the day-of-week of the first day of the month. Get
836		** the day-of-month (zero-origin) of the first "dow" day of the
837		** month.
838		*/
839		d = rulep->r_day - dow;
840		if (d < 0)
841			d += DAYSPERWEEK;
842		for (i = 1; i < rulep->r_week; ++i) {
843			if (d + DAYSPERWEEK >=
844			    mon_lengths[leapyear][rulep->r_mon - 1])
845				break;
846			d += DAYSPERWEEK;
847		}
848
849		/*
850		** "d" is the day-of-month (zero-origin) of the day we want.
851		*/
852		value += d * SECSPERDAY;
853		break;
854	}
855
856	/*
857	** "value" is the Epoch-relative time of 00:00:00 UTC on the day in
858	** question. To get the Epoch-relative time of the specified local
859	** time on that day, add the transition time and the current offset
860	** from UTC.
861	*/
862	return value + rulep->r_time + offset;
863}
864
865/*
866** Given a POSIX section 8-style TZ string, fill in the rule tables as
867** appropriate.
868*/
869
870static int
871tzparse(const char *name, struct state *sp, int lastditch)
872{
873	const char *			stdname;
874	const char *			dstname;
875	size_t				stdlen;
876	size_t				dstlen;
877	long				stdoffset;
878	long				dstoffset;
879	time_t *		atp;
880	unsigned char *	typep;
881	char *			cp;
882	int			load_result;
883	static struct ttinfo		zttinfo;
884
885	dstname = NULL;
886	stdname = name;
887	if (lastditch) {
888		stdlen = strlen(name);	/* length of standard zone name */
889		name += stdlen;
890		if (stdlen >= sizeof sp->chars)
891			stdlen = (sizeof sp->chars) - 1;
892		stdoffset = 0;
893	} else {
894		if (*name == '<') {
895			name++;
896			stdname = name;
897			name = getqzname(name, '>');
898			if (*name != '>')
899				return (-1);
900			stdlen = name - stdname;
901			name++;
902		} else {
903			name = getzname(name);
904			stdlen = name - stdname;
905		}
906		if (*name == '\0')
907			return -1;
908		name = getoffset(name, &stdoffset);
909		if (name == NULL)
910			return -1;
911	}
912	load_result = tzload(TZDEFRULES, sp, FALSE);
913	if (load_result != 0)
914		sp->leapcnt = 0;		/* so, we're off a little */
915	if (*name != '\0') {
916		if (*name == '<') {
917			dstname = ++name;
918			name = getqzname(name, '>');
919			if (*name != '>')
920				return -1;
921			dstlen = name - dstname;
922			name++;
923		} else {
924			dstname = name;
925			name = getzname(name);
926			dstlen = name - dstname; /* length of DST zone name */
927		}
928		if (*name != '\0' && *name != ',' && *name != ';') {
929			name = getoffset(name, &dstoffset);
930			if (name == NULL)
931				return -1;
932		} else
933			dstoffset = stdoffset - SECSPERHOUR;
934		if (*name == '\0' && load_result != 0)
935			name = TZDEFRULESTRING;
936		if (*name == ',' || *name == ';') {
937			struct rule	start;
938			struct rule	end;
939			int		year;
940			time_t		janfirst;
941			time_t		starttime;
942			time_t		endtime;
943
944			++name;
945			if ((name = getrule(name, &start)) == NULL)
946				return -1;
947			if (*name++ != ',')
948				return -1;
949			if ((name = getrule(name, &end)) == NULL)
950				return -1;
951			if (*name != '\0')
952				return -1;
953			sp->typecnt = 2;	/* standard time and DST */
954			/*
955			** Two transitions per year, from EPOCH_YEAR forward.
956			*/
957			sp->ttis[0] = sp->ttis[1] = zttinfo;
958			sp->ttis[0].tt_gmtoff = -dstoffset;
959			sp->ttis[0].tt_isdst = 1;
960			sp->ttis[0].tt_abbrind = stdlen + 1;
961			sp->ttis[1].tt_gmtoff = -stdoffset;
962			sp->ttis[1].tt_isdst = 0;
963			sp->ttis[1].tt_abbrind = 0;
964			atp = sp->ats;
965			typep = sp->types;
966			janfirst = 0;
967			sp->timecnt = 0;
968			for (year = EPOCH_YEAR;
969			    sp->timecnt + 2 <= TZ_MAX_TIMES;
970			    ++year) {
971			    	time_t	newfirst;
972
973				starttime = transtime(janfirst, year, &start,
974				    stdoffset);
975				endtime = transtime(janfirst, year, &end,
976				    dstoffset);
977				if (starttime > endtime) {
978					*atp++ = endtime;
979					*typep++ = 1;	/* DST ends */
980					*atp++ = starttime;
981					*typep++ = 0;	/* DST begins */
982				} else {
983					*atp++ = starttime;
984					*typep++ = 0;	/* DST begins */
985					*atp++ = endtime;
986					*typep++ = 1;	/* DST ends */
987				}
988				sp->timecnt += 2;
989				newfirst = janfirst;
990				newfirst += year_lengths[isleap(year)] *
991				    SECSPERDAY;
992				if (newfirst <= janfirst)
993					break;
994				janfirst = newfirst;
995			}
996		} else {
997			long	theirstdoffset;
998			long	theirdstoffset;
999			long	theiroffset;
1000			int	isdst;
1001			int	i;
1002			int	j;
1003
1004			if (*name != '\0')
1005				return -1;
1006			/*
1007			** Initial values of theirstdoffset and theirdstoffset.
1008			*/
1009			theirstdoffset = 0;
1010			for (i = 0; i < sp->timecnt; ++i) {
1011				j = sp->types[i];
1012				if (!sp->ttis[j].tt_isdst) {
1013					theirstdoffset =
1014						-sp->ttis[j].tt_gmtoff;
1015					break;
1016				}
1017			}
1018			theirdstoffset = 0;
1019			for (i = 0; i < sp->timecnt; ++i) {
1020				j = sp->types[i];
1021				if (sp->ttis[j].tt_isdst) {
1022					theirdstoffset =
1023						-sp->ttis[j].tt_gmtoff;
1024					break;
1025				}
1026			}
1027			/*
1028			** Initially we're assumed to be in standard time.
1029			*/
1030			isdst = FALSE;
1031			theiroffset = theirstdoffset;
1032			/*
1033			** Now juggle transition times and types
1034			** tracking offsets as you do.
1035			*/
1036			for (i = 0; i < sp->timecnt; ++i) {
1037				j = sp->types[i];
1038				sp->types[i] = sp->ttis[j].tt_isdst;
1039				if (sp->ttis[j].tt_ttisgmt) {
1040					/* No adjustment to transition time */
1041				} else {
1042					/*
1043					** If summer time is in effect, and the
1044					** transition time was not specified as
1045					** standard time, add the summer time
1046					** offset to the transition time;
1047					** otherwise, add the standard time
1048					** offset to the transition time.
1049					*/
1050					/*
1051					** Transitions from DST to DDST
1052					** will effectively disappear since
1053					** POSIX provides for only one DST
1054					** offset.
1055					*/
1056					if (isdst && !sp->ttis[j].tt_ttisstd) {
1057						sp->ats[i] += dstoffset -
1058						    theirdstoffset;
1059					} else {
1060						sp->ats[i] += stdoffset -
1061						    theirstdoffset;
1062					}
1063				}
1064				theiroffset = -sp->ttis[j].tt_gmtoff;
1065				if (sp->ttis[j].tt_isdst)
1066					theirdstoffset = theiroffset;
1067				else
1068					theirstdoffset = theiroffset;
1069			}
1070			/*
1071			** Finally, fill in ttis.
1072			*/
1073			sp->ttis[0] = sp->ttis[1] = zttinfo;
1074			sp->ttis[0].tt_gmtoff = -stdoffset;
1075			sp->ttis[0].tt_isdst = FALSE;
1076			sp->ttis[0].tt_abbrind = 0;
1077			sp->ttis[1].tt_gmtoff = -dstoffset;
1078			sp->ttis[1].tt_isdst = TRUE;
1079			sp->ttis[1].tt_abbrind = stdlen + 1;
1080			sp->typecnt = 2;
1081		}
1082	} else {
1083		dstlen = 0;
1084		sp->typecnt = 1;		/* only standard time */
1085		sp->timecnt = 0;
1086		sp->ttis[0] = zttinfo;
1087		sp->ttis[0].tt_gmtoff = -stdoffset;
1088		sp->ttis[0].tt_isdst = 0;
1089		sp->ttis[0].tt_abbrind = 0;
1090	}
1091	sp->charcnt = stdlen + 1;
1092	if (dstlen != 0)
1093		sp->charcnt += dstlen + 1;
1094	if ((size_t) sp->charcnt > sizeof sp->chars)
1095		return -1;
1096	cp = sp->chars;
1097	strlcpy(cp, stdname, stdlen + 1);
1098	cp += stdlen + 1;
1099	if (dstlen != 0) {
1100		strlcpy(cp, dstname, dstlen + 1);
1101	}
1102	return 0;
1103}
1104
1105static void
1106gmtload(struct state *sp)
1107{
1108	if (tzload(gmt, sp, TRUE) != 0)
1109		(void) tzparse(gmt, sp, TRUE);
1110}
1111
1112static void
1113tzsetwall_basic(void)
1114{
1115	if (lcl_is_set < 0)
1116		return;
1117	lcl_is_set = -1;
1118
1119	if (lclptr == NULL) {
1120		lclptr = calloc(1, sizeof *lclptr);
1121		if (lclptr == NULL) {
1122			settzname();	/* all we can do */
1123			return;
1124		}
1125	}
1126	if (tzload(NULL, lclptr, TRUE) != 0)
1127		gmtload(lclptr);
1128	settzname();
1129}
1130
1131#ifndef STD_INSPIRED
1132/*
1133** A non-static declaration of tzsetwall in a system header file
1134** may cause a warning about this upcoming static declaration...
1135*/
1136static
1137#endif /* !defined STD_INSPIRED */
1138void
1139tzsetwall(void)
1140{
1141	_THREAD_PRIVATE_MUTEX_LOCK(lcl);
1142	tzsetwall_basic();
1143	_THREAD_PRIVATE_MUTEX_UNLOCK(lcl);
1144}
1145
1146static void
1147tzset_basic(void)
1148{
1149	static char	lcl_TZname[TZ_STRLEN_MAX + 1];
1150	const char *	name;
1151
1152	name = getenv("TZ");
1153	if (name == NULL) {
1154		tzsetwall_basic();
1155		return;
1156	}
1157
1158	if (lcl_is_set > 0 && strcmp(lcl_TZname, name) == 0)
1159		return;
1160	lcl_is_set = strlen(name) < sizeof lcl_TZname;
1161	if (lcl_is_set)
1162		strlcpy(lcl_TZname, name, sizeof lcl_TZname);
1163
1164	/* Ignore TZ for setuid/setgid processes. */
1165	if (issetugid())
1166		name = TZDEFAULT;
1167
1168	if (lclptr == NULL) {
1169		lclptr = calloc(1, sizeof *lclptr);
1170		if (lclptr == NULL) {
1171			settzname();	/* all we can do */
1172			return;
1173		}
1174	}
1175	if (*name == '\0') {
1176		/*
1177		** User wants it fast rather than right.
1178		*/
1179		lclptr->leapcnt = 0;		/* so, we're off a little */
1180		lclptr->timecnt = 0;
1181		lclptr->typecnt = 0;
1182		lclptr->ttis[0].tt_isdst = 0;
1183		lclptr->ttis[0].tt_gmtoff = 0;
1184		lclptr->ttis[0].tt_abbrind = 0;
1185		strlcpy(lclptr->chars, gmt, sizeof lclptr->chars);
1186	} else if (tzload(name, lclptr, TRUE) != 0) {
1187		if (name[0] == ':' || tzparse(name, lclptr, FALSE) != 0)
1188			gmtload(lclptr);
1189	}
1190	settzname();
1191}
1192
1193void
1194tzset(void)
1195{
1196	_THREAD_PRIVATE_MUTEX_LOCK(lcl);
1197	tzset_basic();
1198	_THREAD_PRIVATE_MUTEX_UNLOCK(lcl);
1199}
1200DEF_WEAK(tzset);
1201
1202/*
1203** The easy way to behave "as if no library function calls" localtime
1204** is to not call it--so we drop its guts into "localsub", which can be
1205** freely called. (And no, the PANS doesn't require the above behavior--
1206** but it *is* desirable.)
1207**
1208** The unused offset argument is for the benefit of mktime variants.
1209*/
1210
1211static struct tm *
1212localsub(const time_t *timep, long offset, struct tm *tmp)
1213{
1214	struct state *		sp;
1215	const struct ttinfo *	ttisp;
1216	int			i;
1217	struct tm *		result;
1218	const time_t			t = *timep;
1219
1220	sp = lclptr;
1221	if (sp == NULL)
1222		return gmtsub(timep, offset, tmp);
1223	if ((sp->goback && t < sp->ats[0]) ||
1224	    (sp->goahead && t > sp->ats[sp->timecnt - 1])) {
1225		time_t			newt = t;
1226		time_t		seconds;
1227		time_t		tcycles;
1228		int_fast64_t	icycles;
1229
1230		if (t < sp->ats[0])
1231			seconds = sp->ats[0] - t;
1232		else
1233			seconds = t - sp->ats[sp->timecnt - 1];
1234		--seconds;
1235		tcycles = seconds / YEARSPERREPEAT / AVGSECSPERYEAR;
1236		++tcycles;
1237		icycles = tcycles;
1238		if (tcycles - icycles >= 1 || icycles - tcycles >= 1)
1239			return NULL;
1240		seconds = icycles;
1241		seconds *= YEARSPERREPEAT;
1242		seconds *= AVGSECSPERYEAR;
1243		if (t < sp->ats[0])
1244			newt += seconds;
1245		else
1246			newt -= seconds;
1247		if (newt < sp->ats[0] ||
1248		    newt > sp->ats[sp->timecnt - 1])
1249			return NULL;	/* "cannot happen" */
1250		result = localsub(&newt, offset, tmp);
1251		if (result == tmp) {
1252			time_t	newy;
1253
1254			newy = tmp->tm_year;
1255			if (t < sp->ats[0])
1256				newy -= icycles * YEARSPERREPEAT;
1257			else
1258				newy += icycles * YEARSPERREPEAT;
1259			tmp->tm_year = newy;
1260			if (tmp->tm_year != newy)
1261				return NULL;
1262		}
1263		return result;
1264	}
1265	if (sp->timecnt == 0 || t < sp->ats[0]) {
1266		i = 0;
1267		while (sp->ttis[i].tt_isdst) {
1268			if (++i >= sp->typecnt) {
1269				i = 0;
1270				break;
1271			}
1272		}
1273	} else {
1274		int	lo = 1;
1275		int	hi = sp->timecnt;
1276
1277		while (lo < hi) {
1278			int	mid = (lo + hi) >> 1;
1279
1280			if (t < sp->ats[mid])
1281				hi = mid;
1282			else
1283				lo = mid + 1;
1284		}
1285		i = (int) sp->types[lo - 1];
1286	}
1287	ttisp = &sp->ttis[i];
1288	/*
1289	** To get (wrong) behavior that's compatible with System V Release 2.0
1290	** you'd replace the statement below with
1291	**	t += ttisp->tt_gmtoff;
1292	**	timesub(&t, 0L, sp, tmp);
1293	*/
1294	result = timesub(&t, ttisp->tt_gmtoff, sp, tmp);
1295	tmp->tm_isdst = ttisp->tt_isdst;
1296	tzname[tmp->tm_isdst] = &sp->chars[ttisp->tt_abbrind];
1297	tmp->tm_zone = &sp->chars[ttisp->tt_abbrind];
1298	return result;
1299}
1300
1301/*
1302** Re-entrant version of localtime.
1303*/
1304
1305struct tm *
1306localtime_r(const time_t *timep, struct tm *p_tm)
1307{
1308	_THREAD_PRIVATE_MUTEX_LOCK(lcl);
1309	tzset_basic();
1310	p_tm = localsub(timep, 0L, p_tm);
1311	_THREAD_PRIVATE_MUTEX_UNLOCK(lcl);
1312	return p_tm;
1313}
1314DEF_WEAK(localtime_r);
1315
1316struct tm *
1317localtime(const time_t *timep)
1318{
1319	_THREAD_PRIVATE_KEY(localtime);
1320	struct tm * p_tm = (struct tm*)_THREAD_PRIVATE(localtime, tm, NULL);
1321
1322	if (p_tm == NULL)
1323		return NULL;
1324	return localtime_r(timep, p_tm);
1325}
1326DEF_STRONG(localtime);
1327
1328/*
1329** gmtsub is to gmtime as localsub is to localtime.
1330*/
1331
1332static struct tm *
1333gmtsub(const time_t *timep, long offset, struct tm *tmp)
1334{
1335	struct tm *	result;
1336
1337	_THREAD_PRIVATE_MUTEX_LOCK(gmt);
1338	if (!gmt_is_set) {
1339		gmt_is_set = TRUE;
1340		gmtptr = calloc(1, sizeof(*gmtptr));
1341		if (gmtptr != NULL)
1342			gmtload(gmtptr);
1343	}
1344	_THREAD_PRIVATE_MUTEX_UNLOCK(gmt);
1345	result = timesub(timep, offset, gmtptr, tmp);
1346	/*
1347	** Could get fancy here and deliver something such as
1348	** "UTC+xxxx" or "UTC-xxxx" if offset is non-zero,
1349	** but this is no time for a treasure hunt.
1350	*/
1351	if (offset != 0)
1352		tmp->tm_zone = wildabbr;
1353	else {
1354		if (gmtptr == NULL)
1355			tmp->tm_zone = (char *)gmt;
1356		else
1357			tmp->tm_zone = gmtptr->chars;
1358	}
1359	return result;
1360}
1361
1362/*
1363** Re-entrant version of gmtime.
1364*/
1365
1366struct tm *
1367gmtime_r(const time_t *timep, struct tm *p_tm)
1368{
1369	return gmtsub(timep, 0L, p_tm);
1370}
1371DEF_WEAK(gmtime_r);
1372
1373struct tm *
1374gmtime(const time_t *timep)
1375{
1376	_THREAD_PRIVATE_KEY(gmtime);
1377	struct tm * p_tm = (struct tm*) _THREAD_PRIVATE(gmtime, tm, NULL);
1378
1379	if (p_tm == NULL)
1380		return NULL;
1381	return gmtime_r(timep, p_tm);
1382
1383}
1384DEF_WEAK(gmtime);
1385
1386#ifdef STD_INSPIRED
1387
1388struct tm *
1389offtime(const time_t *timep, long offset)
1390{
1391	return gmtsub(timep, offset, &tm);
1392}
1393
1394#endif /* defined STD_INSPIRED */
1395
1396/*
1397** Return the number of leap years through the end of the given year
1398** where, to make the math easy, the answer for year zero is defined as zero.
1399*/
1400
1401static int
1402leaps_thru_end_of(int y)
1403{
1404	return (y >= 0) ? (y / 4 - y / 100 + y / 400) :
1405		-(leaps_thru_end_of(-(y + 1)) + 1);
1406}
1407
1408static struct tm *
1409timesub(const time_t *timep, long offset, const struct state *sp, struct tm *tmp)
1410{
1411	const struct lsinfo *	lp;
1412	time_t			tdays;
1413	int			idays;	/* unsigned would be so 2003 */
1414	long			rem;
1415	int			y;
1416	const int *		ip;
1417	long			corr;
1418	int			hit;
1419	int			i;
1420	long			seconds;
1421
1422	corr = 0;
1423	hit = 0;
1424	i = (sp == NULL) ? 0 : sp->leapcnt;
1425	while (--i >= 0) {
1426		lp = &sp->lsis[i];
1427		if (*timep >= lp->ls_trans) {
1428			if (*timep == lp->ls_trans) {
1429				hit = ((i == 0 && lp->ls_corr > 0) ||
1430				    lp->ls_corr > sp->lsis[i - 1].ls_corr);
1431				if (hit) {
1432					while (i > 0 &&
1433					    sp->lsis[i].ls_trans ==
1434					    sp->lsis[i - 1].ls_trans + 1 &&
1435					    sp->lsis[i].ls_corr ==
1436					    sp->lsis[i - 1].ls_corr + 1) {
1437						++hit;
1438						--i;
1439					}
1440				}
1441			}
1442			corr = lp->ls_corr;
1443			break;
1444		}
1445	}
1446	y = EPOCH_YEAR;
1447	tdays = *timep / SECSPERDAY;
1448	rem = *timep - tdays * SECSPERDAY;
1449	while (tdays < 0 || tdays >= year_lengths[isleap(y)]) {
1450		int		newy;
1451		time_t	tdelta;
1452		int	idelta;
1453		int	leapdays;
1454
1455		tdelta = tdays / DAYSPERLYEAR;
1456		idelta = tdelta;
1457		if (tdelta - idelta >= 1 || idelta - tdelta >= 1)
1458			return NULL;
1459		if (idelta == 0)
1460			idelta = (tdays < 0) ? -1 : 1;
1461		newy = y;
1462		if (increment_overflow(&newy, idelta))
1463			return NULL;
1464		leapdays = leaps_thru_end_of(newy - 1) -
1465			leaps_thru_end_of(y - 1);
1466		tdays -= ((time_t) newy - y) * DAYSPERNYEAR;
1467		tdays -= leapdays;
1468		y = newy;
1469	}
1470
1471	seconds = tdays * SECSPERDAY + 0.5;
1472	tdays = seconds / SECSPERDAY;
1473	rem += seconds - tdays * SECSPERDAY;
1474
1475	/*
1476	** Given the range, we can now fearlessly cast...
1477	*/
1478	idays = tdays;
1479	rem += offset - corr;
1480	while (rem < 0) {
1481		rem += SECSPERDAY;
1482		--idays;
1483	}
1484	while (rem >= SECSPERDAY) {
1485		rem -= SECSPERDAY;
1486		++idays;
1487	}
1488	while (idays < 0) {
1489		if (increment_overflow(&y, -1))
1490			return NULL;
1491		idays += year_lengths[isleap(y)];
1492	}
1493	while (idays >= year_lengths[isleap(y)]) {
1494		idays -= year_lengths[isleap(y)];
1495		if (increment_overflow(&y, 1))
1496			return NULL;
1497	}
1498	tmp->tm_year = y;
1499	if (increment_overflow(&tmp->tm_year, -TM_YEAR_BASE))
1500		return NULL;
1501	tmp->tm_yday = idays;
1502	/*
1503	** The "extra" mods below avoid overflow problems.
1504	*/
1505	tmp->tm_wday = EPOCH_WDAY +
1506	    ((y - EPOCH_YEAR) % DAYSPERWEEK) *
1507	    (DAYSPERNYEAR % DAYSPERWEEK) +
1508	    leaps_thru_end_of(y - 1) -
1509	    leaps_thru_end_of(EPOCH_YEAR - 1) +
1510	    idays;
1511	tmp->tm_wday %= DAYSPERWEEK;
1512	if (tmp->tm_wday < 0)
1513		tmp->tm_wday += DAYSPERWEEK;
1514	tmp->tm_hour = (int) (rem / SECSPERHOUR);
1515	rem %= SECSPERHOUR;
1516	tmp->tm_min = (int) (rem / SECSPERMIN);
1517	/*
1518	** A positive leap second requires a special
1519	** representation. This uses "... ??:59:60" et seq.
1520	*/
1521	tmp->tm_sec = (int) (rem % SECSPERMIN) + hit;
1522	ip = mon_lengths[isleap(y)];
1523	for (tmp->tm_mon = 0; idays >= ip[tmp->tm_mon]; ++(tmp->tm_mon))
1524		idays -= ip[tmp->tm_mon];
1525	tmp->tm_mday = (int) (idays + 1);
1526	tmp->tm_isdst = 0;
1527	tmp->tm_gmtoff = offset;
1528	return tmp;
1529}
1530
1531char *
1532ctime(const time_t *timep)
1533{
1534/*
1535** Section 4.12.3.2 of X3.159-1989 requires that
1536**	The ctime function converts the calendar time pointed to by timer
1537**	to local time in the form of a string. It is equivalent to
1538**		asctime(localtime(timer))
1539*/
1540	return asctime(localtime(timep));
1541}
1542
1543char *
1544ctime_r(const time_t *timep, char *buf)
1545{
1546	struct tm	mytm;
1547
1548	return asctime_r(localtime_r(timep, &mytm), buf);
1549}
1550
1551/*
1552** Adapted from code provided by Robert Elz, who writes:
1553**	The "best" way to do mktime I think is based on an idea of Bob
1554**	Kridle's (so its said...) from a long time ago.
1555**	It does a binary search of the time_t space. Since time_t's are
1556**	just 32 bits, its a max of 32 iterations (even at 64 bits it
1557**	would still be very reasonable).
1558*/
1559
1560#ifndef WRONG
1561#define WRONG	(-1)
1562#endif /* !defined WRONG */
1563
1564/*
1565** Normalize logic courtesy Paul Eggert.
1566*/
1567
1568static int
1569increment_overflow(int *ip, int j)
1570{
1571	int const	i = *ip;
1572
1573	/*
1574	** If i >= 0 there can only be overflow if i + j > INT_MAX
1575	** or if j > INT_MAX - i; given i >= 0, INT_MAX - i cannot overflow.
1576	** If i < 0 there can only be overflow if i + j < INT_MIN
1577	** or if j < INT_MIN - i; given i < 0, INT_MIN - i cannot overflow.
1578	*/
1579	if ((i >= 0) ? (j > INT_MAX - i) : (j < INT_MIN - i))
1580		return TRUE;
1581	*ip += j;
1582	return FALSE;
1583}
1584
1585static int
1586long_increment_overflow(long *lp, int m)
1587{
1588	long const	l = *lp;
1589
1590	if ((l >= 0) ? (m > LONG_MAX - l) : (m < LONG_MIN - l))
1591		return TRUE;
1592	*lp += m;
1593	return FALSE;
1594}
1595
1596static int
1597normalize_overflow(int *tensptr, int *unitsptr, int base)
1598{
1599	int	tensdelta;
1600
1601	tensdelta = (*unitsptr >= 0) ?
1602	    (*unitsptr / base) :
1603	    (-1 - (-1 - *unitsptr) / base);
1604	*unitsptr -= tensdelta * base;
1605	return increment_overflow(tensptr, tensdelta);
1606}
1607
1608static int
1609long_normalize_overflow(long *tensptr, int *unitsptr, int base)
1610{
1611	int	tensdelta;
1612
1613	tensdelta = (*unitsptr >= 0) ?
1614	    (*unitsptr / base) :
1615	    (-1 - (-1 - *unitsptr) / base);
1616	*unitsptr -= tensdelta * base;
1617	return long_increment_overflow(tensptr, tensdelta);
1618}
1619
1620static int
1621tmcomp(const struct tm *atmp, const struct tm *btmp)
1622{
1623	int	result;
1624
1625	if ((result = (atmp->tm_year - btmp->tm_year)) == 0 &&
1626	    (result = (atmp->tm_mon - btmp->tm_mon)) == 0 &&
1627	    (result = (atmp->tm_mday - btmp->tm_mday)) == 0 &&
1628	    (result = (atmp->tm_hour - btmp->tm_hour)) == 0 &&
1629	    (result = (atmp->tm_min - btmp->tm_min)) == 0)
1630		result = atmp->tm_sec - btmp->tm_sec;
1631	return result;
1632}
1633
1634static time_t
1635time2sub(struct tm *tmp, struct tm *(*funcp)(const time_t *, long, struct tm *),
1636    long offset, int *okayp, int do_norm_secs)
1637{
1638	const struct state *	sp;
1639	int			dir;
1640	int			i, j;
1641	int			saved_seconds;
1642	long			li;
1643	time_t			lo;
1644	time_t			hi;
1645	long			y;
1646	time_t			newt;
1647	time_t			t;
1648	struct tm		yourtm, mytm;
1649
1650	*okayp = FALSE;
1651	yourtm = *tmp;
1652	if (do_norm_secs) {
1653		if (normalize_overflow(&yourtm.tm_min, &yourtm.tm_sec,
1654			SECSPERMIN))
1655				return WRONG;
1656	}
1657	if (normalize_overflow(&yourtm.tm_hour, &yourtm.tm_min, MINSPERHOUR))
1658		return WRONG;
1659	if (normalize_overflow(&yourtm.tm_mday, &yourtm.tm_hour, HOURSPERDAY))
1660		return WRONG;
1661	y = yourtm.tm_year;
1662	if (long_normalize_overflow(&y, &yourtm.tm_mon, MONSPERYEAR))
1663		return WRONG;
1664	/*
1665	** Turn y into an actual year number for now.
1666	** It is converted back to an offset from TM_YEAR_BASE later.
1667	*/
1668	if (long_increment_overflow(&y, TM_YEAR_BASE))
1669		return WRONG;
1670	while (yourtm.tm_mday <= 0) {
1671		if (long_increment_overflow(&y, -1))
1672			return WRONG;
1673		li = y + (1 < yourtm.tm_mon);
1674		yourtm.tm_mday += year_lengths[isleap(li)];
1675	}
1676	while (yourtm.tm_mday > DAYSPERLYEAR) {
1677		li = y + (1 < yourtm.tm_mon);
1678		yourtm.tm_mday -= year_lengths[isleap(li)];
1679		if (long_increment_overflow(&y, 1))
1680			return WRONG;
1681	}
1682	for ( ; ; ) {
1683		i = mon_lengths[isleap(y)][yourtm.tm_mon];
1684		if (yourtm.tm_mday <= i)
1685			break;
1686		yourtm.tm_mday -= i;
1687		if (++yourtm.tm_mon >= MONSPERYEAR) {
1688			yourtm.tm_mon = 0;
1689			if (long_increment_overflow(&y, 1))
1690				return WRONG;
1691		}
1692	}
1693	if (long_increment_overflow(&y, -TM_YEAR_BASE))
1694		return WRONG;
1695	yourtm.tm_year = y;
1696	if (yourtm.tm_year != y)
1697		return WRONG;
1698	if (yourtm.tm_sec >= 0 && yourtm.tm_sec < SECSPERMIN)
1699		saved_seconds = 0;
1700	else if (y + TM_YEAR_BASE < EPOCH_YEAR) {
1701		/*
1702		** We can't set tm_sec to 0, because that might push the
1703		** time below the minimum representable time.
1704		** Set tm_sec to 59 instead.
1705		** This assumes that the minimum representable time is
1706		** not in the same minute that a leap second was deleted from,
1707		** which is a safer assumption than using 58 would be.
1708		*/
1709		if (increment_overflow(&yourtm.tm_sec, 1 - SECSPERMIN))
1710			return WRONG;
1711		saved_seconds = yourtm.tm_sec;
1712		yourtm.tm_sec = SECSPERMIN - 1;
1713	} else {
1714		saved_seconds = yourtm.tm_sec;
1715		yourtm.tm_sec = 0;
1716	}
1717	/*
1718	** Do a binary search (this works whatever time_t's type is).
1719	*/
1720	lo = 1;
1721	for (i = 0; i < (int) TYPE_BIT(time_t) - 1; ++i)
1722		lo *= 2;
1723	hi = -(lo + 1);
1724	for ( ; ; ) {
1725		t = lo / 2 + hi / 2;
1726		if (t < lo)
1727			t = lo;
1728		else if (t > hi)
1729			t = hi;
1730		if ((*funcp)(&t, offset, &mytm) == NULL) {
1731			/*
1732			** Assume that t is too extreme to be represented in
1733			** a struct tm; arrange things so that it is less
1734			** extreme on the next pass.
1735			*/
1736			dir = (t > 0) ? 1 : -1;
1737		} else
1738			dir = tmcomp(&mytm, &yourtm);
1739		if (dir != 0) {
1740			if (t == lo) {
1741				++t;
1742				if (t <= lo)
1743					return WRONG;
1744				++lo;
1745			} else if (t == hi) {
1746				--t;
1747				if (t >= hi)
1748					return WRONG;
1749				--hi;
1750			}
1751			if (lo > hi)
1752				return WRONG;
1753			if (dir > 0)
1754				hi = t;
1755			else
1756				lo = t;
1757			continue;
1758		}
1759		if (yourtm.tm_isdst < 0 || mytm.tm_isdst == yourtm.tm_isdst)
1760			break;
1761		/*
1762		** Right time, wrong type.
1763		** Hunt for right time, right type.
1764		** It's okay to guess wrong since the guess
1765		** gets checked.
1766		*/
1767		sp = (const struct state *)
1768		    ((funcp == localsub) ? lclptr : gmtptr);
1769		if (sp == NULL)
1770			return WRONG;
1771		for (i = sp->typecnt - 1; i >= 0; --i) {
1772			if (sp->ttis[i].tt_isdst != yourtm.tm_isdst)
1773				continue;
1774			for (j = sp->typecnt - 1; j >= 0; --j) {
1775				if (sp->ttis[j].tt_isdst == yourtm.tm_isdst)
1776					continue;
1777				newt = t + sp->ttis[j].tt_gmtoff -
1778					sp->ttis[i].tt_gmtoff;
1779				if ((*funcp)(&newt, offset, &mytm) == NULL)
1780					continue;
1781				if (tmcomp(&mytm, &yourtm) != 0)
1782					continue;
1783				if (mytm.tm_isdst != yourtm.tm_isdst)
1784					continue;
1785				/*
1786				** We have a match.
1787				*/
1788				t = newt;
1789				goto label;
1790			}
1791		}
1792		return WRONG;
1793	}
1794label:
1795	newt = t + saved_seconds;
1796	if ((newt < t) != (saved_seconds < 0))
1797		return WRONG;
1798	t = newt;
1799	if ((*funcp)(&t, offset, tmp))
1800		*okayp = TRUE;
1801	return t;
1802}
1803
1804static time_t
1805time2(struct tm *tmp, struct tm * (*funcp)(const time_t *, long, struct tm *),
1806    long offset, int *okayp)
1807{
1808	time_t	t;
1809
1810	/*
1811	** First try without normalization of seconds
1812	** (in case tm_sec contains a value associated with a leap second).
1813	** If that fails, try with normalization of seconds.
1814	*/
1815	t = time2sub(tmp, funcp, offset, okayp, FALSE);
1816	return *okayp ? t : time2sub(tmp, funcp, offset, okayp, TRUE);
1817}
1818
1819static time_t
1820time1(struct tm *tmp, struct tm * (*funcp)(const time_t *, long, struct tm *),
1821    long offset)
1822{
1823	time_t			t;
1824	const struct state *	sp;
1825	int			samei, otheri;
1826	int			sameind, otherind;
1827	int			i;
1828	int			nseen;
1829	int			seen[TZ_MAX_TYPES];
1830	int			types[TZ_MAX_TYPES];
1831	int			okay;
1832
1833	if (tmp == NULL) {
1834		errno = EINVAL;
1835		return WRONG;
1836	}
1837	if (tmp->tm_isdst > 1)
1838		tmp->tm_isdst = 1;
1839	t = time2(tmp, funcp, offset, &okay);
1840#ifdef PCTS
1841	/*
1842	** PCTS code courtesy Grant Sullivan.
1843	*/
1844	if (okay)
1845		return t;
1846	if (tmp->tm_isdst < 0)
1847		tmp->tm_isdst = 0;	/* reset to std and try again */
1848#endif /* defined PCTS */
1849#ifndef PCTS
1850	if (okay || tmp->tm_isdst < 0)
1851		return t;
1852#endif /* !defined PCTS */
1853	/*
1854	** We're supposed to assume that somebody took a time of one type
1855	** and did some math on it that yielded a "struct tm" that's bad.
1856	** We try to divine the type they started from and adjust to the
1857	** type they need.
1858	*/
1859	sp = (const struct state *) ((funcp == localsub) ?  lclptr : gmtptr);
1860	if (sp == NULL)
1861		return WRONG;
1862	for (i = 0; i < sp->typecnt; ++i)
1863		seen[i] = FALSE;
1864	nseen = 0;
1865	for (i = sp->timecnt - 1; i >= 0; --i) {
1866		if (!seen[sp->types[i]]) {
1867			seen[sp->types[i]] = TRUE;
1868			types[nseen++] = sp->types[i];
1869		}
1870	}
1871	for (sameind = 0; sameind < nseen; ++sameind) {
1872		samei = types[sameind];
1873		if (sp->ttis[samei].tt_isdst != tmp->tm_isdst)
1874			continue;
1875		for (otherind = 0; otherind < nseen; ++otherind) {
1876			otheri = types[otherind];
1877			if (sp->ttis[otheri].tt_isdst == tmp->tm_isdst)
1878				continue;
1879			tmp->tm_sec += sp->ttis[otheri].tt_gmtoff -
1880			    sp->ttis[samei].tt_gmtoff;
1881			tmp->tm_isdst = !tmp->tm_isdst;
1882			t = time2(tmp, funcp, offset, &okay);
1883			if (okay)
1884				return t;
1885			tmp->tm_sec -= sp->ttis[otheri].tt_gmtoff -
1886			    sp->ttis[samei].tt_gmtoff;
1887			tmp->tm_isdst = !tmp->tm_isdst;
1888		}
1889	}
1890	return WRONG;
1891}
1892
1893time_t
1894mktime(struct tm *tmp)
1895{
1896	time_t ret;
1897
1898	_THREAD_PRIVATE_MUTEX_LOCK(lcl);
1899	tzset_basic();
1900	ret = time1(tmp, localsub, 0L);
1901	_THREAD_PRIVATE_MUTEX_UNLOCK(lcl);
1902	return ret;
1903}
1904DEF_STRONG(mktime);
1905
1906#ifdef STD_INSPIRED
1907
1908time_t
1909timelocal(struct tm *tmp)
1910{
1911	if (tmp != NULL)
1912		tmp->tm_isdst = -1;	/* in case it wasn't initialized */
1913	return mktime(tmp);
1914}
1915
1916time_t
1917timegm(struct tm *tmp)
1918{
1919	if (tmp != NULL)
1920		tmp->tm_isdst = 0;
1921	return time1(tmp, gmtsub, 0L);
1922}
1923
1924time_t
1925timeoff(struct tm *tmp, long offset)
1926{
1927	if (tmp != NULL)
1928		tmp->tm_isdst = 0;
1929	return time1(tmp, gmtsub, offset);
1930}
1931
1932#endif /* defined STD_INSPIRED */
1933
1934/*
1935** XXX--is the below the right way to conditionalize??
1936*/
1937
1938#ifdef STD_INSPIRED
1939
1940/*
1941** IEEE Std 1003.1-1988 (POSIX) legislates that 536457599
1942** shall correspond to "Wed Dec 31 23:59:59 UTC 1986", which
1943** is not the case if we are accounting for leap seconds.
1944** So, we provide the following conversion routines for use
1945** when exchanging timestamps with POSIX conforming systems.
1946*/
1947
1948static long
1949leapcorr(time_t *timep)
1950{
1951	struct state *		sp;
1952	struct lsinfo *	lp;
1953	int			i;
1954
1955	sp = lclptr;
1956	i = sp->leapcnt;
1957	while (--i >= 0) {
1958		lp = &sp->lsis[i];
1959		if (*timep >= lp->ls_trans)
1960			return lp->ls_corr;
1961	}
1962	return 0;
1963}
1964
1965time_t
1966time2posix(time_t t)
1967{
1968	tzset();
1969	return t - leapcorr(&t);
1970}
1971
1972time_t
1973posix2time(time_t t)
1974{
1975	time_t	x;
1976	time_t	y;
1977
1978	tzset();
1979	/*
1980	** For a positive leap second hit, the result
1981	** is not unique. For a negative leap second
1982	** hit, the corresponding time doesn't exist,
1983	** so we return an adjacent second.
1984	*/
1985	x = t + leapcorr(&t);
1986	y = x - leapcorr(&x);
1987	if (y < t) {
1988		do {
1989			x++;
1990			y = x - leapcorr(&x);
1991		} while (y < t);
1992		if (t != y)
1993			return x - 1;
1994	} else if (y > t) {
1995		do {
1996			--x;
1997			y = x - leapcorr(&x);
1998		} while (y > t);
1999		if (t != y)
2000			return x + 1;
2001	}
2002	return x;
2003}
2004
2005#endif /* defined STD_INSPIRED */
2006