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