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