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