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