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