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