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