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