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