localtime.c revision 1.117
1/* $NetBSD: localtime.c,v 1.117 2019/04/04 19:27:28 christos Exp $ */ 2 3/* Convert timestamp from time_t to struct tm. */ 4 5/* 6** This file is in the public domain, so clarified as of 7** 1996-06-05 by Arthur David Olson. 8*/ 9 10#include <sys/cdefs.h> 11#if defined(LIBC_SCCS) && !defined(lint) 12#if 0 13static char elsieid[] = "@(#)localtime.c 8.17"; 14#else 15__RCSID("$NetBSD: localtime.c,v 1.117 2019/04/04 19:27:28 christos Exp $"); 16#endif 17#endif /* LIBC_SCCS and not lint */ 18 19/* 20** Leap second handling from Bradley White. 21** POSIX-style TZ environment variable handling from Guy Harris. 22*/ 23 24/*LINTLIBRARY*/ 25 26#include "namespace.h" 27#include <assert.h> 28#define LOCALTIME_IMPLEMENTATION 29#include "private.h" 30 31#include "tzfile.h" 32#include <fcntl.h> 33 34#if NETBSD_INSPIRED 35# define NETBSD_INSPIRED_EXTERN 36#else 37# define NETBSD_INSPIRED_EXTERN static 38#endif 39 40#if defined(__weak_alias) 41__weak_alias(daylight,_daylight) 42__weak_alias(tzname,_tzname) 43#endif 44 45#ifndef TZ_ABBR_MAX_LEN 46#define TZ_ABBR_MAX_LEN 16 47#endif /* !defined TZ_ABBR_MAX_LEN */ 48 49#ifndef TZ_ABBR_CHAR_SET 50#define TZ_ABBR_CHAR_SET \ 51 "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789 :+-._" 52#endif /* !defined TZ_ABBR_CHAR_SET */ 53 54#ifndef TZ_ABBR_ERR_CHAR 55#define TZ_ABBR_ERR_CHAR '_' 56#endif /* !defined TZ_ABBR_ERR_CHAR */ 57 58/* 59** SunOS 4.1.1 headers lack O_BINARY. 60*/ 61 62#ifdef O_BINARY 63#define OPEN_MODE (O_RDONLY | O_BINARY | O_CLOEXEC) 64#endif /* defined O_BINARY */ 65#ifndef O_BINARY 66#define OPEN_MODE (O_RDONLY | O_CLOEXEC) 67#endif /* !defined O_BINARY */ 68 69#ifndef WILDABBR 70/* 71** Someone might make incorrect use of a time zone abbreviation: 72** 1. They might reference tzname[0] before calling tzset (explicitly 73** or implicitly). 74** 2. They might reference tzname[1] before calling tzset (explicitly 75** or implicitly). 76** 3. They might reference tzname[1] after setting to a time zone 77** in which Daylight Saving Time is never observed. 78** 4. They might reference tzname[0] after setting to a time zone 79** in which Standard Time is never observed. 80** 5. They might reference tm.TM_ZONE after calling offtime. 81** What's best to do in the above cases is open to debate; 82** for now, we just set things up so that in any of the five cases 83** WILDABBR is used. Another possibility: initialize tzname[0] to the 84** string "tzname[0] used before set", and similarly for the other cases. 85** And another: initialize tzname[0] to "ERA", with an explanation in the 86** manual page of what this "time zone abbreviation" means (doing this so 87** that tzname[0] has the "normal" length of three characters). 88*/ 89#define WILDABBR " " 90#endif /* !defined WILDABBR */ 91 92static const char wildabbr[] = WILDABBR; 93 94static const char gmt[] = "GMT"; 95 96/* 97** The DST rules to use if TZ has no rules and we can't load TZDEFRULES. 98** Default to US rules as of 2017-05-07. 99** POSIX does not specify the default DST rules; 100** for historical reasons, US rules are a common default. 101*/ 102#ifndef TZDEFRULESTRING 103#define TZDEFRULESTRING ",M3.2.0,M11.1.0" 104#endif 105 106struct ttinfo { /* time type information */ 107 int_fast32_t tt_gmtoff; /* UT offset in seconds */ 108 bool tt_isdst; /* used to set tm_isdst */ 109 int tt_abbrind; /* abbreviation list index */ 110 bool tt_ttisstd; /* transition is std time */ 111 bool tt_ttisgmt; /* transition is UT */ 112}; 113 114struct lsinfo { /* leap second information */ 115 time_t ls_trans; /* transition time */ 116 int_fast64_t ls_corr; /* correction to apply */ 117}; 118 119#define SMALLEST(a, b) (((a) < (b)) ? (a) : (b)) 120#define BIGGEST(a, b) (((a) > (b)) ? (a) : (b)) 121 122#ifdef TZNAME_MAX 123#define MY_TZNAME_MAX TZNAME_MAX 124#endif /* defined TZNAME_MAX */ 125#ifndef TZNAME_MAX 126#define MY_TZNAME_MAX 255 127#endif /* !defined TZNAME_MAX */ 128 129#define state __state 130struct state { 131 int leapcnt; 132 int timecnt; 133 int typecnt; 134 int charcnt; 135 bool goback; 136 bool goahead; 137 time_t ats[TZ_MAX_TIMES]; 138 unsigned char types[TZ_MAX_TIMES]; 139 struct ttinfo ttis[TZ_MAX_TYPES]; 140 char chars[/*CONSTCOND*/BIGGEST(BIGGEST(TZ_MAX_CHARS + 1, 141 sizeof gmt), (2 * (MY_TZNAME_MAX + 1)))]; 142 struct lsinfo lsis[TZ_MAX_LEAPS]; 143 144 /* The time type to use for early times or if no transitions. 145 It is always zero for recent tzdb releases. 146 It might be nonzero for data from tzdb 2018e or earlier. */ 147 int defaulttype; 148}; 149 150enum r_type { 151 JULIAN_DAY, /* Jn = Julian day */ 152 DAY_OF_YEAR, /* n = day of year */ 153 MONTH_NTH_DAY_OF_WEEK /* Mm.n.d = month, week, day of week */ 154}; 155 156struct rule { 157 enum r_type r_type; /* type of rule */ 158 int r_day; /* day number of rule */ 159 int r_week; /* week number of rule */ 160 int r_mon; /* month number of rule */ 161 int_fast32_t r_time; /* transition time of rule */ 162}; 163 164static struct tm *gmtsub(struct state const *, time_t const *, int_fast32_t, 165 struct tm *); 166static bool increment_overflow(int *, int); 167static bool increment_overflow_time(time_t *, int_fast32_t); 168static bool normalize_overflow32(int_fast32_t *, int *, int); 169static struct tm *timesub(time_t const *, int_fast32_t, struct state const *, 170 struct tm *); 171static bool typesequiv(struct state const *, int, int); 172static bool tzparse(char const *, struct state *, bool); 173 174static timezone_t gmtptr; 175 176#ifndef TZ_STRLEN_MAX 177#define TZ_STRLEN_MAX 255 178#endif /* !defined TZ_STRLEN_MAX */ 179 180static char lcl_TZname[TZ_STRLEN_MAX + 1]; 181static int lcl_is_set; 182 183 184#if !defined(__LIBC12_SOURCE__) 185timezone_t __lclptr; 186#ifdef _REENTRANT 187rwlock_t __lcl_lock = RWLOCK_INITIALIZER; 188#endif 189#endif 190 191/* 192** Section 4.12.3 of X3.159-1989 requires that 193** Except for the strftime function, these functions [asctime, 194** ctime, gmtime, localtime] return values in one of two static 195** objects: a broken-down time structure and an array of char. 196** Thanks to Paul Eggert for noting this. 197*/ 198 199static struct tm tm; 200 201#if !HAVE_POSIX_DECLS || TZ_TIME_T || defined(__NetBSD__) 202# if !defined(__LIBC12_SOURCE__) 203 204__aconst char * tzname[2] = { 205 (__aconst char *)__UNCONST(wildabbr), 206 (__aconst char *)__UNCONST(wildabbr) 207}; 208 209# else 210 211extern __aconst char * tzname[2]; 212 213# endif /* __LIBC12_SOURCE__ */ 214 215# if USG_COMPAT 216# if !defined(__LIBC12_SOURCE__) 217long timezone = 0; 218int daylight = 0; 219# else 220extern int daylight; 221extern long timezone __RENAME(__timezone13); 222# endif /* __LIBC12_SOURCE__ */ 223# endif /* defined USG_COMPAT */ 224 225# ifdef ALTZONE 226long altzone = 0; 227# endif /* defined ALTZONE */ 228#endif /* !HAVE_POSIX_DECLS */ 229 230/* Initialize *S to a value based on GMTOFF, ISDST, and ABBRIND. */ 231static void 232init_ttinfo(struct ttinfo *s, int_fast32_t gmtoff, bool isdst, int abbrind) 233{ 234 s->tt_gmtoff = gmtoff; 235 s->tt_isdst = isdst; 236 s->tt_abbrind = abbrind; 237 s->tt_ttisstd = false; 238 s->tt_ttisgmt = false; 239} 240 241static int_fast32_t 242detzcode(const char *const codep) 243{ 244 int_fast32_t result; 245 int i; 246 int_fast32_t one = 1; 247 int_fast32_t halfmaxval = one << (32 - 2); 248 int_fast32_t maxval = halfmaxval - 1 + halfmaxval; 249 int_fast32_t minval = -1 - maxval; 250 251 result = codep[0] & 0x7f; 252 for (i = 1; i < 4; ++i) 253 result = (result << 8) | (codep[i] & 0xff); 254 255 if (codep[0] & 0x80) { 256 /* Do two's-complement negation even on non-two's-complement machines. 257 If the result would be minval - 1, return minval. */ 258 result -= !TWOS_COMPLEMENT(int_fast32_t) && result != 0; 259 result += minval; 260 } 261 return result; 262} 263 264static int_fast64_t 265detzcode64(const char *const codep) 266{ 267 int_fast64_t result; 268 int i; 269 int_fast64_t one = 1; 270 int_fast64_t halfmaxval = one << (64 - 2); 271 int_fast64_t maxval = halfmaxval - 1 + halfmaxval; 272 int_fast64_t minval = -TWOS_COMPLEMENT(int_fast64_t) - maxval; 273 274 result = codep[0] & 0x7f; 275 for (i = 1; i < 8; ++i) 276 result = (result << 8) | (codep[i] & 0xff); 277 278 if (codep[0] & 0x80) { 279 /* Do two's-complement negation even on non-two's-complement machines. 280 If the result would be minval - 1, return minval. */ 281 result -= !TWOS_COMPLEMENT(int_fast64_t) && result != 0; 282 result += minval; 283 } 284 return result; 285} 286 287const char * 288tzgetname(const timezone_t sp, int isdst) 289{ 290 int i; 291 for (i = 0; i < sp->typecnt; ++i) { 292 const struct ttinfo *const ttisp = &sp->ttis[sp->types[i]]; 293 294 if (ttisp->tt_isdst == isdst) 295 return &sp->chars[ttisp->tt_abbrind]; 296 } 297 errno = ESRCH; 298 return NULL; 299} 300 301long 302tzgetgmtoff(const timezone_t sp, int isdst) 303{ 304 int i; 305 long l = -1; 306 for (i = 0; i < sp->typecnt; ++i) { 307 const struct ttinfo *const ttisp = &sp->ttis[sp->types[i]]; 308 309 if (ttisp->tt_isdst == isdst) { 310 l = ttisp->tt_gmtoff; 311 if (sp->types[i] != 0) 312 return l; 313 } 314 } 315 if (l == -1) 316 errno = ESRCH; 317 return l; 318} 319 320static void 321scrub_abbrs(struct state *sp) 322{ 323 int i; 324 325 /* 326 ** First, replace bogus characters. 327 */ 328 for (i = 0; i < sp->charcnt; ++i) 329 if (strchr(TZ_ABBR_CHAR_SET, sp->chars[i]) == NULL) 330 sp->chars[i] = TZ_ABBR_ERR_CHAR; 331 /* 332 ** Second, truncate long abbreviations. 333 */ 334 for (i = 0; i < sp->typecnt; ++i) { 335 const struct ttinfo * const ttisp = &sp->ttis[i]; 336 char * cp = &sp->chars[ttisp->tt_abbrind]; 337 338 if (strlen(cp) > TZ_ABBR_MAX_LEN && 339 strcmp(cp, GRANDPARENTED) != 0) 340 *(cp + TZ_ABBR_MAX_LEN) = '\0'; 341 } 342} 343 344static void 345update_tzname_etc(const struct state *sp, const struct ttinfo *ttisp) 346{ 347#if HAVE_TZNAME 348 tzname[ttisp->tt_isdst] = __UNCONST(&sp->chars[ttisp->tt_abbrind]); 349#endif 350#if USG_COMPAT 351 if (!ttisp->tt_isdst) 352 timezone = - ttisp->tt_gmtoff; 353#endif 354#ifdef ALTZONE 355 if (ttisp->tt_isdst) 356 altzone = - ttisp->tt_gmtoff; 357#endif /* defined ALTZONE */ 358} 359 360static void 361settzname(void) 362{ 363 timezone_t const sp = __lclptr; 364 int i; 365 366#if HAVE_TZNAME 367 tzname[0] = tzname[1] = 368 (__aconst char *) __UNCONST(sp ? wildabbr : gmt); 369#endif 370#if USG_COMPAT 371 daylight = 0; 372 timezone = 0; 373#endif 374#ifdef ALTZONE 375 altzone = 0; 376#endif /* defined ALTZONE */ 377 if (sp == NULL) { 378 return; 379 } 380 /* 381 ** And to get the latest time zone abbreviations into tzname. . . 382 */ 383 for (i = 0; i < sp->typecnt; ++i) 384 update_tzname_etc(sp, &sp->ttis[i]); 385 386 for (i = 0; i < sp->timecnt; ++i) { 387 const struct ttinfo * const ttisp = &sp->ttis[sp->types[i]]; 388 update_tzname_etc(sp, ttisp); 389#if USG_COMPAT 390 if (ttisp->tt_isdst) 391 daylight = 1; 392#endif 393 } 394} 395 396static bool 397differ_by_repeat(const time_t t1, const time_t t0) 398{ 399 if (TYPE_BIT(time_t) - TYPE_SIGNED(time_t) < SECSPERREPEAT_BITS) 400 return 0; 401 return (int_fast64_t)t1 - (int_fast64_t)t0 == SECSPERREPEAT; 402} 403 404union input_buffer { 405 /* The first part of the buffer, interpreted as a header. */ 406 struct tzhead tzhead; 407 408 /* The entire buffer. */ 409 char buf[2 * sizeof(struct tzhead) + 2 * sizeof (struct state) 410 + 4 * TZ_MAX_TIMES]; 411}; 412 413/* TZDIR with a trailing '/' rather than a trailing '\0'. */ 414static char const tzdirslash[sizeof TZDIR] = TZDIR "/"; 415 416/* Local storage needed for 'tzloadbody'. */ 417union local_storage { 418 /* The results of analyzing the file's contents after it is opened. */ 419 struct file_analysis { 420 /* The input buffer. */ 421 union input_buffer u; 422 423 /* A temporary state used for parsing a TZ string in the file. */ 424 struct state st; 425 } u; 426 427 /* The file name to be opened. */ 428 char fullname[/*CONSTCOND*/BIGGEST(sizeof (struct file_analysis), 429 sizeof tzdirslash + 1024)]; 430}; 431 432/* Load tz data from the file named NAME into *SP. Read extended 433 format if DOEXTEND. Use *LSP for temporary storage. Return 0 on 434 success, an errno value on failure. */ 435static int 436tzloadbody(char const *name, struct state *sp, bool doextend, 437 union local_storage *lsp) 438{ 439 int i; 440 int fid; 441 int stored; 442 ssize_t nread; 443 bool doaccess; 444 union input_buffer *up = &lsp->u.u; 445 size_t tzheadsize = sizeof(struct tzhead); 446 447 sp->goback = sp->goahead = false; 448 449 if (! name) { 450 name = TZDEFAULT; 451 if (! name) 452 return EINVAL; 453 } 454 455 if (name[0] == ':') 456 ++name; 457#ifdef SUPPRESS_TZDIR 458 /* Do not prepend TZDIR. This is intended for specialized 459 applications only, due to its security implications. */ 460 doaccess = true; 461#else 462 doaccess = name[0] == '/'; 463#endif 464 if (!doaccess) { 465 char const *dot; 466 size_t namelen = strlen(name); 467 if (sizeof lsp->fullname - sizeof tzdirslash <= namelen) 468 return ENAMETOOLONG; 469 470 /* Create a string "TZDIR/NAME". Using sprintf here 471 would pull in stdio (and would fail if the 472 resulting string length exceeded INT_MAX!). */ 473 memcpy(lsp->fullname, tzdirslash, sizeof tzdirslash); 474 strcpy(lsp->fullname + sizeof tzdirslash, name); 475 476 /* Set doaccess if NAME contains a ".." file name 477 component, as such a name could read a file outside 478 the TZDIR virtual subtree. */ 479 for (dot = name; (dot = strchr(dot, '.')) != NULL; dot++) 480 if ((dot == name || dot[-1] == '/') && dot[1] == '.' 481 && (dot[2] == '/' || !dot[2])) { 482 doaccess = true; 483 break; 484 } 485 486 name = lsp->fullname; 487 } 488 if (doaccess && access(name, R_OK) != 0) 489 return errno; 490 491 fid = open(name, OPEN_MODE); 492 if (fid < 0) 493 return errno; 494 nread = read(fid, up->buf, sizeof up->buf); 495 if (nread < (ssize_t)tzheadsize) { 496 int err = nread < 0 ? errno : EINVAL; 497 close(fid); 498 return err; 499 } 500 if (close(fid) < 0) 501 return errno; 502 for (stored = 4; stored <= 8; stored *= 2) { 503 int_fast32_t ttisstdcnt = detzcode(up->tzhead.tzh_ttisstdcnt); 504 int_fast32_t ttisgmtcnt = detzcode(up->tzhead.tzh_ttisgmtcnt); 505 int_fast64_t prevtr = 0; 506 int_fast32_t prevcorr = 0; 507 int_fast32_t leapcnt = detzcode(up->tzhead.tzh_leapcnt); 508 int_fast32_t timecnt = detzcode(up->tzhead.tzh_timecnt); 509 int_fast32_t typecnt = detzcode(up->tzhead.tzh_typecnt); 510 int_fast32_t charcnt = detzcode(up->tzhead.tzh_charcnt); 511 char const *p = up->buf + tzheadsize; 512 /* Although tzfile(5) currently requires typecnt to be nonzero, 513 support future formats that may allow zero typecnt 514 in files that have a TZ string and no transitions. */ 515 if (! (0 <= leapcnt && leapcnt < TZ_MAX_LEAPS 516 && 0 <= typecnt && typecnt < TZ_MAX_TYPES 517 && 0 <= timecnt && timecnt < TZ_MAX_TIMES 518 && 0 <= charcnt && charcnt < TZ_MAX_CHARS 519 && (ttisstdcnt == typecnt || ttisstdcnt == 0) 520 && (ttisgmtcnt == typecnt || ttisgmtcnt == 0))) 521 return EINVAL; 522 if ((size_t)nread 523 < (tzheadsize /* struct tzhead */ 524 + timecnt * stored /* ats */ 525 + timecnt /* types */ 526 + typecnt * 6 /* ttinfos */ 527 + charcnt /* chars */ 528 + leapcnt * (stored + 4) /* lsinfos */ 529 + ttisstdcnt /* ttisstds */ 530 + ttisgmtcnt)) /* ttisgmts */ 531 return EINVAL; 532 sp->leapcnt = leapcnt; 533 sp->timecnt = timecnt; 534 sp->typecnt = typecnt; 535 sp->charcnt = charcnt; 536 537 /* Read transitions, discarding those out of time_t range. 538 But pretend the last transition before TIME_T_MIN 539 occurred at TIME_T_MIN. */ 540 timecnt = 0; 541 for (i = 0; i < sp->timecnt; ++i) { 542 int_fast64_t at 543 = stored == 4 ? detzcode(p) : detzcode64(p); 544 sp->types[i] = at <= TIME_T_MAX; 545 if (sp->types[i]) { 546 time_t attime 547 = ((TYPE_SIGNED(time_t) ? 548 at < TIME_T_MIN : at < 0) 549 ? TIME_T_MIN : (time_t)at); 550 if (timecnt && attime <= sp->ats[timecnt - 1]) { 551 if (attime < sp->ats[timecnt - 1]) 552 return EINVAL; 553 sp->types[i - 1] = 0; 554 timecnt--; 555 } 556 sp->ats[timecnt++] = attime; 557 } 558 p += stored; 559 } 560 561 timecnt = 0; 562 for (i = 0; i < sp->timecnt; ++i) { 563 unsigned char typ = *p++; 564 if (sp->typecnt <= typ) 565 return EINVAL; 566 if (sp->types[i]) 567 sp->types[timecnt++] = typ; 568 } 569 sp->timecnt = timecnt; 570 for (i = 0; i < sp->typecnt; ++i) { 571 struct ttinfo * ttisp; 572 unsigned char isdst, abbrind; 573 574 ttisp = &sp->ttis[i]; 575 ttisp->tt_gmtoff = detzcode(p); 576 p += 4; 577 isdst = *p++; 578 if (! (isdst < 2)) 579 return EINVAL; 580 ttisp->tt_isdst = isdst; 581 abbrind = *p++; 582 if (! (abbrind < sp->charcnt)) 583 return EINVAL; 584 ttisp->tt_abbrind = abbrind; 585 } 586 for (i = 0; i < sp->charcnt; ++i) 587 sp->chars[i] = *p++; 588 sp->chars[i] = '\0'; /* ensure '\0' at end */ 589 590 /* Read leap seconds, discarding those out of time_t range. */ 591 leapcnt = 0; 592 for (i = 0; i < sp->leapcnt; ++i) { 593 int_fast64_t tr = stored == 4 ? detzcode(p) : 594 detzcode64(p); 595 int_fast32_t corr = detzcode(p + stored); 596 p += stored + 4; 597 /* Leap seconds cannot occur before the Epoch. */ 598 if (tr < 0) 599 return EINVAL; 600 if (tr <= TIME_T_MAX) { 601 /* Leap seconds cannot occur more than once per UTC month, 602 and UTC months are at least 28 days long (minus 1 603 second for a negative leap second). Each leap second's 604 correction must differ from the previous one's by 1 605 second. */ 606 if (tr - prevtr < 28 * SECSPERDAY - 1 607 || (corr != prevcorr - 1 608 && corr != prevcorr + 1)) 609 return EINVAL; 610 611 sp->lsis[leapcnt].ls_trans = 612 (time_t)(prevtr = tr); 613 sp->lsis[leapcnt].ls_corr = prevcorr = corr; 614 leapcnt++; 615 } 616 } 617 sp->leapcnt = leapcnt; 618 619 for (i = 0; i < sp->typecnt; ++i) { 620 struct ttinfo * ttisp; 621 622 ttisp = &sp->ttis[i]; 623 if (ttisstdcnt == 0) 624 ttisp->tt_ttisstd = false; 625 else { 626 if (*p != true && *p != false) 627 return EINVAL; 628 ttisp->tt_ttisstd = *p++; 629 } 630 } 631 for (i = 0; i < sp->typecnt; ++i) { 632 struct ttinfo * ttisp; 633 634 ttisp = &sp->ttis[i]; 635 if (ttisgmtcnt == 0) 636 ttisp->tt_ttisgmt = false; 637 else { 638 if (*p != true && *p != false) 639 return EINVAL; 640 ttisp->tt_ttisgmt = *p++; 641 } 642 } 643 /* 644 ** If this is an old file, we're done. 645 */ 646 if (up->tzhead.tzh_version[0] == '\0') 647 break; 648 nread -= p - up->buf; 649 memmove(up->buf, p, (size_t)nread); 650 } 651 if (doextend && nread > 2 && 652 up->buf[0] == '\n' && up->buf[nread - 1] == '\n' && 653 sp->typecnt + 2 <= TZ_MAX_TYPES) { 654 struct state *ts = &lsp->u.st; 655 656 up->buf[nread - 1] = '\0'; 657 if (tzparse(&up->buf[1], ts, false)) { 658 659 /* Attempt to reuse existing abbreviations. 660 Without this, America/Anchorage would be right on 661 the edge after 2037 when TZ_MAX_CHARS is 50, as 662 sp->charcnt equals 40 (for LMT AST AWT APT AHST 663 AHDT YST AKDT AKST) and ts->charcnt equals 10 664 (for AKST AKDT). Reusing means sp->charcnt can 665 stay 40 in this example. */ 666 int gotabbr = 0; 667 int charcnt = sp->charcnt; 668 for (i = 0; i < ts->typecnt; i++) { 669 char *tsabbr = ts->chars + ts->ttis[i].tt_abbrind; 670 int j; 671 for (j = 0; j < charcnt; j++) 672 if (strcmp(sp->chars + j, tsabbr) == 0) { 673 ts->ttis[i].tt_abbrind = j; 674 gotabbr++; 675 break; 676 } 677 if (! (j < charcnt)) { 678 size_t tsabbrlen = strlen(tsabbr); 679 if (j + tsabbrlen < TZ_MAX_CHARS) { 680 strcpy(sp->chars + j, tsabbr); 681 charcnt = (int_fast32_t)(j + tsabbrlen + 1); 682 ts->ttis[i].tt_abbrind = j; 683 gotabbr++; 684 } 685 } 686 } 687 if (gotabbr == ts->typecnt) { 688 sp->charcnt = charcnt; 689 690 /* Ignore any trailing, no-op transitions generated 691 by zic as they don't help here and can run afoul 692 of bugs in zic 2016j or earlier. */ 693 while (1 < sp->timecnt 694 && (sp->types[sp->timecnt - 1] 695 == sp->types[sp->timecnt - 2])) 696 sp->timecnt--; 697 698 for (i = 0; i < ts->timecnt; i++) 699 if (sp->timecnt == 0 700 || sp->ats[sp->timecnt - 1] < ts->ats[i]) 701 break; 702 while (i < ts->timecnt 703 && sp->timecnt < TZ_MAX_TIMES) { 704 sp->ats[sp->timecnt] = ts->ats[i]; 705 sp->types[sp->timecnt] = (sp->typecnt 706 + ts->types[i]); 707 sp->timecnt++; 708 i++; 709 } 710 for (i = 0; i < ts->typecnt; i++) 711 sp->ttis[sp->typecnt++] = ts->ttis[i]; 712 } 713 } 714 } 715 if (sp->typecnt == 0) 716 return EINVAL; 717 if (sp->timecnt > 1) { 718 for (i = 1; i < sp->timecnt; ++i) 719 if (typesequiv(sp, sp->types[i], sp->types[0]) && 720 differ_by_repeat(sp->ats[i], sp->ats[0])) { 721 sp->goback = true; 722 break; 723 } 724 for (i = sp->timecnt - 2; i >= 0; --i) 725 if (typesequiv(sp, sp->types[sp->timecnt - 1], 726 sp->types[i]) && 727 differ_by_repeat(sp->ats[sp->timecnt - 1], 728 sp->ats[i])) { 729 sp->goahead = true; 730 break; 731 } 732 } 733 734 /* Infer sp->defaulttype from the data. Although this default 735 type is always zero for data from recent tzdb releases, 736 things are trickier for data from tzdb 2018e or earlier. 737 738 The first set of heuristics work around bugs in 32-bit data 739 generated by tzdb 2013c or earlier. The workaround is for 740 zones like Australia/Macquarie where timestamps before the 741 first transition have a time type that is not the earliest 742 standard-time type. See: 743 https://mm.icann.org/pipermail/tz/2013-May/019368.html */ 744 /* 745 ** If type 0 is unused in transitions, 746 ** it's the type to use for early times. 747 */ 748 for (i = 0; i < sp->timecnt; ++i) 749 if (sp->types[i] == 0) 750 break; 751 i = i < sp->timecnt ? -1 : 0; 752 /* 753 ** Absent the above, 754 ** if there are transition times 755 ** and the first transition is to a daylight time 756 ** find the standard type less than and closest to 757 ** the type of the first transition. 758 */ 759 if (i < 0 && sp->timecnt > 0 && sp->ttis[sp->types[0]].tt_isdst) { 760 i = sp->types[0]; 761 while (--i >= 0) 762 if (!sp->ttis[i].tt_isdst) 763 break; 764 } 765 /* The next heuristics are for data generated by tzdb 2018e or 766 earlier, for zones like EST5EDT where the first transition 767 is to DST. */ 768 /* 769 ** If no result yet, find the first standard type. 770 ** If there is none, punt to type zero. 771 */ 772 if (i < 0) { 773 i = 0; 774 while (sp->ttis[i].tt_isdst) 775 if (++i >= sp->typecnt) { 776 i = 0; 777 break; 778 } 779 } 780 /* A simple 'sp->defaulttype = 0;' would suffice here if we 781 didn't have to worry about 2018e-or-earlier data. Even 782 simpler would be to remove the defaulttype member and just 783 use 0 in its place. */ 784 sp->defaulttype = i; 785 786 return 0; 787} 788 789/* Load tz data from the file named NAME into *SP. Read extended 790 format if DOEXTEND. Return 0 on success, an errno value on failure. */ 791static int 792tzload(char const *name, struct state *sp, bool doextend) 793{ 794 union local_storage *lsp = malloc(sizeof *lsp); 795 if (!lsp) 796 return errno; 797 else { 798 int err = tzloadbody(name, sp, doextend, lsp); 799 free(lsp); 800 return err; 801 } 802} 803 804static bool 805typesequiv(const struct state *sp, int a, int b) 806{ 807 bool result; 808 809 if (sp == NULL || 810 a < 0 || a >= sp->typecnt || 811 b < 0 || b >= sp->typecnt) 812 result = false; 813 else { 814 const struct ttinfo * ap = &sp->ttis[a]; 815 const struct ttinfo * bp = &sp->ttis[b]; 816 result = ap->tt_gmtoff == bp->tt_gmtoff && 817 ap->tt_isdst == bp->tt_isdst && 818 ap->tt_ttisstd == bp->tt_ttisstd && 819 ap->tt_ttisgmt == bp->tt_ttisgmt && 820 strcmp(&sp->chars[ap->tt_abbrind], 821 &sp->chars[bp->tt_abbrind]) == 0; 822 } 823 return result; 824} 825 826static const int mon_lengths[2][MONSPERYEAR] = { 827 { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }, 828 { 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 } 829}; 830 831static const int year_lengths[2] = { 832 DAYSPERNYEAR, DAYSPERLYEAR 833}; 834 835/* 836** Given a pointer into a timezone string, scan until a character that is not 837** a valid character in a time zone abbreviation is found. 838** Return a pointer to that character. 839*/ 840 841static ATTRIBUTE_PURE const char * 842getzname(const char *strp) 843{ 844 char c; 845 846 while ((c = *strp) != '\0' && !is_digit(c) && c != ',' && c != '-' && 847 c != '+') 848 ++strp; 849 return strp; 850} 851 852/* 853** Given a pointer into an extended timezone string, scan until the ending 854** delimiter of the time zone abbreviation is located. 855** Return a pointer to the delimiter. 856** 857** As with getzname above, the legal character set is actually quite 858** restricted, with other characters producing undefined results. 859** We don't do any checking here; checking is done later in common-case code. 860*/ 861 862static ATTRIBUTE_PURE const char * 863getqzname(const char *strp, const int delim) 864{ 865 int c; 866 867 while ((c = *strp) != '\0' && c != delim) 868 ++strp; 869 return strp; 870} 871 872/* 873** Given a pointer into a timezone string, extract a number from that string. 874** Check that the number is within a specified range; if it is not, return 875** NULL. 876** Otherwise, return a pointer to the first character not part of the number. 877*/ 878 879static const char * 880getnum(const char *strp, int *const nump, const int min, const int max) 881{ 882 char c; 883 int num; 884 885 if (strp == NULL || !is_digit(c = *strp)) { 886 errno = EINVAL; 887 return NULL; 888 } 889 num = 0; 890 do { 891 num = num * 10 + (c - '0'); 892 if (num > max) { 893 errno = EOVERFLOW; 894 return NULL; /* illegal value */ 895 } 896 c = *++strp; 897 } while (is_digit(c)); 898 if (num < min) { 899 errno = EINVAL; 900 return NULL; /* illegal value */ 901 } 902 *nump = num; 903 return strp; 904} 905 906/* 907** Given a pointer into a timezone string, extract a number of seconds, 908** in hh[:mm[:ss]] form, from the string. 909** If any error occurs, return NULL. 910** Otherwise, return a pointer to the first character not part of the number 911** of seconds. 912*/ 913 914static const char * 915getsecs(const char *strp, int_fast32_t *const secsp) 916{ 917 int num; 918 919 /* 920 ** 'HOURSPERDAY * DAYSPERWEEK - 1' allows quasi-Posix rules like 921 ** "M10.4.6/26", which does not conform to Posix, 922 ** but which specifies the equivalent of 923 ** "02:00 on the first Sunday on or after 23 Oct". 924 */ 925 strp = getnum(strp, &num, 0, HOURSPERDAY * DAYSPERWEEK - 1); 926 if (strp == NULL) 927 return NULL; 928 *secsp = num * (int_fast32_t) SECSPERHOUR; 929 if (*strp == ':') { 930 ++strp; 931 strp = getnum(strp, &num, 0, MINSPERHOUR - 1); 932 if (strp == NULL) 933 return NULL; 934 *secsp += num * SECSPERMIN; 935 if (*strp == ':') { 936 ++strp; 937 /* 'SECSPERMIN' allows for leap seconds. */ 938 strp = getnum(strp, &num, 0, SECSPERMIN); 939 if (strp == NULL) 940 return NULL; 941 *secsp += num; 942 } 943 } 944 return strp; 945} 946 947/* 948** Given a pointer into a timezone string, extract an offset, in 949** [+-]hh[:mm[:ss]] form, from the string. 950** If any error occurs, return NULL. 951** Otherwise, return a pointer to the first character not part of the time. 952*/ 953 954static const char * 955getoffset(const char *strp, int_fast32_t *const offsetp) 956{ 957 bool neg = false; 958 959 if (*strp == '-') { 960 neg = true; 961 ++strp; 962 } else if (*strp == '+') 963 ++strp; 964 strp = getsecs(strp, offsetp); 965 if (strp == NULL) 966 return NULL; /* illegal time */ 967 if (neg) 968 *offsetp = -*offsetp; 969 return strp; 970} 971 972/* 973** Given a pointer into a timezone string, extract a rule in the form 974** date[/time]. See POSIX section 8 for the format of "date" and "time". 975** If a valid rule is not found, return NULL. 976** Otherwise, return a pointer to the first character not part of the rule. 977*/ 978 979static const char * 980getrule(const char *strp, struct rule *const rulep) 981{ 982 if (*strp == 'J') { 983 /* 984 ** Julian day. 985 */ 986 rulep->r_type = JULIAN_DAY; 987 ++strp; 988 strp = getnum(strp, &rulep->r_day, 1, DAYSPERNYEAR); 989 } else if (*strp == 'M') { 990 /* 991 ** Month, week, day. 992 */ 993 rulep->r_type = MONTH_NTH_DAY_OF_WEEK; 994 ++strp; 995 strp = getnum(strp, &rulep->r_mon, 1, MONSPERYEAR); 996 if (strp == NULL) 997 return NULL; 998 if (*strp++ != '.') 999 return NULL; 1000 strp = getnum(strp, &rulep->r_week, 1, 5); 1001 if (strp == NULL) 1002 return NULL; 1003 if (*strp++ != '.') 1004 return NULL; 1005 strp = getnum(strp, &rulep->r_day, 0, DAYSPERWEEK - 1); 1006 } else if (is_digit(*strp)) { 1007 /* 1008 ** Day of year. 1009 */ 1010 rulep->r_type = DAY_OF_YEAR; 1011 strp = getnum(strp, &rulep->r_day, 0, DAYSPERLYEAR - 1); 1012 } else return NULL; /* invalid format */ 1013 if (strp == NULL) 1014 return NULL; 1015 if (*strp == '/') { 1016 /* 1017 ** Time specified. 1018 */ 1019 ++strp; 1020 strp = getoffset(strp, &rulep->r_time); 1021 } else rulep->r_time = 2 * SECSPERHOUR; /* default = 2:00:00 */ 1022 return strp; 1023} 1024 1025/* 1026** Given a year, a rule, and the offset from UT at the time that rule takes 1027** effect, calculate the year-relative time that rule takes effect. 1028*/ 1029 1030static int_fast32_t 1031transtime(const int year, const struct rule *const rulep, 1032 const int_fast32_t offset) 1033{ 1034 bool leapyear; 1035 int_fast32_t value; 1036 int i; 1037 int d, m1, yy0, yy1, yy2, dow; 1038 1039 INITIALIZE(value); 1040 leapyear = isleap(year); 1041 switch (rulep->r_type) { 1042 1043 case JULIAN_DAY: 1044 /* 1045 ** Jn - Julian day, 1 == January 1, 60 == March 1 even in leap 1046 ** years. 1047 ** In non-leap years, or if the day number is 59 or less, just 1048 ** add SECSPERDAY times the day number-1 to the time of 1049 ** January 1, midnight, to get the day. 1050 */ 1051 value = (rulep->r_day - 1) * SECSPERDAY; 1052 if (leapyear && rulep->r_day >= 60) 1053 value += SECSPERDAY; 1054 break; 1055 1056 case DAY_OF_YEAR: 1057 /* 1058 ** n - day of year. 1059 ** Just add SECSPERDAY times the day number to the time of 1060 ** January 1, midnight, to get the day. 1061 */ 1062 value = rulep->r_day * SECSPERDAY; 1063 break; 1064 1065 case MONTH_NTH_DAY_OF_WEEK: 1066 /* 1067 ** Mm.n.d - nth "dth day" of month m. 1068 */ 1069 1070 /* 1071 ** Use Zeller's Congruence to get day-of-week of first day of 1072 ** month. 1073 */ 1074 m1 = (rulep->r_mon + 9) % 12 + 1; 1075 yy0 = (rulep->r_mon <= 2) ? (year - 1) : year; 1076 yy1 = yy0 / 100; 1077 yy2 = yy0 % 100; 1078 dow = ((26 * m1 - 2) / 10 + 1079 1 + yy2 + yy2 / 4 + yy1 / 4 - 2 * yy1) % 7; 1080 if (dow < 0) 1081 dow += DAYSPERWEEK; 1082 1083 /* 1084 ** "dow" is the day-of-week of the first day of the month. Get 1085 ** the day-of-month (zero-origin) of the first "dow" day of the 1086 ** month. 1087 */ 1088 d = rulep->r_day - dow; 1089 if (d < 0) 1090 d += DAYSPERWEEK; 1091 for (i = 1; i < rulep->r_week; ++i) { 1092 if (d + DAYSPERWEEK >= 1093 mon_lengths[leapyear][rulep->r_mon - 1]) 1094 break; 1095 d += DAYSPERWEEK; 1096 } 1097 1098 /* 1099 ** "d" is the day-of-month (zero-origin) of the day we want. 1100 */ 1101 value = d * SECSPERDAY; 1102 for (i = 0; i < rulep->r_mon - 1; ++i) 1103 value += mon_lengths[leapyear][i] * SECSPERDAY; 1104 break; 1105 } 1106 1107 /* 1108 ** "value" is the year-relative time of 00:00:00 UT on the day in 1109 ** question. To get the year-relative time of the specified local 1110 ** time on that day, add the transition time and the current offset 1111 ** from UT. 1112 */ 1113 return value + rulep->r_time + offset; 1114} 1115 1116/* 1117** Given a POSIX section 8-style TZ string, fill in the rule tables as 1118** appropriate. 1119*/ 1120 1121static bool 1122tzparse(const char *name, struct state *sp, bool lastditch) 1123{ 1124 const char * stdname; 1125 const char * dstname; 1126 size_t stdlen; 1127 size_t dstlen; 1128 size_t charcnt; 1129 int_fast32_t stdoffset; 1130 int_fast32_t dstoffset; 1131 char * cp; 1132 bool load_ok; 1133 1134 dstname = NULL; /* XXX gcc */ 1135 stdname = name; 1136 if (lastditch) { 1137 stdlen = sizeof gmt - 1; 1138 name += stdlen; 1139 stdoffset = 0; 1140 } else { 1141 if (*name == '<') { 1142 name++; 1143 stdname = name; 1144 name = getqzname(name, '>'); 1145 if (*name != '>') 1146 return false; 1147 stdlen = name - stdname; 1148 name++; 1149 } else { 1150 name = getzname(name); 1151 stdlen = name - stdname; 1152 } 1153 if (!stdlen) 1154 return false; 1155 name = getoffset(name, &stdoffset); 1156 if (name == NULL) 1157 return false; 1158 } 1159 charcnt = stdlen + 1; 1160 if (sizeof sp->chars < charcnt) 1161 return false; 1162 load_ok = tzload(TZDEFRULES, sp, false) == 0; 1163 if (!load_ok) 1164 sp->leapcnt = 0; /* so, we're off a little */ 1165 if (*name != '\0') { 1166 if (*name == '<') { 1167 dstname = ++name; 1168 name = getqzname(name, '>'); 1169 if (*name != '>') 1170 return false; 1171 dstlen = name - dstname; 1172 name++; 1173 } else { 1174 dstname = name; 1175 name = getzname(name); 1176 dstlen = name - dstname; /* length of DST abbr. */ 1177 } 1178 if (!dstlen) 1179 return false; 1180 charcnt += dstlen + 1; 1181 if (sizeof sp->chars < charcnt) 1182 return false; 1183 if (*name != '\0' && *name != ',' && *name != ';') { 1184 name = getoffset(name, &dstoffset); 1185 if (name == NULL) 1186 return false; 1187 } else dstoffset = stdoffset - SECSPERHOUR; 1188 if (*name == '\0' && !load_ok) 1189 name = TZDEFRULESTRING; 1190 if (*name == ',' || *name == ';') { 1191 struct rule start; 1192 struct rule end; 1193 int year; 1194 int yearlim; 1195 int timecnt; 1196 time_t janfirst; 1197 int_fast32_t janoffset = 0; 1198 int yearbeg; 1199 1200 ++name; 1201 if ((name = getrule(name, &start)) == NULL) 1202 return false; 1203 if (*name++ != ',') 1204 return false; 1205 if ((name = getrule(name, &end)) == NULL) 1206 return false; 1207 if (*name != '\0') 1208 return false; 1209 sp->typecnt = 2; /* standard time and DST */ 1210 /* 1211 ** Two transitions per year, from EPOCH_YEAR forward. 1212 */ 1213 init_ttinfo(&sp->ttis[0], -stdoffset, false, 0); 1214 init_ttinfo(&sp->ttis[1], -dstoffset, true, 1215 (int)(stdlen + 1)); 1216 sp->defaulttype = 0; 1217 timecnt = 0; 1218 janfirst = 0; 1219 yearbeg = EPOCH_YEAR; 1220 1221 do { 1222 int_fast32_t yearsecs 1223 = year_lengths[isleap(yearbeg - 1)] * SECSPERDAY; 1224 yearbeg--; 1225 if (increment_overflow_time(&janfirst, -yearsecs)) { 1226 janoffset = -yearsecs; 1227 break; 1228 } 1229 } while (EPOCH_YEAR - YEARSPERREPEAT / 2 < yearbeg); 1230 1231 yearlim = yearbeg + YEARSPERREPEAT + 1; 1232 for (year = yearbeg; year < yearlim; year++) { 1233 int_fast32_t 1234 starttime = transtime(year, &start, stdoffset), 1235 endtime = transtime(year, &end, dstoffset); 1236 int_fast32_t 1237 yearsecs = (year_lengths[isleap(year)] 1238 * SECSPERDAY); 1239 bool reversed = endtime < starttime; 1240 if (reversed) { 1241 int_fast32_t swap = starttime; 1242 starttime = endtime; 1243 endtime = swap; 1244 } 1245 if (reversed 1246 || (starttime < endtime 1247 && (endtime - starttime 1248 < (yearsecs 1249 + (stdoffset - dstoffset))))) { 1250 if (TZ_MAX_TIMES - 2 < timecnt) 1251 break; 1252 sp->ats[timecnt] = janfirst; 1253 if (! increment_overflow_time 1254 (&sp->ats[timecnt], 1255 janoffset + starttime)) 1256 sp->types[timecnt++] = !reversed; 1257 sp->ats[timecnt] = janfirst; 1258 if (! increment_overflow_time 1259 (&sp->ats[timecnt], 1260 janoffset + endtime)) { 1261 sp->types[timecnt++] = reversed; 1262 yearlim = year + YEARSPERREPEAT + 1; 1263 } 1264 } 1265 if (increment_overflow_time 1266 (&janfirst, janoffset + yearsecs)) 1267 break; 1268 janoffset = 0; 1269 } 1270 sp->timecnt = timecnt; 1271 if (! timecnt) { 1272 sp->ttis[0] = sp->ttis[1]; 1273 sp->typecnt = 1; /* Perpetual DST. */ 1274 } else if (YEARSPERREPEAT < year - yearbeg) 1275 sp->goback = sp->goahead = true; 1276 } else { 1277 int_fast32_t theirstdoffset; 1278 int_fast32_t theirdstoffset; 1279 int_fast32_t theiroffset; 1280 bool isdst; 1281 int i; 1282 int j; 1283 1284 if (*name != '\0') 1285 return false; 1286 /* 1287 ** Initial values of theirstdoffset and theirdstoffset. 1288 */ 1289 theirstdoffset = 0; 1290 for (i = 0; i < sp->timecnt; ++i) { 1291 j = sp->types[i]; 1292 if (!sp->ttis[j].tt_isdst) { 1293 theirstdoffset = 1294 -sp->ttis[j].tt_gmtoff; 1295 break; 1296 } 1297 } 1298 theirdstoffset = 0; 1299 for (i = 0; i < sp->timecnt; ++i) { 1300 j = sp->types[i]; 1301 if (sp->ttis[j].tt_isdst) { 1302 theirdstoffset = 1303 -sp->ttis[j].tt_gmtoff; 1304 break; 1305 } 1306 } 1307 /* 1308 ** Initially we're assumed to be in standard time. 1309 */ 1310 isdst = false; 1311 theiroffset = theirstdoffset; 1312 /* 1313 ** Now juggle transition times and types 1314 ** tracking offsets as you do. 1315 */ 1316 for (i = 0; i < sp->timecnt; ++i) { 1317 j = sp->types[i]; 1318 sp->types[i] = sp->ttis[j].tt_isdst; 1319 if (sp->ttis[j].tt_ttisgmt) { 1320 /* No adjustment to transition time */ 1321 } else { 1322 /* 1323 ** If daylight saving time is in 1324 ** effect, and the transition time was 1325 ** not specified as standard time, add 1326 ** the daylight saving time offset to 1327 ** the transition time; otherwise, add 1328 ** the standard time offset to the 1329 ** transition time. 1330 */ 1331 /* 1332 ** Transitions from DST to DDST 1333 ** will effectively disappear since 1334 ** POSIX provides for only one DST 1335 ** offset. 1336 */ 1337 if (isdst && !sp->ttis[j].tt_ttisstd) { 1338 sp->ats[i] += (time_t) 1339 (dstoffset - theirdstoffset); 1340 } else { 1341 sp->ats[i] += (time_t) 1342 (stdoffset - theirstdoffset); 1343 } 1344 } 1345 theiroffset = -sp->ttis[j].tt_gmtoff; 1346 if (sp->ttis[j].tt_isdst) 1347 theirstdoffset = theiroffset; 1348 else theirdstoffset = theiroffset; 1349 } 1350 /* 1351 ** Finally, fill in ttis. 1352 */ 1353 init_ttinfo(&sp->ttis[0], -stdoffset, false, 0); 1354 init_ttinfo(&sp->ttis[1], -dstoffset, true, 1355 (int)(stdlen + 1)); 1356 sp->typecnt = 2; 1357 sp->defaulttype = 0; 1358 } 1359 } else { 1360 dstlen = 0; 1361 sp->typecnt = 1; /* only standard time */ 1362 sp->timecnt = 0; 1363 init_ttinfo(&sp->ttis[0], -stdoffset, false, 0); 1364 init_ttinfo(&sp->ttis[1], 0, false, 0); 1365 sp->defaulttype = 0; 1366 } 1367 sp->charcnt = (int)charcnt; 1368 cp = sp->chars; 1369 (void) memcpy(cp, stdname, stdlen); 1370 cp += stdlen; 1371 *cp++ = '\0'; 1372 if (dstlen != 0) { 1373 (void) memcpy(cp, dstname, dstlen); 1374 *(cp + dstlen) = '\0'; 1375 } 1376 return true; 1377} 1378 1379static void 1380gmtload(struct state *const sp) 1381{ 1382 if (tzload(gmt, sp, true) != 0) 1383 (void) tzparse(gmt, sp, true); 1384} 1385 1386static int 1387zoneinit(struct state *sp, char const *name) 1388{ 1389 if (name && ! name[0]) { 1390 /* 1391 ** User wants it fast rather than right. 1392 */ 1393 sp->leapcnt = 0; /* so, we're off a little */ 1394 sp->timecnt = 0; 1395 sp->typecnt = 0; 1396 sp->charcnt = 0; 1397 sp->goback = sp->goahead = false; 1398 init_ttinfo(&sp->ttis[0], 0, false, 0); 1399 strcpy(sp->chars, gmt); 1400 sp->defaulttype = 0; 1401 return 0; 1402 } else { 1403 int err = tzload(name, sp, true); 1404 if (err != 0 && name && name[0] != ':' && 1405 tzparse(name, sp, false)) 1406 err = 0; 1407 if (err == 0) 1408 scrub_abbrs(sp); 1409 return err; 1410 } 1411} 1412 1413static void 1414tzsetlcl(char const *name) 1415{ 1416 struct state *sp = __lclptr; 1417 int lcl = name ? strlen(name) < sizeof lcl_TZname : -1; 1418 if (lcl < 0 ? lcl_is_set < 0 1419 : 0 < lcl_is_set && strcmp(lcl_TZname, name) == 0) 1420 return; 1421 1422 if (! sp) 1423 __lclptr = sp = malloc(sizeof *__lclptr); 1424 if (sp) { 1425 if (zoneinit(sp, name) != 0) 1426 zoneinit(sp, ""); 1427 if (0 < lcl) 1428 strcpy(lcl_TZname, name); 1429 } 1430 settzname(); 1431 lcl_is_set = lcl; 1432} 1433 1434#ifdef STD_INSPIRED 1435void 1436tzsetwall(void) 1437{ 1438 rwlock_wrlock(&__lcl_lock); 1439 tzsetlcl(NULL); 1440 rwlock_unlock(&__lcl_lock); 1441} 1442#endif 1443 1444void 1445tzset_unlocked(void) 1446{ 1447 tzsetlcl(getenv("TZ")); 1448} 1449 1450void 1451tzset(void) 1452{ 1453 rwlock_wrlock(&__lcl_lock); 1454 tzset_unlocked(); 1455 rwlock_unlock(&__lcl_lock); 1456} 1457 1458static void 1459gmtcheck(void) 1460{ 1461 static bool gmt_is_set; 1462 rwlock_wrlock(&__lcl_lock); 1463 if (! gmt_is_set) { 1464 gmtptr = malloc(sizeof *gmtptr); 1465 if (gmtptr) 1466 gmtload(gmtptr); 1467 gmt_is_set = true; 1468 } 1469 rwlock_unlock(&__lcl_lock); 1470} 1471 1472#if NETBSD_INSPIRED 1473 1474timezone_t 1475tzalloc(const char *name) 1476{ 1477 timezone_t sp = malloc(sizeof *sp); 1478 if (sp) { 1479 int err = zoneinit(sp, name); 1480 if (err != 0) { 1481 free(sp); 1482 errno = err; 1483 return NULL; 1484 } 1485 } 1486 return sp; 1487} 1488 1489void 1490tzfree(timezone_t sp) 1491{ 1492 free(sp); 1493} 1494 1495/* 1496** NetBSD 6.1.4 has ctime_rz, but omit it because POSIX says ctime and 1497** ctime_r are obsolescent and have potential security problems that 1498** ctime_rz would share. Callers can instead use localtime_rz + strftime. 1499** 1500** NetBSD 6.1.4 has tzgetname, but omit it because it doesn't work 1501** in zones with three or more time zone abbreviations. 1502** Callers can instead use localtime_rz + strftime. 1503*/ 1504 1505#endif 1506 1507/* 1508** The easy way to behave "as if no library function calls" localtime 1509** is to not call it, so we drop its guts into "localsub", which can be 1510** freely called. (And no, the PANS doesn't require the above behavior, 1511** but it *is* desirable.) 1512** 1513** If successful and SETNAME is nonzero, 1514** set the applicable parts of tzname, timezone and altzone; 1515** however, it's OK to omit this step if the timezone is POSIX-compatible, 1516** since in that case tzset should have already done this step correctly. 1517** SETNAME's type is intfast32_t for compatibility with gmtsub, 1518** but it is actually a boolean and its value should be 0 or 1. 1519*/ 1520 1521/*ARGSUSED*/ 1522static struct tm * 1523localsub(struct state const *sp, time_t const *timep, int_fast32_t setname, 1524 struct tm *const tmp) 1525{ 1526 const struct ttinfo * ttisp; 1527 int i; 1528 struct tm * result; 1529 const time_t t = *timep; 1530 1531 if (sp == NULL) { 1532 /* Don't bother to set tzname etc.; tzset has already done it. */ 1533 return gmtsub(gmtptr, timep, 0, tmp); 1534 } 1535 if ((sp->goback && t < sp->ats[0]) || 1536 (sp->goahead && t > sp->ats[sp->timecnt - 1])) { 1537 time_t newt = t; 1538 time_t seconds; 1539 time_t years; 1540 1541 if (t < sp->ats[0]) 1542 seconds = sp->ats[0] - t; 1543 else seconds = t - sp->ats[sp->timecnt - 1]; 1544 --seconds; 1545 years = (time_t)((seconds / SECSPERREPEAT + 1) * YEARSPERREPEAT); 1546 seconds = (time_t)(years * AVGSECSPERYEAR); 1547 if (t < sp->ats[0]) 1548 newt += seconds; 1549 else newt -= seconds; 1550 if (newt < sp->ats[0] || 1551 newt > sp->ats[sp->timecnt - 1]) { 1552 errno = EINVAL; 1553 return NULL; /* "cannot happen" */ 1554 } 1555 result = localsub(sp, &newt, setname, tmp); 1556 if (result) { 1557 int_fast64_t newy; 1558 1559 newy = result->tm_year; 1560 if (t < sp->ats[0]) 1561 newy -= years; 1562 else newy += years; 1563 if (! (INT_MIN <= newy && newy <= INT_MAX)) { 1564 errno = EOVERFLOW; 1565 return NULL; 1566 } 1567 result->tm_year = (int)newy; 1568 } 1569 return result; 1570 } 1571 if (sp->timecnt == 0 || t < sp->ats[0]) { 1572 i = sp->defaulttype; 1573 } else { 1574 int lo = 1; 1575 int hi = sp->timecnt; 1576 1577 while (lo < hi) { 1578 int mid = (lo + hi) / 2; 1579 1580 if (t < sp->ats[mid]) 1581 hi = mid; 1582 else lo = mid + 1; 1583 } 1584 i = (int) sp->types[lo - 1]; 1585 } 1586 ttisp = &sp->ttis[i]; 1587 /* 1588 ** To get (wrong) behavior that's compatible with System V Release 2.0 1589 ** you'd replace the statement below with 1590 ** t += ttisp->tt_gmtoff; 1591 ** timesub(&t, 0L, sp, tmp); 1592 */ 1593 result = timesub(&t, ttisp->tt_gmtoff, sp, tmp); 1594 if (result) { 1595 result->tm_isdst = ttisp->tt_isdst; 1596#ifdef TM_ZONE 1597 result->TM_ZONE = __UNCONST(&sp->chars[ttisp->tt_abbrind]); 1598#endif /* defined TM_ZONE */ 1599 if (setname) 1600 update_tzname_etc(sp, ttisp); 1601 } 1602 return result; 1603} 1604 1605#if NETBSD_INSPIRED 1606 1607struct tm * 1608localtime_rz(timezone_t sp, time_t const *timep, struct tm *tmp) 1609{ 1610 return localsub(sp, timep, 0, tmp); 1611} 1612 1613#endif 1614 1615static struct tm * 1616localtime_tzset(time_t const *timep, struct tm *tmp, bool setname) 1617{ 1618 rwlock_wrlock(&__lcl_lock); 1619 if (setname || !lcl_is_set) 1620 tzset_unlocked(); 1621 tmp = localsub(__lclptr, timep, setname, tmp); 1622 rwlock_unlock(&__lcl_lock); 1623 return tmp; 1624} 1625 1626struct tm * 1627localtime(const time_t *timep) 1628{ 1629 return localtime_tzset(timep, &tm, true); 1630} 1631 1632struct tm * 1633localtime_r(const time_t * __restrict timep, struct tm *tmp) 1634{ 1635 return localtime_tzset(timep, tmp, true); 1636} 1637 1638/* 1639** gmtsub is to gmtime as localsub is to localtime. 1640*/ 1641 1642static struct tm * 1643gmtsub(struct state const *sp, const time_t *timep, int_fast32_t offset, 1644 struct tm *tmp) 1645{ 1646 struct tm * result; 1647 1648 result = timesub(timep, offset, gmtptr, tmp); 1649#ifdef TM_ZONE 1650 /* 1651 ** Could get fancy here and deliver something such as 1652 ** "+xx" or "-xx" if offset is non-zero, 1653 ** but this is no time for a treasure hunt. 1654 */ 1655 if (result) 1656 result->TM_ZONE = offset ? __UNCONST(wildabbr) : gmtptr ? 1657 gmtptr->chars : __UNCONST(gmt); 1658#endif /* defined TM_ZONE */ 1659 return result; 1660} 1661 1662 1663/* 1664** Re-entrant version of gmtime. 1665*/ 1666 1667struct tm * 1668gmtime_r(const time_t *timep, struct tm *tmp) 1669{ 1670 gmtcheck(); 1671 return gmtsub(NULL, timep, 0, tmp); 1672} 1673 1674struct tm * 1675gmtime(const time_t *timep) 1676{ 1677 return gmtime_r(timep, &tm); 1678} 1679#ifdef STD_INSPIRED 1680 1681struct tm * 1682offtime(const time_t *timep, long offset) 1683{ 1684 gmtcheck(); 1685 return gmtsub(gmtptr, timep, (int_fast32_t)offset, &tm); 1686} 1687 1688struct tm * 1689offtime_r(const time_t *timep, long offset, struct tm *tmp) 1690{ 1691 gmtcheck(); 1692 return gmtsub(NULL, timep, (int_fast32_t)offset, tmp); 1693} 1694 1695#endif /* defined STD_INSPIRED */ 1696 1697#if TZ_TIME_T 1698 1699# if USG_COMPAT 1700# define daylight 0 1701# define timezone 0 1702# endif 1703# ifndef ALTZONE 1704# define altzone 0 1705# endif 1706 1707/* Convert from the underlying system's time_t to the ersatz time_tz, 1708 which is called 'time_t' in this file. Typically, this merely 1709 converts the time's integer width. On some platforms, the system 1710 time is local time not UT, or uses some epoch other than the POSIX 1711 epoch. 1712 1713 Although this code appears to define a function named 'time' that 1714 returns time_t, the macros in private.h cause this code to actually 1715 define a function named 'tz_time' that returns tz_time_t. The call 1716 to sys_time invokes the underlying system's 'time' function. */ 1717 1718time_t 1719time(time_t *p) 1720{ 1721 time_t r = sys_time(0); 1722 if (r != (time_t) -1) { 1723 int_fast32_t offset = EPOCH_LOCAL ? (daylight ? timezone : altzone) : 0; 1724 if (increment_overflow32(&offset, -EPOCH_OFFSET) 1725 || increment_overflow_time (&r, offset)) { 1726 errno = EOVERFLOW; 1727 r = -1; 1728 } 1729 } 1730 if (p) 1731 *p = r; 1732 return r; 1733} 1734#endif 1735 1736/* 1737** Return the number of leap years through the end of the given year 1738** where, to make the math easy, the answer for year zero is defined as zero. 1739*/ 1740static int 1741leaps_thru_end_of_nonneg(int y) 1742{ 1743 return y / 4 - y / 100 + y / 400; 1744} 1745 1746static int ATTRIBUTE_PURE 1747leaps_thru_end_of(const int y) 1748{ 1749 return (y < 0 1750 ? -1 - leaps_thru_end_of_nonneg(-1 - y) 1751 : leaps_thru_end_of_nonneg(y)); 1752} 1753 1754static struct tm * 1755timesub(const time_t *timep, int_fast32_t offset, 1756 const struct state *sp, struct tm *tmp) 1757{ 1758 const struct lsinfo * lp; 1759 time_t tdays; 1760 int idays; /* unsigned would be so 2003 */ 1761 int_fast64_t rem; 1762 int y; 1763 const int * ip; 1764 int_fast64_t corr; 1765 int hit; 1766 int i; 1767 1768 corr = 0; 1769 hit = false; 1770 i = (sp == NULL) ? 0 : sp->leapcnt; 1771 while (--i >= 0) { 1772 lp = &sp->lsis[i]; 1773 if (*timep >= lp->ls_trans) { 1774 corr = lp->ls_corr; 1775 hit = (*timep == lp->ls_trans 1776 && (i == 0 ? 0 : lp[-1].ls_corr) < corr); 1777 break; 1778 } 1779 } 1780 y = EPOCH_YEAR; 1781 tdays = (time_t)(*timep / SECSPERDAY); 1782 rem = *timep % SECSPERDAY; 1783 while (tdays < 0 || tdays >= year_lengths[isleap(y)]) { 1784 int newy; 1785 time_t tdelta; 1786 int idelta; 1787 int leapdays; 1788 1789 tdelta = tdays / DAYSPERLYEAR; 1790 if (! ((! TYPE_SIGNED(time_t) || INT_MIN <= tdelta) 1791 && tdelta <= INT_MAX)) 1792 goto out_of_range; 1793 _DIAGASSERT(__type_fit(int, tdelta)); 1794 idelta = (int)tdelta; 1795 if (idelta == 0) 1796 idelta = (tdays < 0) ? -1 : 1; 1797 newy = y; 1798 if (increment_overflow(&newy, idelta)) 1799 goto out_of_range; 1800 leapdays = leaps_thru_end_of(newy - 1) - 1801 leaps_thru_end_of(y - 1); 1802 tdays -= ((time_t) newy - y) * DAYSPERNYEAR; 1803 tdays -= leapdays; 1804 y = newy; 1805 } 1806 /* 1807 ** Given the range, we can now fearlessly cast... 1808 */ 1809 idays = (int) tdays; 1810 rem += offset - corr; 1811 while (rem < 0) { 1812 rem += SECSPERDAY; 1813 --idays; 1814 } 1815 while (rem >= SECSPERDAY) { 1816 rem -= SECSPERDAY; 1817 ++idays; 1818 } 1819 while (idays < 0) { 1820 if (increment_overflow(&y, -1)) 1821 goto out_of_range; 1822 idays += year_lengths[isleap(y)]; 1823 } 1824 while (idays >= year_lengths[isleap(y)]) { 1825 idays -= year_lengths[isleap(y)]; 1826 if (increment_overflow(&y, 1)) 1827 goto out_of_range; 1828 } 1829 tmp->tm_year = y; 1830 if (increment_overflow(&tmp->tm_year, -TM_YEAR_BASE)) 1831 goto out_of_range; 1832 tmp->tm_yday = idays; 1833 /* 1834 ** The "extra" mods below avoid overflow problems. 1835 */ 1836 tmp->tm_wday = EPOCH_WDAY + 1837 ((y - EPOCH_YEAR) % DAYSPERWEEK) * 1838 (DAYSPERNYEAR % DAYSPERWEEK) + 1839 leaps_thru_end_of(y - 1) - 1840 leaps_thru_end_of(EPOCH_YEAR - 1) + 1841 idays; 1842 tmp->tm_wday %= DAYSPERWEEK; 1843 if (tmp->tm_wday < 0) 1844 tmp->tm_wday += DAYSPERWEEK; 1845 tmp->tm_hour = (int) (rem / SECSPERHOUR); 1846 rem %= SECSPERHOUR; 1847 tmp->tm_min = (int) (rem / SECSPERMIN); 1848 /* 1849 ** A positive leap second requires a special 1850 ** representation. This uses "... ??:59:60" et seq. 1851 */ 1852 tmp->tm_sec = (int) (rem % SECSPERMIN) + hit; 1853 ip = mon_lengths[isleap(y)]; 1854 for (tmp->tm_mon = 0; idays >= ip[tmp->tm_mon]; ++(tmp->tm_mon)) 1855 idays -= ip[tmp->tm_mon]; 1856 tmp->tm_mday = (int) (idays + 1); 1857 tmp->tm_isdst = 0; 1858#ifdef TM_GMTOFF 1859 tmp->TM_GMTOFF = offset; 1860#endif /* defined TM_GMTOFF */ 1861 return tmp; 1862out_of_range: 1863 errno = EOVERFLOW; 1864 return NULL; 1865} 1866 1867char * 1868ctime(const time_t *timep) 1869{ 1870/* 1871** Section 4.12.3.2 of X3.159-1989 requires that 1872** The ctime function converts the calendar time pointed to by timer 1873** to local time in the form of a string. It is equivalent to 1874** asctime(localtime(timer)) 1875*/ 1876 struct tm *tmp = localtime(timep); 1877 return tmp ? asctime(tmp) : NULL; 1878} 1879 1880char * 1881ctime_r(const time_t *timep, char *buf) 1882{ 1883 struct tm mytm; 1884 struct tm *tmp = localtime_r(timep, &mytm); 1885 return tmp ? asctime_r(tmp, buf) : NULL; 1886} 1887 1888char * 1889ctime_rz(const timezone_t sp, const time_t * timep, char *buf) 1890{ 1891 struct tm mytm, *rtm; 1892 1893 rtm = localtime_rz(sp, timep, &mytm); 1894 if (rtm == NULL) 1895 return NULL; 1896 return asctime_r(rtm, buf); 1897} 1898 1899/* 1900** Adapted from code provided by Robert Elz, who writes: 1901** The "best" way to do mktime I think is based on an idea of Bob 1902** Kridle's (so its said...) from a long time ago. 1903** It does a binary search of the time_t space. Since time_t's are 1904** just 32 bits, its a max of 32 iterations (even at 64 bits it 1905** would still be very reasonable). 1906*/ 1907 1908#ifndef WRONG 1909#define WRONG ((time_t)-1) 1910#endif /* !defined WRONG */ 1911 1912/* 1913** Normalize logic courtesy Paul Eggert. 1914*/ 1915 1916static bool 1917increment_overflow(int *ip, int j) 1918{ 1919 int const i = *ip; 1920 1921 /* 1922 ** If i >= 0 there can only be overflow if i + j > INT_MAX 1923 ** or if j > INT_MAX - i; given i >= 0, INT_MAX - i cannot overflow. 1924 ** If i < 0 there can only be overflow if i + j < INT_MIN 1925 ** or if j < INT_MIN - i; given i < 0, INT_MIN - i cannot overflow. 1926 */ 1927 if ((i >= 0) ? (j > INT_MAX - i) : (j < INT_MIN - i)) 1928 return true; 1929 *ip += j; 1930 return false; 1931} 1932 1933static bool 1934increment_overflow32(int_fast32_t *const lp, int const m) 1935{ 1936 int_fast32_t const l = *lp; 1937 1938 if ((l >= 0) ? (m > INT_FAST32_MAX - l) : (m < INT_FAST32_MIN - l)) 1939 return true; 1940 *lp += m; 1941 return false; 1942} 1943 1944static bool 1945increment_overflow_time(time_t *tp, int_fast32_t j) 1946{ 1947 /* 1948 ** This is like 1949 ** 'if (! (TIME_T_MIN <= *tp + j && *tp + j <= TIME_T_MAX)) ...', 1950 ** except that it does the right thing even if *tp + j would overflow. 1951 */ 1952 if (! (j < 0 1953 ? (TYPE_SIGNED(time_t) ? TIME_T_MIN - j <= *tp : -1 - j < *tp) 1954 : *tp <= TIME_T_MAX - j)) 1955 return true; 1956 *tp += j; 1957 return false; 1958} 1959 1960static bool 1961normalize_overflow(int *const tensptr, int *const unitsptr, const int base) 1962{ 1963 int tensdelta; 1964 1965 tensdelta = (*unitsptr >= 0) ? 1966 (*unitsptr / base) : 1967 (-1 - (-1 - *unitsptr) / base); 1968 *unitsptr -= tensdelta * base; 1969 return increment_overflow(tensptr, tensdelta); 1970} 1971 1972static bool 1973normalize_overflow32(int_fast32_t *tensptr, int *unitsptr, int base) 1974{ 1975 int tensdelta; 1976 1977 tensdelta = (*unitsptr >= 0) ? 1978 (*unitsptr / base) : 1979 (-1 - (-1 - *unitsptr) / base); 1980 *unitsptr -= tensdelta * base; 1981 return increment_overflow32(tensptr, tensdelta); 1982} 1983 1984static int 1985tmcomp(const struct tm *const atmp, 1986 const struct tm *const btmp) 1987{ 1988 int result; 1989 1990 if (atmp->tm_year != btmp->tm_year) 1991 return atmp->tm_year < btmp->tm_year ? -1 : 1; 1992 if ((result = (atmp->tm_mon - btmp->tm_mon)) == 0 && 1993 (result = (atmp->tm_mday - btmp->tm_mday)) == 0 && 1994 (result = (atmp->tm_hour - btmp->tm_hour)) == 0 && 1995 (result = (atmp->tm_min - btmp->tm_min)) == 0) 1996 result = atmp->tm_sec - btmp->tm_sec; 1997 return result; 1998} 1999 2000static time_t 2001time2sub(struct tm *const tmp, 2002 struct tm *(*funcp)(struct state const *, time_t const *, 2003 int_fast32_t, struct tm *), 2004 struct state const *sp, 2005 const int_fast32_t offset, 2006 bool *okayp, 2007 bool do_norm_secs) 2008{ 2009 int dir; 2010 int i, j; 2011 int saved_seconds; 2012 int_fast32_t li; 2013 time_t lo; 2014 time_t hi; 2015#ifdef NO_ERROR_IN_DST_GAP 2016 time_t ilo; 2017#endif 2018 int_fast32_t y; 2019 time_t newt; 2020 time_t t; 2021 struct tm yourtm, mytm; 2022 2023 *okayp = false; 2024 yourtm = *tmp; 2025#ifdef NO_ERROR_IN_DST_GAP 2026again: 2027#endif 2028 if (do_norm_secs) { 2029 if (normalize_overflow(&yourtm.tm_min, &yourtm.tm_sec, 2030 SECSPERMIN)) 2031 goto out_of_range; 2032 } 2033 if (normalize_overflow(&yourtm.tm_hour, &yourtm.tm_min, MINSPERHOUR)) 2034 goto out_of_range; 2035 if (normalize_overflow(&yourtm.tm_mday, &yourtm.tm_hour, HOURSPERDAY)) 2036 goto out_of_range; 2037 y = yourtm.tm_year; 2038 if (normalize_overflow32(&y, &yourtm.tm_mon, MONSPERYEAR)) 2039 goto out_of_range; 2040 /* 2041 ** Turn y into an actual year number for now. 2042 ** It is converted back to an offset from TM_YEAR_BASE later. 2043 */ 2044 if (increment_overflow32(&y, TM_YEAR_BASE)) 2045 goto out_of_range; 2046 while (yourtm.tm_mday <= 0) { 2047 if (increment_overflow32(&y, -1)) 2048 goto out_of_range; 2049 li = y + (1 < yourtm.tm_mon); 2050 yourtm.tm_mday += year_lengths[isleap(li)]; 2051 } 2052 while (yourtm.tm_mday > DAYSPERLYEAR) { 2053 li = y + (1 < yourtm.tm_mon); 2054 yourtm.tm_mday -= year_lengths[isleap(li)]; 2055 if (increment_overflow32(&y, 1)) 2056 goto out_of_range; 2057 } 2058 for ( ; ; ) { 2059 i = mon_lengths[isleap(y)][yourtm.tm_mon]; 2060 if (yourtm.tm_mday <= i) 2061 break; 2062 yourtm.tm_mday -= i; 2063 if (++yourtm.tm_mon >= MONSPERYEAR) { 2064 yourtm.tm_mon = 0; 2065 if (increment_overflow32(&y, 1)) 2066 goto out_of_range; 2067 } 2068 } 2069 if (increment_overflow32(&y, -TM_YEAR_BASE)) 2070 goto out_of_range; 2071 if (! (INT_MIN <= y && y <= INT_MAX)) 2072 goto out_of_range; 2073 yourtm.tm_year = (int)y; 2074 if (yourtm.tm_sec >= 0 && yourtm.tm_sec < SECSPERMIN) 2075 saved_seconds = 0; 2076 else if (y + TM_YEAR_BASE < EPOCH_YEAR) { 2077 /* 2078 ** We can't set tm_sec to 0, because that might push the 2079 ** time below the minimum representable time. 2080 ** Set tm_sec to 59 instead. 2081 ** This assumes that the minimum representable time is 2082 ** not in the same minute that a leap second was deleted from, 2083 ** which is a safer assumption than using 58 would be. 2084 */ 2085 if (increment_overflow(&yourtm.tm_sec, 1 - SECSPERMIN)) 2086 goto out_of_range; 2087 saved_seconds = yourtm.tm_sec; 2088 yourtm.tm_sec = SECSPERMIN - 1; 2089 } else { 2090 saved_seconds = yourtm.tm_sec; 2091 yourtm.tm_sec = 0; 2092 } 2093 /* 2094 ** Do a binary search (this works whatever time_t's type is). 2095 */ 2096 lo = TIME_T_MIN; 2097 hi = TIME_T_MAX; 2098#ifdef NO_ERROR_IN_DST_GAP 2099 ilo = lo; 2100#endif 2101 for ( ; ; ) { 2102 t = lo / 2 + hi / 2; 2103 if (t < lo) 2104 t = lo; 2105 else if (t > hi) 2106 t = hi; 2107 if (! funcp(sp, &t, offset, &mytm)) { 2108 /* 2109 ** Assume that t is too extreme to be represented in 2110 ** a struct tm; arrange things so that it is less 2111 ** extreme on the next pass. 2112 */ 2113 dir = (t > 0) ? 1 : -1; 2114 } else dir = tmcomp(&mytm, &yourtm); 2115 if (dir != 0) { 2116 if (t == lo) { 2117 if (t == TIME_T_MAX) 2118 goto out_of_range; 2119 ++t; 2120 ++lo; 2121 } else if (t == hi) { 2122 if (t == TIME_T_MIN) 2123 goto out_of_range; 2124 --t; 2125 --hi; 2126 } 2127#ifdef NO_ERROR_IN_DST_GAP 2128 if (ilo != lo && lo - 1 == hi && yourtm.tm_isdst < 0 && 2129 do_norm_secs) { 2130 for (i = sp->typecnt - 1; i >= 0; --i) { 2131 for (j = sp->typecnt - 1; j >= 0; --j) { 2132 time_t off; 2133 if (sp->ttis[j].tt_isdst == 2134 sp->ttis[i].tt_isdst) 2135 continue; 2136 off = sp->ttis[j].tt_gmtoff - 2137 sp->ttis[i].tt_gmtoff; 2138 yourtm.tm_sec += off < 0 ? 2139 -off : off; 2140 goto again; 2141 } 2142 } 2143 } 2144#endif 2145 if (lo > hi) 2146 goto invalid; 2147 if (dir > 0) 2148 hi = t; 2149 else lo = t; 2150 continue; 2151 } 2152#if defined TM_GMTOFF && ! UNINIT_TRAP 2153 if (mytm.TM_GMTOFF != yourtm.TM_GMTOFF 2154 && (yourtm.TM_GMTOFF < 0 2155 ? (-SECSPERDAY <= yourtm.TM_GMTOFF 2156 && (mytm.TM_GMTOFF <= 2157 (/*CONSTCOND*/SMALLEST (INT_FAST32_MAX, LONG_MAX) 2158 + yourtm.TM_GMTOFF))) 2159 : (yourtm.TM_GMTOFF <= SECSPERDAY 2160 && ((/*CONSTCOND*/BIGGEST (INT_FAST32_MIN, LONG_MIN) 2161 + yourtm.TM_GMTOFF) 2162 <= mytm.TM_GMTOFF)))) { 2163 /* MYTM matches YOURTM except with the wrong UT offset. 2164 YOURTM.TM_GMTOFF is plausible, so try it instead. 2165 It's OK if YOURTM.TM_GMTOFF contains uninitialized data, 2166 since the guess gets checked. */ 2167 time_t altt = t; 2168 int_fast32_t diff = (int_fast32_t) 2169 (mytm.TM_GMTOFF - yourtm.TM_GMTOFF); 2170 if (!increment_overflow_time(&altt, diff)) { 2171 struct tm alttm; 2172 if (! funcp(sp, &altt, offset, &alttm) 2173 && alttm.tm_isdst == mytm.tm_isdst 2174 && alttm.TM_GMTOFF == yourtm.TM_GMTOFF 2175 && tmcomp(&alttm, &yourtm)) { 2176 t = altt; 2177 mytm = alttm; 2178 } 2179 } 2180 } 2181#endif 2182 if (yourtm.tm_isdst < 0 || mytm.tm_isdst == yourtm.tm_isdst) 2183 break; 2184 /* 2185 ** Right time, wrong type. 2186 ** Hunt for right time, right type. 2187 ** It's okay to guess wrong since the guess 2188 ** gets checked. 2189 */ 2190 if (sp == NULL) 2191 goto invalid; 2192 for (i = sp->typecnt - 1; i >= 0; --i) { 2193 if (sp->ttis[i].tt_isdst != yourtm.tm_isdst) 2194 continue; 2195 for (j = sp->typecnt - 1; j >= 0; --j) { 2196 if (sp->ttis[j].tt_isdst == yourtm.tm_isdst) 2197 continue; 2198 newt = (time_t)(t + sp->ttis[j].tt_gmtoff - 2199 sp->ttis[i].tt_gmtoff); 2200 if (! funcp(sp, &newt, offset, &mytm)) 2201 continue; 2202 if (tmcomp(&mytm, &yourtm) != 0) 2203 continue; 2204 if (mytm.tm_isdst != yourtm.tm_isdst) 2205 continue; 2206 /* 2207 ** We have a match. 2208 */ 2209 t = newt; 2210 goto label; 2211 } 2212 } 2213 goto invalid; 2214 } 2215label: 2216 newt = t + saved_seconds; 2217 if ((newt < t) != (saved_seconds < 0)) 2218 goto out_of_range; 2219 t = newt; 2220 if (funcp(sp, &t, offset, tmp)) { 2221 *okayp = true; 2222 return t; 2223 } 2224out_of_range: 2225 errno = EOVERFLOW; 2226 return WRONG; 2227invalid: 2228 errno = EINVAL; 2229 return WRONG; 2230} 2231 2232static time_t 2233time2(struct tm * const tmp, 2234 struct tm *(*funcp)(struct state const *, time_t const *, 2235 int_fast32_t, struct tm *), 2236 struct state const *sp, 2237 const int_fast32_t offset, 2238 bool *okayp) 2239{ 2240 time_t t; 2241 2242 /* 2243 ** First try without normalization of seconds 2244 ** (in case tm_sec contains a value associated with a leap second). 2245 ** If that fails, try with normalization of seconds. 2246 */ 2247 t = time2sub(tmp, funcp, sp, offset, okayp, false); 2248 return *okayp ? t : time2sub(tmp, funcp, sp, offset, okayp, true); 2249} 2250 2251static time_t 2252time1(struct tm *const tmp, 2253 struct tm *(*funcp) (struct state const *, time_t const *, 2254 int_fast32_t, struct tm *), 2255 struct state const *sp, 2256 const int_fast32_t offset) 2257{ 2258 time_t t; 2259 int samei, otheri; 2260 int sameind, otherind; 2261 int i; 2262 int nseen; 2263 int save_errno; 2264 char seen[TZ_MAX_TYPES]; 2265 unsigned char types[TZ_MAX_TYPES]; 2266 bool okay; 2267 2268 if (tmp == NULL) { 2269 errno = EINVAL; 2270 return WRONG; 2271 } 2272 if (tmp->tm_isdst > 1) 2273 tmp->tm_isdst = 1; 2274 save_errno = errno; 2275 t = time2(tmp, funcp, sp, offset, &okay); 2276 if (okay) { 2277 errno = save_errno; 2278 return t; 2279 } 2280 if (tmp->tm_isdst < 0) 2281#ifdef PCTS 2282 /* 2283 ** POSIX Conformance Test Suite code courtesy Grant Sullivan. 2284 */ 2285 tmp->tm_isdst = 0; /* reset to std and try again */ 2286#else 2287 return t; 2288#endif /* !defined PCTS */ 2289 /* 2290 ** We're supposed to assume that somebody took a time of one type 2291 ** and did some math on it that yielded a "struct tm" that's bad. 2292 ** We try to divine the type they started from and adjust to the 2293 ** type they need. 2294 */ 2295 if (sp == NULL) { 2296 errno = EINVAL; 2297 return WRONG; 2298 } 2299 for (i = 0; i < sp->typecnt; ++i) 2300 seen[i] = false; 2301 nseen = 0; 2302 for (i = sp->timecnt - 1; i >= 0; --i) 2303 if (!seen[sp->types[i]]) { 2304 seen[sp->types[i]] = true; 2305 types[nseen++] = sp->types[i]; 2306 } 2307 for (sameind = 0; sameind < nseen; ++sameind) { 2308 samei = types[sameind]; 2309 if (sp->ttis[samei].tt_isdst != tmp->tm_isdst) 2310 continue; 2311 for (otherind = 0; otherind < nseen; ++otherind) { 2312 otheri = types[otherind]; 2313 if (sp->ttis[otheri].tt_isdst == tmp->tm_isdst) 2314 continue; 2315 tmp->tm_sec += (int)(sp->ttis[otheri].tt_gmtoff - 2316 sp->ttis[samei].tt_gmtoff); 2317 tmp->tm_isdst = !tmp->tm_isdst; 2318 t = time2(tmp, funcp, sp, offset, &okay); 2319 if (okay) { 2320 errno = save_errno; 2321 return t; 2322 } 2323 tmp->tm_sec -= (int)(sp->ttis[otheri].tt_gmtoff - 2324 sp->ttis[samei].tt_gmtoff); 2325 tmp->tm_isdst = !tmp->tm_isdst; 2326 } 2327 } 2328 errno = EOVERFLOW; 2329 return WRONG; 2330} 2331 2332static time_t 2333mktime_tzname(timezone_t sp, struct tm *tmp, bool setname) 2334{ 2335 if (sp) 2336 return time1(tmp, localsub, sp, setname); 2337 else { 2338 gmtcheck(); 2339 return time1(tmp, gmtsub, gmtptr, 0); 2340 } 2341} 2342 2343#if NETBSD_INSPIRED 2344 2345time_t 2346mktime_z(timezone_t sp, struct tm *const tmp) 2347{ 2348 return mktime_tzname(sp, tmp, false); 2349} 2350 2351#endif 2352 2353time_t 2354mktime(struct tm *tmp) 2355{ 2356 time_t t; 2357 2358 rwlock_wrlock(&__lcl_lock); 2359 tzset_unlocked(); 2360 t = mktime_tzname(__lclptr, tmp, true); 2361 rwlock_unlock(&__lcl_lock); 2362 return t; 2363} 2364 2365#ifdef STD_INSPIRED 2366 2367time_t 2368timelocal_z(const timezone_t sp, struct tm *const tmp) 2369{ 2370 if (tmp != NULL) 2371 tmp->tm_isdst = -1; /* in case it wasn't initialized */ 2372 return mktime_z(sp, tmp); 2373} 2374 2375time_t 2376timelocal(struct tm *tmp) 2377{ 2378 if (tmp != NULL) 2379 tmp->tm_isdst = -1; /* in case it wasn't initialized */ 2380 return mktime(tmp); 2381} 2382 2383time_t 2384timegm(struct tm *tmp) 2385{ 2386 2387 return timeoff(tmp, 0); 2388} 2389 2390time_t 2391timeoff(struct tm *tmp, long offset) 2392{ 2393 if (tmp) 2394 tmp->tm_isdst = 0; 2395 gmtcheck(); 2396 return time1(tmp, gmtsub, gmtptr, (int_fast32_t)offset); 2397} 2398 2399#endif /* defined STD_INSPIRED */ 2400 2401/* 2402** XXX--is the below the right way to conditionalize?? 2403*/ 2404 2405#ifdef STD_INSPIRED 2406 2407/* 2408** IEEE Std 1003.1 (POSIX) says that 536457599 2409** shall correspond to "Wed Dec 31 23:59:59 UTC 1986", which 2410** is not the case if we are accounting for leap seconds. 2411** So, we provide the following conversion routines for use 2412** when exchanging timestamps with POSIX conforming systems. 2413*/ 2414 2415static int_fast64_t 2416leapcorr(const timezone_t sp, time_t t) 2417{ 2418 struct lsinfo const * lp; 2419 int i; 2420 2421 i = sp->leapcnt; 2422 while (--i >= 0) { 2423 lp = &sp->lsis[i]; 2424 if (t >= lp->ls_trans) 2425 return lp->ls_corr; 2426 } 2427 return 0; 2428} 2429 2430NETBSD_INSPIRED_EXTERN time_t 2431time2posix_z(timezone_t sp, time_t t) 2432{ 2433 return (time_t)(t - leapcorr(sp, t)); 2434} 2435 2436time_t 2437time2posix(time_t t) 2438{ 2439 rwlock_wrlock(&__lcl_lock); 2440 if (!lcl_is_set) 2441 tzset_unlocked(); 2442 if (__lclptr) 2443 t = (time_t)(t - leapcorr(__lclptr, t)); 2444 rwlock_unlock(&__lcl_lock); 2445 return t; 2446} 2447 2448NETBSD_INSPIRED_EXTERN time_t 2449posix2time_z(timezone_t sp, time_t t) 2450{ 2451 time_t x; 2452 time_t y; 2453 2454 /* 2455 ** For a positive leap second hit, the result 2456 ** is not unique. For a negative leap second 2457 ** hit, the corresponding time doesn't exist, 2458 ** so we return an adjacent second. 2459 */ 2460 x = (time_t)(t + leapcorr(sp, t)); 2461 y = (time_t)(x - leapcorr(sp, x)); 2462 if (y < t) { 2463 do { 2464 x++; 2465 y = (time_t)(x - leapcorr(sp, x)); 2466 } while (y < t); 2467 x -= y != t; 2468 } else if (y > t) { 2469 do { 2470 --x; 2471 y = (time_t)(x - leapcorr(sp, x)); 2472 } while (y > t); 2473 x += y != t; 2474 } 2475 return x; 2476} 2477 2478time_t 2479posix2time(time_t t) 2480{ 2481 rwlock_wrlock(&__lcl_lock); 2482 if (!lcl_is_set) 2483 tzset_unlocked(); 2484 if (__lclptr) 2485 t = posix2time_z(__lclptr, t); 2486 rwlock_unlock(&__lcl_lock); 2487 return t; 2488} 2489 2490#endif /* defined STD_INSPIRED */ 2491