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 "private.h" 17 18 #include "tzdir.h" 19 #include "tzfile.h" 20 #include <fcntl.h> 21 22 #if HAVE_SYS_STAT_H 23 # include <sys/stat.h> 24 # ifndef S_ISREG 25 # define S_ISREG(mode) (((mode) & S_IFMT) == S_IFREG) /* Ancient UNIX. */ 26 # endif 27 #else 28 struct stat { char st_ctime, st_dev, st_ino; }; 29 # define dev_t char 30 # define ino_t char 31 # define fstat(fd, st) (memset(st, 0, sizeof *(st)), 0) 32 # define stat(name, st) fstat(0, st) 33 # define S_ISREG(mode) 1 34 #endif 35 36 #ifndef HAVE_STRUCT_STAT_ST_CTIM 37 # define HAVE_STRUCT_STAT_ST_CTIM 1 38 #endif 39 #if !defined st_ctim && defined __APPLE__ && defined __MACH__ 40 # define st_ctim st_ctimespec 41 #endif 42 43 #ifndef THREAD_SAFE 44 # define THREAD_SAFE 0 45 #endif 46 47 #ifndef THREAD_RWLOCK 48 # define THREAD_RWLOCK 0 49 #endif 50 51 #ifndef THREAD_TM_MULTI 52 # define THREAD_TM_MULTI 0 53 #endif 54 55 #ifndef USE_TIMEX_T 56 # define USE_TIMEX_T false 57 #endif 58 59 #if THREAD_SAFE 60 # include <pthread.h> 61 62 # ifndef THREAD_PREFER_SINGLE 63 # define THREAD_PREFER_SINGLE 0 64 # endif 65 # if THREAD_PREFER_SINGLE 66 # ifndef HAVE___ISTHREADED 67 # if defined __FreeBSD__ || defined __OpenBSD__ 68 # define HAVE___ISTHREADED 1 69 # else 70 # define HAVE___ISTHREADED 0 71 # endif 72 # endif 73 # if HAVE___ISTHREADED 74 extern int __isthreaded; 75 # else 76 # if !defined HAVE_SYS_SINGLE_THREADED_H && defined __has_include 77 # if __has_include(<sys/single_threaded.h>) 78 # define HAVE_SYS_SINGLE_THREADED_H 1 79 # else 80 # define HAVE_SYS_SINGLE_THREADED_H 0 81 # endif 82 # endif 83 # ifndef HAVE_SYS_SINGLE_THREADED_H 84 # if defined __GLIBC__ && 2 < __GLIBC__ + (32 <= __GLIBC_MINOR__) 85 # define HAVE_SYS_SINGLE_THREADED_H 1 86 # else 87 # define HAVE_SYS_SINGLE_THREADED_H 0 88 # endif 89 # endif 90 # if HAVE_SYS_SINGLE_THREADED_H 91 # include <sys/single_threaded.h> 92 # endif 93 # endif 94 # endif 95 #endif 96 97 #if !defined TM_GMTOFF || !USE_TIMEX_T 98 # if THREAD_SAFE 99 100 /* True if the current process might be multi-threaded, 101 false if it is definitely single-threaded. 102 If false, it will be false the next time it is called 103 unless the caller creates a thread in the meantime. 104 If true, it might become false the next time it is called 105 if all other threads exit in the meantime. */ 106 static bool 107 is_threaded(void) 108 { 109 # if THREAD_PREFER_SINGLE && HAVE___ISTHREADED 110 return !!__isthreaded; 111 # elif THREAD_PREFER_SINGLE && HAVE_SYS_SINGLE_THREADED_H 112 return !__libc_single_threaded; 113 # else 114 return true; 115 # endif 116 } 117 118 # if THREAD_RWLOCK 119 static pthread_rwlock_t locallock = PTHREAD_RWLOCK_INITIALIZER; 120 static int dolock(void) { return pthread_rwlock_rdlock(&locallock); } 121 static void dounlock(void) { pthread_rwlock_unlock(&locallock); } 122 # else 123 static pthread_mutex_t locallock = PTHREAD_MUTEX_INITIALIZER; 124 static int dolock(void) { return pthread_mutex_lock(&locallock); } 125 static void dounlock(void) { pthread_mutex_unlock(&locallock); } 126 # endif 127 128 /* Get a lock. Return 0 on success, a positive errno value on failure, 129 negative if known to be single-threaded so no lock is needed. */ 130 static int 131 lock(void) 132 { 133 if (!is_threaded()) 134 return -1; 135 return dolock(); 136 } 137 static void 138 unlock(bool threaded) 139 { 140 if (threaded) 141 dounlock(); 142 } 143 # else 144 static int lock(void) { return -1; } 145 static void unlock(ATTRIBUTE_MAYBE_UNUSED bool threaded) { } 146 # endif 147 #endif 148 149 #if THREAD_SAFE 150 typedef pthread_once_t once_t; 151 # define ONCE_INIT PTHREAD_ONCE_INIT 152 #else 153 typedef bool once_t; 154 # define ONCE_INIT false 155 #endif 156 157 static void 158 once(once_t *once_control, void init_routine(void)) 159 { 160 #if THREAD_SAFE 161 pthread_once(once_control, init_routine); 162 #else 163 if (!*once_control) { 164 *once_control = true; 165 init_routine(); 166 } 167 #endif 168 } 169 170 enum tm_multi { LOCALTIME_TM_MULTI, GMTIME_TM_MULTI, OFFTIME_TM_MULTI }; 171 172 #if THREAD_SAFE && THREAD_TM_MULTI 173 174 enum { N_TM_MULTI = OFFTIME_TM_MULTI + 1 }; 175 static pthread_key_t tm_multi_key; 176 static int tm_multi_key_err; 177 178 static void 179 tm_multi_key_init(void) 180 { 181 tm_multi_key_err = pthread_key_create(&tm_multi_key, free); 182 } 183 184 #endif 185 186 /* Unless intptr_t is missing, pacify gcc -Wcast-qual on char const * exprs. 187 Use this carefully, as the casts disable type checking. 188 This is a macro so that it can be used in static initializers. */ 189 #ifdef INTPTR_MAX 190 # define UNCONST(a) ((char *) (intptr_t) (a)) 191 #else 192 # define UNCONST(a) ((char *) (a)) 193 #endif 194 195 /* A signed type wider than int, so that we can add 1900 + tm_mon/12 to tm_year 196 without overflow. The static_assert checks that it is indeed wider 197 than int; if this fails on your platform please let us know. */ 198 #if INT_MAX < LONG_MAX 199 typedef long iinntt; 200 # define IINNTT_MIN LONG_MIN 201 # define IINNTT_MAX LONG_MAX 202 #elif INT_MAX < LLONG_MAX 203 typedef long long iinntt; 204 # define IINNTT_MIN LLONG_MIN 205 # define IINNTT_MAX LLONG_MAX 206 #else 207 typedef intmax_t iinntt; 208 # define IINNTT_MIN INTMAX_MIN 209 # define IINNTT_MAX INTMAX_MAX 210 #endif 211 static_assert(IINNTT_MIN < INT_MIN && INT_MAX < IINNTT_MAX); 212 213 #ifndef HAVE_STRUCT_TIMESPEC 214 # define HAVE_STRUCT_TIMESPEC 1 215 #endif 216 #if !HAVE_STRUCT_TIMESPEC 217 struct timespec { time_t tv_sec; long tv_nsec; }; 218 #endif 219 220 #if !defined CLOCK_MONOTONIC_COARSE && defined CLOCK_MONOTONIC 221 # define CLOCK_MONOTONIC_COARSE CLOCK_MONOTONIC 222 #endif 223 #ifndef CLOCK_MONOTONIC_COARSE 224 # undef clock_gettime 225 # define clock_gettime(id, t) ((t)->tv_sec = time(NULL), (t)->tv_nsec = 0, 0) 226 #endif 227 228 /* How many seconds to wait before checking the default TZif file again. 229 Negative means no checking. Default to 61 if DETECT_TZ_CHANGES 230 (as circa 2025 FreeBSD builds its localtime.c with -DDETECT_TZ_CHANGES), 231 and to -1 otherwise. */ 232 #ifndef TZ_CHANGE_INTERVAL 233 # ifdef DETECT_TZ_CHANGES 234 # define TZ_CHANGE_INTERVAL 61 235 # else 236 # define TZ_CHANGE_INTERVAL (-1) 237 # endif 238 #endif 239 static_assert(TZ_CHANGE_INTERVAL < 0 || HAVE_SYS_STAT_H); 240 241 /* The change detection interval. */ 242 #if TZ_CHANGE_INTERVAL < 0 || !defined __FreeBSD__ 243 enum { tz_change_interval = TZ_CHANGE_INTERVAL }; 244 #else 245 /* FreeBSD uses this private-but-extern var in its internal test suite. */ 246 int __tz_change_interval = TZ_CHANGE_INTERVAL; 247 # define tz_change_interval __tz_change_interval 248 #endif 249 250 /* The type of monotonic times. 251 This is the system time_t, even if USE_TIMEX_T #defines time_t below. */ 252 typedef time_t monotime_t; 253 254 /* On platforms where offtime or mktime might overflow, 255 strftime.c defines USE_TIMEX_T to be true and includes us. 256 This tells us to #define time_t to an internal type timex_t that is 257 wide enough so that strftime %s never suffers from integer overflow, 258 and to #define offtime (if TM_GMTOFF is defined) or mktime (otherwise) 259 to a static function that returns the redefined time_t. 260 It also tells us to define only data and code needed 261 to support the offtime or mktime variant. */ 262 #if USE_TIMEX_T 263 # undef TIME_T_MIN 264 # undef TIME_T_MAX 265 # undef time_t 266 # define time_t timex_t 267 # if MKTIME_FITS_IN(LONG_MIN, LONG_MAX) 268 typedef long timex_t; 269 # define TIME_T_MIN LONG_MIN 270 # define TIME_T_MAX LONG_MAX 271 # elif MKTIME_FITS_IN(LLONG_MIN, LLONG_MAX) 272 typedef long long timex_t; 273 # define TIME_T_MIN LLONG_MIN 274 # define TIME_T_MAX LLONG_MAX 275 # else 276 typedef intmax_t timex_t; 277 # define TIME_T_MIN INTMAX_MIN 278 # define TIME_T_MAX INTMAX_MAX 279 # endif 280 281 # ifdef TM_GMTOFF 282 # undef timeoff 283 # define timeoff timex_timeoff 284 # undef EXTERN_TIMEOFF 285 # else 286 # undef mktime 287 # define mktime timex_mktime 288 # endif 289 #endif 290 291 /* Placeholders for platforms lacking openat. */ 292 #ifndef AT_FDCWD 293 # define AT_FDCWD (-1) /* any negative value will do */ 294 static int openat(int dd, char const *path, int oflag) { unreachable (); } 295 #endif 296 297 /* Port to platforms that lack some O_* flags. Unless otherwise 298 specified, the flags are standardized by POSIX. */ 299 300 #ifndef O_BINARY 301 # define O_BINARY 0 /* MS-Windows */ 302 #endif 303 #ifndef O_CLOEXEC 304 # define O_CLOEXEC 0 305 #endif 306 #ifndef O_CLOFORK 307 # define O_CLOFORK 0 308 #endif 309 #ifndef O_DIRECTORY 310 # define O_DIRECTORY 0 311 #endif 312 #ifndef O_IGNORE_CTTY 313 # define O_IGNORE_CTTY 0 /* GNU/Hurd */ 314 #endif 315 #ifndef O_NOCTTY 316 # define O_NOCTTY 0 317 #endif 318 #ifndef O_PATH 319 # define O_PATH 0 320 #endif 321 #ifndef O_REGULAR 322 # define O_REGULAR 0 323 #endif 324 #ifndef O_RESOLVE_BENEATH 325 # define O_RESOLVE_BENEATH 0 326 #endif 327 #ifndef O_SEARCH 328 # define O_SEARCH 0 329 #endif 330 331 #if !HAVE_ISSETUGID 332 333 # if !defined HAVE_SYS_AUXV_H && defined __has_include 334 # if __has_include(<sys/auxv.h>) 335 # define HAVE_SYS_AUXV_H 1 336 # endif 337 # endif 338 # ifndef HAVE_SYS_AUXV_H 339 # if defined __GLIBC__ && 2 < __GLIBC__ + (19 <= __GLIBC_MINOR__) 340 # define HAVE_SYS_AUXV_H 1 341 # else 342 # define HAVE_SYS_AUXV_H 0 343 # endif 344 # endif 345 # if HAVE_SYS_AUXV_H 346 # include <sys/auxv.h> 347 # endif 348 349 /* Return 1 if the process is privileged, 0 otherwise. */ 350 static int 351 issetugid(void) 352 { 353 # if HAVE_SYS_AUXV_H && defined AT_SECURE 354 unsigned long val; 355 errno = 0; 356 val = getauxval(AT_SECURE); 357 if (val || errno != ENOENT) 358 return !!val; 359 # endif 360 # if HAVE_GETRESUID 361 { 362 uid_t ruid, euid, suid; 363 gid_t rgid, egid, sgid; 364 if (0 <= getresuid (&ruid, &euid, &suid)) { 365 if ((ruid ^ euid) | (ruid ^ suid)) 366 return 1; 367 if (0 <= getresgid (&rgid, &egid, &sgid)) 368 return !!((rgid ^ egid) | (rgid ^ sgid)); 369 } 370 } 371 # endif 372 # if HAVE_GETEUID 373 return geteuid() != getuid() || getegid() != getgid(); 374 # else 375 return 0; 376 # endif 377 } 378 #endif 379 380 #ifndef WILDABBR 381 /* 382 ** Someone might make incorrect use of a time zone abbreviation: 383 ** 1. They might reference tzname[0] before calling tzset (explicitly 384 ** or implicitly). 385 ** 2. They might reference tzname[1] before calling tzset (explicitly 386 ** or implicitly). 387 ** 3. They might reference tzname[1] after setting to a time zone 388 ** in which Daylight Saving Time is never observed. 389 ** 4. They might reference tzname[0] after setting to a time zone 390 ** in which Standard Time is never observed. 391 ** 5. They might reference tm.TM_ZONE after calling offtime. 392 ** What's best to do in the above cases is open to debate; 393 ** for now, we just set things up so that in any of the five cases 394 ** WILDABBR is used. Another possibility: initialize tzname[0] to the 395 ** string "tzname[0] used before set", and similarly for the other cases. 396 ** And another: initialize tzname[0] to "ERA", with an explanation in the 397 ** manual page of what this "time zone abbreviation" means (doing this so 398 ** that tzname[0] has the "normal" length of three characters). 399 */ 400 # define WILDABBR " " 401 #endif /* !defined WILDABBR */ 402 403 static const char wildabbr[] = WILDABBR; 404 405 static char const etc_utc[] = "Etc/UTC"; 406 407 #if !USE_TIMEX_T || defined TM_ZONE || !defined TM_GMTOFF 408 static char const *utc = etc_utc + sizeof "Etc/" - 1; 409 #endif 410 411 /* 412 ** The DST rules to use if TZ has no rules. 413 ** Default to US rules as of 2017-05-07. 414 ** POSIX does not specify the default DST rules; 415 ** for historical reasons, US rules are a common default. 416 */ 417 #ifndef TZDEFRULESTRING 418 # define TZDEFRULESTRING ",M3.2.0,M11.1.0" 419 #endif 420 421 /* If compiled with -DOPENAT_TZDIR, then when accessing a relative 422 name like "America/Los_Angeles", first open TZDIR (default 423 "/usr/share/zoneinfo") as a directory and then use the result in 424 openat with "America/Los_Angeles", rather than the traditional 425 approach of opening "/usr/share/zoneinfo/America/Los_Angeles". 426 Although the OPENAT_TZDIR approach is less efficient, suffers from 427 spurious EMFILE and ENFILE failures, and is no more secure in practice, 428 it is how bleeding edge FreeBSD did things from August 2025 429 through at least September 2025. */ 430 #ifndef OPENAT_TZDIR 431 # define OPENAT_TZDIR 0 432 #endif 433 434 /* If compiled with -DSUPPRESS_TZDIR, do not prepend TZDIR to relative TZ. 435 This is intended for specialized applications only, due to its 436 security implications. */ 437 #ifndef SUPPRESS_TZDIR 438 # define SUPPRESS_TZDIR 0 439 #endif 440 441 /* Limit to time zone abbreviation length in proleptic TZ strings. 442 This is distinct from TZ_MAX_CHARS, which limits TZif file contents. 443 It defaults to 254, not 255, so that desigidx_type can be an unsigned char. 444 unsigned char suffices for TZif files, so the only reason to increase 445 TZNAME_MAXIMUM is to support TZ strings specifying abbreviations 446 longer than 254 bytes. There is little reason to do that, though, 447 as strings that long are hardly "abbreviations". */ 448 #ifndef TZNAME_MAXIMUM 449 # define TZNAME_MAXIMUM 254 450 #endif 451 452 #if TZNAME_MAXIMUM < UCHAR_MAX 453 typedef unsigned char desigidx_type; 454 #elif TZNAME_MAXIMUM < INT_MAX 455 typedef int desigidx_type; 456 #elif TZNAME_MAXIMUM < PTRDIFF_MAX 457 typedef ptrdiff_t desigidx_type; 458 #else 459 # error "TZNAME_MAXIMUM too large" 460 #endif 461 462 /* A type that can represent any 32-bit two's complement integer, 463 i.e., any integer in the range -2**31 .. 2**31 - 1. 464 Ordinarily this is int_fast32_t, but on non-C23 hosts 465 that are not two's complement it is int_fast64_t. */ 466 #if INT_FAST32_MIN < -TWO_31_MINUS_1 467 typedef int_fast32_t int_fast32_2s; 468 #else 469 typedef int_fast64_t int_fast32_2s; 470 #endif 471 472 struct ttinfo { /* time type information */ 473 int_least32_t tt_utoff; /* UT offset in seconds; in the range 474 -2**31 + 1 .. 2**31 - 1 */ 475 desigidx_type tt_desigidx; /* abbreviation list index */ 476 bool tt_isdst; /* used to set tm_isdst */ 477 bool tt_ttisstd; /* transition is std time */ 478 bool tt_ttisut; /* transition is UT */ 479 }; 480 481 struct lsinfo { /* leap second information */ 482 time_t ls_trans; /* transition time (positive) */ 483 int_fast32_2s ls_corr; /* correction to apply */ 484 }; 485 486 /* This abbreviation means local time is unspecified. */ 487 static char const UNSPEC[] = "-00"; 488 489 /* How many extra bytes are needed at the end of struct state's chars array. 490 This needs to be at least 1 for null termination in case the input 491 data isn't properly terminated, and it also needs to be big enough 492 for ttunspecified to work without crashing. */ 493 enum { CHARS_EXTRA = max(sizeof UNSPEC, 2) - 1 }; 494 495 /* A representation of the contents of a TZif file. Ideally this 496 would have no size limits; the following sizes should suffice for 497 practical use. This struct should not be too large, as instances 498 are put on the stack and stacks are relatively small on some platforms. 499 See tzfile.h for more about the sizes. */ 500 struct state { 501 #if TZ_RUNTIME_LEAPS 502 int leapcnt; 503 #endif 504 int timecnt; 505 int typecnt; 506 int charcnt; 507 bool goback; 508 bool goahead; 509 time_t ats[TZ_MAX_TIMES]; 510 unsigned char types[TZ_MAX_TIMES]; 511 struct ttinfo ttis[TZ_MAX_TYPES]; 512 char chars[max(max(TZ_MAX_CHARS + CHARS_EXTRA, sizeof "UTC"), 513 2 * (TZNAME_MAXIMUM + 1))]; 514 #if TZ_RUNTIME_LEAPS 515 struct lsinfo lsis[TZ_MAX_LEAPS]; 516 #endif 517 }; 518 519 static int 520 leapcount(ATTRIBUTE_MAYBE_UNUSED struct state const *sp) 521 { 522 #if TZ_RUNTIME_LEAPS 523 return sp->leapcnt; 524 #else 525 return 0; 526 #endif 527 } 528 static void 529 set_leapcount(ATTRIBUTE_MAYBE_UNUSED struct state *sp, 530 ATTRIBUTE_MAYBE_UNUSED int leapcnt) 531 { 532 #if TZ_RUNTIME_LEAPS 533 sp->leapcnt = leapcnt; 534 #endif 535 } 536 static struct lsinfo 537 lsinfo(ATTRIBUTE_MAYBE_UNUSED struct state const *sp, 538 ATTRIBUTE_MAYBE_UNUSED int i) 539 { 540 #if TZ_RUNTIME_LEAPS 541 return sp->lsis[i]; 542 #else 543 unreachable(); 544 #endif 545 } 546 static void 547 set_lsinfo(ATTRIBUTE_MAYBE_UNUSED struct state *sp, 548 ATTRIBUTE_MAYBE_UNUSED int i, 549 ATTRIBUTE_MAYBE_UNUSED struct lsinfo lsinfo) 550 { 551 #if TZ_RUNTIME_LEAPS 552 sp->lsis[i] = lsinfo; 553 #endif 554 } 555 556 enum r_type { 557 JULIAN_DAY, /* Jn = Julian day */ 558 DAY_OF_YEAR, /* n = day of year */ 559 MONTH_NTH_DAY_OF_WEEK /* Mm.n.d = month, week, day of week */ 560 }; 561 562 struct rule { 563 enum r_type r_type; /* type of rule */ 564 int r_day; /* day number of rule */ 565 int r_week; /* week number of rule */ 566 int r_mon; /* month number of rule */ 567 int_fast32_t r_time; /* transition time of rule */ 568 }; 569 570 static struct tm *gmtsub(struct state const *, time_t const *, int_fast32_t, 571 struct tm *); 572 static bool increment_overflow(int *, int); 573 static bool increment_overflow_time(time_t *, int_fast32_2s); 574 static int_fast32_2s leapcorr(struct state const *, time_t); 575 static struct tm *timesub(time_t const *, int_fast32_t, struct state const *, 576 struct tm *); 577 static bool tzparse(char const *, struct state *, struct state const *); 578 579 #ifndef ALL_STATE 580 # define ALL_STATE 0 581 #endif 582 583 #if ALL_STATE 584 static struct state * lclptr; 585 static struct state * gmtptr; 586 #else 587 static struct state lclmem; 588 static struct state gmtmem; 589 static struct state *const lclptr = &lclmem; 590 static struct state *const gmtptr = &gmtmem; 591 #endif /* State Farm */ 592 593 /* Maximum number of bytes in an efficiently-handled TZ string. 594 Longer strings work, albeit less efficiently. */ 595 #ifndef TZ_STRLEN_MAX 596 # define TZ_STRLEN_MAX 255 597 #endif /* !defined TZ_STRLEN_MAX */ 598 599 #if !USE_TIMEX_T || !defined TM_GMTOFF 600 static char lcl_TZname[TZ_STRLEN_MAX + 1]; 601 static int lcl_is_set; 602 #endif 603 604 /* 605 ** Section 4.12.3 of X3.159-1989 requires that 606 ** Except for the strftime function, these functions [asctime, 607 ** ctime, gmtime, localtime] return values in one of two static 608 ** objects: a broken-down time structure and an array of char. 609 ** Thanks to Paul Eggert for noting this. 610 ** 611 ** Although this requirement was removed in C99 it is still present in POSIX. 612 ** Follow the requirement if SUPPORT_C89, even though this is more likely to 613 ** trigger latent bugs in programs. 614 */ 615 616 #if !USE_TIMEX_T 617 618 # if SUPPORT_C89 619 static struct tm tm; 620 # endif 621 622 # if 2 <= HAVE_TZNAME + TZ_TIME_T 623 char *tzname[2] = { UNCONST(wildabbr), UNCONST(wildabbr) }; 624 # endif 625 # if 2 <= USG_COMPAT + TZ_TIME_T 626 long timezone; 627 int daylight; 628 # endif 629 # if 2 <= ALTZONE + TZ_TIME_T 630 long altzone; 631 # endif 632 633 #endif 634 635 /* Initialize *S to a value based on UTOFF, ISDST, and DESIGIDX. */ 636 static void 637 init_ttinfo(struct ttinfo *s, int_fast32_t utoff, bool isdst, 638 desigidx_type desigidx) 639 { 640 s->tt_utoff = utoff; 641 s->tt_isdst = isdst; 642 s->tt_desigidx = desigidx; 643 s->tt_ttisstd = false; 644 s->tt_ttisut = false; 645 } 646 647 /* Return true if SP's time type I does not specify local time. */ 648 static bool 649 ttunspecified(struct state const *sp, int i) 650 { 651 char const *abbr = &sp->chars[sp->ttis[i].tt_desigidx]; 652 /* memcmp is likely faster than strcmp, and is safe due to CHARS_EXTRA. */ 653 return memcmp(abbr, UNSPEC, sizeof UNSPEC) == 0; 654 } 655 656 static int_fast32_2s 657 detzcode(const char *const codep) 658 { 659 register int i; 660 int_fast32_2s 661 maxval = TWO_31_MINUS_1, 662 minval = -1 - maxval, 663 result; 664 665 result = codep[0] & 0x7f; 666 for (i = 1; i < 4; ++i) 667 result = (result << 8) | (codep[i] & 0xff); 668 669 if (codep[0] & 0x80) { 670 /* Do two's-complement negation even on non-two's-complement machines. 671 This cannot overflow, as int_fast32_2s is wide enough. */ 672 result += minval; 673 } 674 return result; 675 } 676 677 static int_fast64_t 678 detzcode64(const char *const codep) 679 { 680 register int_fast64_t result; 681 register int i; 682 int_fast64_t one = 1; 683 int_fast64_t halfmaxval = one << (64 - 2); 684 int_fast64_t maxval = halfmaxval - 1 + halfmaxval; 685 int_fast64_t minval = -TWOS_COMPLEMENT(int_fast64_t) - maxval; 686 687 result = codep[0] & 0x7f; 688 for (i = 1; i < 8; ++i) 689 result = (result << 8) | (codep[i] & 0xff); 690 691 if (codep[0] & 0x80) { 692 /* Do two's-complement negation even on non-two's-complement machines. 693 If the result would be minval - 1, return minval. */ 694 result -= !TWOS_COMPLEMENT(int_fast64_t) && result != 0; 695 result += minval; 696 } 697 return result; 698 } 699 700 #if !USE_TIMEX_T || !defined TM_GMTOFF 701 702 static void 703 update_tzname_etc(struct state const *sp, struct ttinfo const *ttisp) 704 { 705 # if HAVE_TZNAME 706 tzname[ttisp->tt_isdst] = UNCONST(&sp->chars[ttisp->tt_desigidx]); 707 # endif 708 # if USG_COMPAT 709 if (!ttisp->tt_isdst) 710 timezone = - ttisp->tt_utoff; 711 # endif 712 # if ALTZONE 713 if (ttisp->tt_isdst) 714 altzone = - ttisp->tt_utoff; 715 # endif 716 } 717 718 /* If STDDST_MASK indicates that SP's TYPE provides useful info, 719 update tzname, timezone, and/or altzone and return STDDST_MASK, 720 diminished by the provided info if it is a specified local time. 721 Otherwise, return STDDST_MASK. See settzname for STDDST_MASK. */ 722 static int 723 may_update_tzname_etc(int stddst_mask, struct state *sp, int type) 724 { 725 struct ttinfo *ttisp = &sp->ttis[type]; 726 int this_bit = 1 << ttisp->tt_isdst; 727 if (stddst_mask & this_bit) { 728 update_tzname_etc(sp, ttisp); 729 if (!ttunspecified(sp, type)) 730 return stddst_mask & ~this_bit; 731 } 732 return stddst_mask; 733 } 734 735 static void 736 settzname(void) 737 { 738 register struct state * const sp = lclptr; 739 register int i; 740 741 /* If STDDST_MASK & 1 we need info about a standard time. 742 If STDDST_MASK & 2 we need info about a daylight saving time. 743 When STDDST_MASK becomes zero we can stop looking. */ 744 int stddst_mask = 0; 745 746 # if HAVE_TZNAME 747 tzname[0] = tzname[1] = UNCONST(sp ? wildabbr : utc); 748 stddst_mask = 3; 749 # endif 750 # if USG_COMPAT 751 timezone = 0; 752 stddst_mask = 3; 753 # endif 754 # if ALTZONE 755 altzone = 0; 756 stddst_mask |= 2; 757 # endif 758 /* 759 ** And to get the latest time zone abbreviations into tzname. . . 760 */ 761 if (sp) { 762 for (i = sp->timecnt - 1; stddst_mask && 0 <= i; i--) 763 stddst_mask = may_update_tzname_etc(stddst_mask, sp, sp->types[i]); 764 for (i = sp->typecnt - 1; stddst_mask && 0 <= i; i--) 765 stddst_mask = may_update_tzname_etc(stddst_mask, sp, i); 766 } 767 # if USG_COMPAT 768 daylight = stddst_mask >> 1 ^ 1; 769 # endif 770 } 771 772 /* Replace bogus characters in time zone abbreviations. 773 Return 0 on success, an errno value if a time zone abbreviation is 774 too long. */ 775 static int 776 scrub_abbrs(struct state *sp) 777 { 778 int i; 779 780 /* Reject overlong abbreviations. */ 781 for (i = 0; i < sp->charcnt - (TZNAME_MAXIMUM + 1); ) { 782 int len = strnlen(&sp->chars[i], TZNAME_MAXIMUM + 1); 783 if (TZNAME_MAXIMUM < len) 784 return EOVERFLOW; 785 i += len + 1; 786 } 787 788 /* Replace bogus characters. */ 789 for (i = 0; i < sp->charcnt; ++i) 790 switch (sp->chars[i]) { 791 case '\0': 792 case '+': case '-': case '.': 793 case '0': case '1': case '2': case '3': case '4': 794 case '5': case '6': case '7': case '8': case '9': 795 case ':': 796 case 'A': case 'B': case 'C': case 'D': case 'E': case 'F': case 'G': 797 case 'H': case 'I': case 'J': case 'K': case 'L': case 'M': case 'N': 798 case 'O': case 'P': case 'Q': case 'R': case 'S': case 'T': case 'U': 799 case 'V': case 'W': case 'X': case 'Y': case 'Z': 800 case 'a': case 'b': case 'c': case 'd': case 'e': case 'f': case 'g': 801 case 'h': case 'i': case 'j': case 'k': case 'l': case 'm': case 'n': 802 case 'o': case 'p': case 'q': case 'r': case 's': case 't': case 'u': 803 case 'v': case 'w': case 'x': case 'y': case 'z': 804 break; 805 806 default: 807 sp->chars[i] = '_'; 808 break; 809 } 810 811 return 0; 812 } 813 814 #endif 815 816 /* Return true if the TZif file with descriptor FD changed, 817 or may have changed, since the last time we were called. 818 Return false if it did not change. 819 If *ST is valid it is the file's current status; 820 otherwise, update *ST to the status if possible. */ 821 static bool 822 tzfile_changed(int fd, struct stat *st) 823 { 824 /* If old_ctim.tv_sec, these variables hold the corresponding part 825 of the file's metadata the last time this function was called. */ 826 static struct timespec old_ctim; 827 static dev_t old_dev; 828 static ino_t old_ino; 829 830 if (!st->st_ctime && fstat(fd, st) < 0) { 831 /* We do not know the file's state, so reset. */ 832 old_ctim.tv_sec = 0; 833 return true; 834 } else { 835 /* Use the change time, as it changes more reliably; mod time can 836 be set back with futimens etc. Use subsecond timestamp 837 resolution if available, as this can help distinguish files on 838 non-POSIX platforms where st_dev and st_ino are unreliable. */ 839 struct timespec ctim; 840 #if HAVE_STRUCT_STAT_ST_CTIM 841 ctim = st->st_ctim; 842 #else 843 ctim.tv_sec = st->st_ctime; 844 ctim.tv_nsec = 0; 845 #endif 846 847 if ((ctim.tv_sec ^ old_ctim.tv_sec) | (ctim.tv_nsec ^ old_ctim.tv_nsec) 848 | (st->st_dev ^ old_dev) | (st->st_ino ^ old_ino)) { 849 old_ctim = ctim; 850 old_dev = st->st_dev; 851 old_ino = st->st_ino; 852 return true; 853 } 854 855 return false; 856 } 857 } 858 859 /* Input buffer for data read from a compiled tz file. */ 860 union input_buffer { 861 /* The first part of the buffer, interpreted as a header. */ 862 struct tzhead tzhead; 863 864 /* The entire buffer. Ideally this would have no size limits; 865 the following should suffice for practical use. */ 866 char buf[2 * sizeof(struct tzhead) + 2 * sizeof(struct state) 867 + 4 * TZ_MAX_TIMES]; 868 }; 869 870 /* TZDIR with a trailing '/'. It is null-terminated if OPENAT_TZDIR. */ 871 #if !OPENAT_TZDIR 872 ATTRIBUTE_NONSTRING 873 #endif 874 static char const tzdirslash[sizeof TZDIR + OPENAT_TZDIR] = TZDIR "/"; 875 enum { tzdirslashlen = sizeof TZDIR }; 876 #ifdef PATH_MAX 877 static_assert(tzdirslashlen <= PATH_MAX); /* Sanity check; assumed below. */ 878 #endif 879 880 /* Local storage needed for 'tzloadbody'. */ 881 union local_storage { 882 /* The results of analyzing the file's contents after it is opened. */ 883 struct file_analysis { 884 /* The input buffer. */ 885 union input_buffer u; 886 887 /* A temporary state used for parsing a TZ string in the file. */ 888 struct state st; 889 } u; 890 891 #if defined PATH_MAX && !OPENAT_TZDIR && !SUPPRESS_TZDIR 892 /* The name of the file to be opened. */ 893 char fullname[PATH_MAX]; 894 #endif 895 }; 896 897 /* These tzload flags can be ORed together, and fit into 'char'. */ 898 enum { TZLOAD_FROMENV = 1 }; /* The TZ string came from the environment. */ 899 enum { TZLOAD_TZSTRING = 2 }; /* Read any newline-surrounded TZ string. */ 900 enum { TZLOAD_TZDIR_SUB = 4 }; /* TZ should be a file under TZDIR. */ 901 902 /* Load tz data from the file named NAME into *SP. Respect TZLOADFLAGS. 903 Use **LSPP for temporary storage. Return 0 on 904 success, an errno value on failure. */ 905 static int 906 tzloadbody(char const *name, struct state *sp, char tzloadflags, 907 union local_storage **lspp) 908 { 909 register int i; 910 register int fid; 911 register int stored; 912 register ssize_t nread; 913 char const *relname; 914 union local_storage *lsp = *lspp; 915 union input_buffer *up; 916 register int tzheadsize = sizeof(struct tzhead); 917 int dd = AT_FDCWD; 918 int oflags = (O_RDONLY | O_BINARY | O_CLOEXEC | O_CLOFORK 919 | O_IGNORE_CTTY | O_NOCTTY | O_REGULAR); 920 int err; 921 struct stat st; 922 st.st_ctime = 0; 923 924 sp->goback = sp->goahead = false; 925 926 if (! name) { 927 name = TZDEFAULT; 928 if (! name) 929 return EINVAL; 930 #ifdef __FreeBSD__ 931 tzloadflags &= ~TZLOAD_FROMENV; 932 #endif /* __FreeBSD__ */ 933 } 934 935 if (name[0] == ':') 936 ++name; 937 938 relname = name; 939 940 /* If the program is privileged, NAME is TZDEFAULT or 941 subsidiary to TZDIR. Also, NAME is not a device. */ 942 if (name[0] == '/' && strcmp(name, TZDEFAULT) != 0) { 943 if (!SUPPRESS_TZDIR 944 && strncmp(relname, tzdirslash, tzdirslashlen) == 0) 945 for (relname += tzdirslashlen; *relname == '/'; relname++) 946 continue; 947 else if (issetugid()) 948 return ENOTCAPABLE; 949 else if (!O_REGULAR) { 950 /* Check for devices, as their mere opening could have 951 unwanted side effects. Though racy, there is no 952 portable way to fix the races. This check is needed 953 only for files not otherwise known to be non-devices. */ 954 if (stat(name, &st) < 0) 955 return errno; 956 if (!S_ISREG(st.st_mode)) 957 return EINVAL; 958 } 959 } 960 961 if (relname[0] != '/') { 962 if (!OPENAT_TZDIR || !O_RESOLVE_BENEATH) { 963 /* Fail if a relative name contains a non-terminal ".." component, 964 as such a name could read a non-directory outside TZDIR 965 when AT_FDCWD and O_RESOLVE_BENEATH are not available. */ 966 char const *component; 967 for (component = relname; component[0]; component++) 968 if (component[0] == '.' && component[1] == '.' 969 && component[2] == '/' 970 && (component == relname || component[-1] == '/')) 971 return ENOTCAPABLE; 972 } 973 974 if (OPENAT_TZDIR && !SUPPRESS_TZDIR) { 975 /* Prefer O_SEARCH or O_PATH if available; 976 O_RDONLY should be OK too, as TZDIR is invariably readable. 977 O_DIRECTORY should be redundant but might help 978 on old platforms that mishandle trailing '/'. */ 979 dd = open(tzdirslash, 980 ((O_SEARCH ? O_SEARCH : O_PATH ? O_PATH : O_RDONLY) 981 | O_BINARY | O_CLOEXEC | O_CLOFORK | O_DIRECTORY)); 982 if (dd < 0) 983 return errno; 984 #ifdef __FreeBSD__ 985 if (issetugid()) 986 #endif /* __FreeBSD__ */ 987 oflags |= O_RESOLVE_BENEATH; 988 } 989 } 990 991 if (!OPENAT_TZDIR && !SUPPRESS_TZDIR && name[0] != '/') { 992 char *cp; 993 size_t fullnamesize; 994 #ifdef PATH_MAX 995 size_t namesizemax = PATH_MAX - tzdirslashlen; 996 size_t namelen = strnlen (name, namesizemax); 997 if (namesizemax <= namelen) 998 return ENAMETOOLONG; 999 #else 1000 size_t namelen = strlen (name); 1001 #endif 1002 fullnamesize = tzdirslashlen + namelen + 1; 1003 1004 /* Create a string "TZDIR/NAME". Using sprintf here 1005 would pull in stdio (and would fail if the 1006 resulting string length exceeded INT_MAX!). */ 1007 if (ALL_STATE || sizeof *lsp < fullnamesize) { 1008 lsp = malloc(max(sizeof *lsp, fullnamesize)); 1009 if (!lsp) 1010 return HAVE_MALLOC_ERRNO ? errno : ENOMEM; 1011 *lspp = lsp; 1012 } 1013 cp = mempcpy(lsp, tzdirslash, tzdirslashlen); 1014 cp = mempcpy(cp, name, namelen); 1015 *cp = '\0'; 1016 #if defined PATH_MAX && !OPENAT_TZDIR && !SUPPRESS_TZDIR 1017 name = lsp->fullname; 1018 #else 1019 name = (char *) lsp; 1020 #endif 1021 } 1022 1023 fid = OPENAT_TZDIR ? openat(dd, relname, oflags) : open(name, oflags); 1024 err = errno; 1025 if (0 <= dd) 1026 close(dd); 1027 if (fid < 0) 1028 return err; 1029 1030 /* If detecting changes to the the primary TZif file's state and 1031 the file's status is unchanged, save time by returning now. 1032 Otherwise read the file's contents. Close the file either way. */ 1033 if (0 <= tz_change_interval && (tzloadflags & TZLOAD_FROMENV) 1034 && !tzfile_changed(fid, &st)) 1035 err = -1; 1036 else { 1037 if (ALL_STATE && !lsp) { 1038 lsp = malloc(sizeof *lsp); 1039 if (!lsp) 1040 return HAVE_MALLOC_ERRNO ? errno : ENOMEM; 1041 *lspp = lsp; 1042 } 1043 up = &lsp->u.u; 1044 nread = read(fid, up->buf, sizeof up->buf); 1045 err = tzheadsize <= nread ? 0 : nread < 0 ? errno : EINVAL; 1046 } 1047 close(fid); 1048 if (err) 1049 return err < 0 ? 0 : err; 1050 1051 for (stored = 4; stored <= 8; stored *= 2) { 1052 char version = up->tzhead.tzh_version[0]; 1053 bool skip_datablock = stored == 4 && version; 1054 int_fast32_t datablock_size; 1055 int_fast32_2s 1056 ttisstdcnt = detzcode(up->tzhead.tzh_ttisstdcnt), 1057 ttisutcnt = detzcode(up->tzhead.tzh_ttisutcnt), 1058 leapcnt = detzcode(up->tzhead.tzh_leapcnt), 1059 timecnt = detzcode(up->tzhead.tzh_timecnt), 1060 typecnt = detzcode(up->tzhead.tzh_typecnt), 1061 charcnt = detzcode(up->tzhead.tzh_charcnt); 1062 char const *p = up->buf + tzheadsize; 1063 /* Although tzfile(5) currently requires typecnt to be nonzero, 1064 support future formats that may allow zero typecnt 1065 in files that have a TZ string and no transitions. */ 1066 if (! (0 <= leapcnt 1067 && leapcnt <= (TZ_RUNTIME_LEAPS ? TZ_MAX_LEAPS : 0) 1068 && 0 <= typecnt && typecnt <= TZ_MAX_TYPES 1069 && 0 <= timecnt && timecnt <= TZ_MAX_TIMES 1070 && 0 <= charcnt && charcnt <= TZ_MAX_CHARS 1071 && 0 <= ttisstdcnt && ttisstdcnt <= TZ_MAX_TYPES 1072 && 0 <= ttisutcnt && ttisutcnt <= TZ_MAX_TYPES)) 1073 return EINVAL; 1074 datablock_size 1075 = (timecnt * stored /* ats */ 1076 + timecnt /* types */ 1077 + typecnt * 6 /* ttinfos */ 1078 + charcnt /* chars */ 1079 + leapcnt * (stored + 4) /* lsinfos */ 1080 + ttisstdcnt /* ttisstds */ 1081 + ttisutcnt); /* ttisuts */ 1082 if (nread < tzheadsize + datablock_size) 1083 return EINVAL; 1084 if (skip_datablock) 1085 p += datablock_size; 1086 else if (! ((ttisstdcnt == typecnt || ttisstdcnt == 0) 1087 && (ttisutcnt == typecnt || ttisutcnt == 0))) 1088 return EINVAL; 1089 else { 1090 int_fast64_t prevtr = -1; 1091 int_fast32_2s prevcorr; 1092 set_leapcount(sp, leapcnt); 1093 sp->timecnt = timecnt; 1094 sp->typecnt = typecnt; 1095 sp->charcnt = charcnt; 1096 1097 /* Read transitions, discarding those out of time_t range. 1098 But pretend the last transition before TIME_T_MIN 1099 occurred at TIME_T_MIN. */ 1100 timecnt = 0; 1101 for (i = 0; i < sp->timecnt; ++i) { 1102 int_fast64_t at 1103 = stored == 4 ? detzcode(p) : detzcode64(p); 1104 sp->types[i] = at <= TIME_T_MAX; 1105 if (sp->types[i]) { 1106 time_t attime 1107 = ((TYPE_SIGNED(time_t) ? at < TIME_T_MIN : at < 0) 1108 ? TIME_T_MIN : at); 1109 if (timecnt && attime <= sp->ats[timecnt - 1]) { 1110 if (attime < sp->ats[timecnt - 1]) 1111 return EINVAL; 1112 sp->types[i - 1] = 0; 1113 timecnt--; 1114 } 1115 sp->ats[timecnt++] = attime; 1116 } 1117 p += stored; 1118 } 1119 1120 timecnt = 0; 1121 for (i = 0; i < sp->timecnt; ++i) { 1122 unsigned char typ = *p++; 1123 if (sp->typecnt <= typ) 1124 return EINVAL; 1125 if (sp->types[i]) 1126 sp->types[timecnt++] = typ; 1127 } 1128 sp->timecnt = timecnt; 1129 for (i = 0; i < sp->typecnt; ++i) { 1130 register struct ttinfo * ttisp; 1131 unsigned char isdst, desigidx; 1132 int_fast32_2s utoff = detzcode(p); 1133 1134 /* Reject a UT offset equal to -2**31, as it might 1135 cause trouble both in this file and in callers. 1136 Also, it violates RFC 9636 section 3.2. */ 1137 if (utoff < -TWO_31_MINUS_1) 1138 return EINVAL; 1139 1140 ttisp = &sp->ttis[i]; 1141 ttisp->tt_utoff = utoff; 1142 p += 4; 1143 isdst = *p++; 1144 if (! (isdst < 2)) 1145 return EINVAL; 1146 ttisp->tt_isdst = isdst; 1147 desigidx = *p++; 1148 if (! (desigidx < sp->charcnt)) 1149 return EINVAL; 1150 ttisp->tt_desigidx = desigidx; 1151 } 1152 for (i = 0; i < sp->charcnt; ++i) 1153 sp->chars[i] = *p++; 1154 /* Ensure '\0'-terminated, and make it safe to call 1155 ttunspecified later. */ 1156 memset(&sp->chars[i], 0, CHARS_EXTRA); 1157 1158 /* Read leap seconds, discarding those out of time_t range. */ 1159 leapcnt = 0; 1160 for (i = 0; i < leapcount(sp); i++) { 1161 int_fast64_t tr = stored == 4 ? detzcode(p) : detzcode64(p); 1162 int_fast32_2s corr = detzcode(p + stored); 1163 p += stored + 4; 1164 1165 /* Leap seconds cannot occur before the Epoch, 1166 or out of order. */ 1167 if (tr <= prevtr) 1168 return EINVAL; 1169 1170 /* To avoid other botches in this code, each leap second's 1171 correction must differ from the previous one's by 1 1172 second or less, except that the first correction can be 1173 any value; these requirements are more generous than 1174 RFC 9636, to allow future RFC extensions. */ 1175 if (! (i == 0 1176 || (prevcorr < corr 1177 ? corr == prevcorr + 1 1178 : (corr == prevcorr 1179 || corr == prevcorr - 1)))) 1180 return EINVAL; 1181 prevtr = tr; 1182 prevcorr = corr; 1183 1184 if (tr <= TIME_T_MAX) { 1185 struct lsinfo ls; 1186 ls.ls_trans = tr; 1187 ls.ls_corr = corr; 1188 set_lsinfo(sp, leapcnt, ls); 1189 leapcnt++; 1190 } 1191 } 1192 set_leapcount(sp, leapcnt); 1193 1194 for (i = 0; i < sp->typecnt; ++i) { 1195 register struct ttinfo * ttisp; 1196 1197 ttisp = &sp->ttis[i]; 1198 if (ttisstdcnt == 0) 1199 ttisp->tt_ttisstd = false; 1200 else { 1201 if (*p != true && *p != false) 1202 return EINVAL; 1203 ttisp->tt_ttisstd = *p++; 1204 } 1205 } 1206 for (i = 0; i < sp->typecnt; ++i) { 1207 register struct ttinfo * ttisp; 1208 1209 ttisp = &sp->ttis[i]; 1210 if (ttisutcnt == 0) 1211 ttisp->tt_ttisut = false; 1212 else { 1213 if (*p != true && *p != false) 1214 return EINVAL; 1215 ttisp->tt_ttisut = *p++; 1216 } 1217 } 1218 } 1219 1220 nread -= p - up->buf; 1221 memmove(up->buf, p, nread); 1222 1223 /* If this is an old file, we're done. */ 1224 if (!version) 1225 break; 1226 } 1227 if ((tzloadflags & TZLOAD_TZSTRING) && nread > 2 && 1228 up->buf[0] == '\n' && up->buf[nread - 1] == '\n' && 1229 sp->typecnt + 2 <= TZ_MAX_TYPES) { 1230 struct state *ts = &lsp->u.st; 1231 1232 up->buf[nread - 1] = '\0'; 1233 if (tzparse(&up->buf[1], ts, sp)) { 1234 1235 /* Attempt to reuse existing abbreviations. 1236 Without this, America/Anchorage would 1237 consume 50 bytes for abbreviations, as 1238 sp->charcnt equals 40 (for LMT AST AWT APT AHST 1239 AHDT YST AKDT AKST) and ts->charcnt equals 10 1240 (for AKST AKDT). Reusing means sp->charcnt can 1241 stay 40 in this example. */ 1242 int gotabbr = 0; 1243 int charcnt = sp->charcnt; 1244 for (i = 0; i < ts->typecnt; i++) { 1245 char *tsabbr = ts->chars + ts->ttis[i].tt_desigidx; 1246 int j; 1247 for (j = 0; j < charcnt; j++) 1248 if (strcmp(sp->chars + j, tsabbr) == 0) { 1249 ts->ttis[i].tt_desigidx = j; 1250 gotabbr++; 1251 break; 1252 } 1253 if (! (j < charcnt)) { 1254 int tsabbrlen = strnlen(tsabbr, TZ_MAX_CHARS - j); 1255 if (j + tsabbrlen < TZ_MAX_CHARS) { 1256 char *cp = sp->chars + j; 1257 cp = mempcpy(cp, tsabbr, tsabbrlen); 1258 *cp = '\0'; 1259 charcnt = j + tsabbrlen + 1; 1260 ts->ttis[i].tt_desigidx = j; 1261 gotabbr++; 1262 } 1263 } 1264 } 1265 if (gotabbr == ts->typecnt) { 1266 sp->charcnt = charcnt; 1267 1268 /* Ignore any trailing, no-op transitions generated 1269 by zic as they don't help here and can run afoul 1270 of bugs in zic 2016j or earlier. */ 1271 while (1 < sp->timecnt 1272 && (sp->types[sp->timecnt - 1] 1273 == sp->types[sp->timecnt - 2])) 1274 sp->timecnt--; 1275 1276 sp->goahead = ts->goahead; 1277 1278 for (i = 0; i < ts->timecnt; i++) { 1279 time_t t = ts->ats[i]; 1280 if (increment_overflow_time(&t, leapcorr(sp, t)) 1281 || (0 < sp->timecnt 1282 && t <= sp->ats[sp->timecnt - 1])) 1283 continue; 1284 if (TZ_MAX_TIMES <= sp->timecnt) { 1285 sp->goahead = false; 1286 break; 1287 } 1288 sp->ats[sp->timecnt] = t; 1289 sp->types[sp->timecnt] = (sp->typecnt 1290 + ts->types[i]); 1291 sp->timecnt++; 1292 } 1293 for (i = 0; i < ts->typecnt; i++) 1294 sp->ttis[sp->typecnt++] = ts->ttis[i]; 1295 } 1296 } 1297 } 1298 if (sp->typecnt == 0) 1299 return EINVAL; 1300 1301 return 0; 1302 } 1303 1304 /* Load tz data from the file named NAME into *SP. Respect TZLOADFLAGS. 1305 Return 0 on success, an errno value on failure. */ 1306 static int 1307 tzload(char const *name, struct state *sp, char tzloadflags) 1308 { 1309 int r; 1310 union local_storage *lsp0; 1311 union local_storage *lsp; 1312 #if ALL_STATE 1313 lsp = NULL; 1314 #else 1315 union local_storage ls; 1316 lsp = &ls; 1317 #endif 1318 lsp0 = lsp; 1319 r = tzloadbody(name, sp, tzloadflags, &lsp); 1320 if (lsp != lsp0) 1321 free(lsp); 1322 return r; 1323 } 1324 1325 static const int mon_lengths[2][MONSPERYEAR] = { 1326 { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }, 1327 { 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 } 1328 }; 1329 1330 static const int year_lengths[2] = { 1331 DAYSPERNYEAR, DAYSPERLYEAR 1332 }; 1333 1334 /* Is C an ASCII digit? */ 1335 static bool 1336 is_digit(char c) 1337 { 1338 return '0' <= c && c <= '9'; 1339 } 1340 1341 /* 1342 ** Given a pointer into a timezone string, scan until a character that is not 1343 ** a valid character in a time zone abbreviation is found. 1344 ** Return a pointer to that character. 1345 */ 1346 1347 ATTRIBUTE_PURE_114833 static const char * 1348 getzname(register const char *strp) 1349 { 1350 register char c; 1351 1352 while ((c = *strp) != '\0' && !is_digit(c) && c != ',' && c != '-' && 1353 c != '+') 1354 ++strp; 1355 return strp; 1356 } 1357 1358 /* 1359 ** Given a pointer into an extended timezone string, scan until the ending 1360 ** delimiter of the time zone abbreviation is located. 1361 ** Return a pointer to the delimiter. 1362 ** 1363 ** As with getzname above, the legal character set is actually quite 1364 ** restricted, with other characters producing undefined results. 1365 ** We don't do any checking here; checking is done later in common-case code. 1366 */ 1367 1368 ATTRIBUTE_PURE_114833 static const char * 1369 getqzname(register const char *strp, const int delim) 1370 { 1371 register int c; 1372 1373 while ((c = *strp) != '\0' && c != delim) 1374 ++strp; 1375 return strp; 1376 } 1377 1378 /* 1379 ** Given a pointer into a timezone string, extract a number from that string. 1380 ** Check that the number is within a specified range; if it is not, return 1381 ** NULL. 1382 ** Otherwise, return a pointer to the first character not part of the number. 1383 */ 1384 1385 static const char * 1386 getnum(register const char *strp, int *const nump, const int min, const int max) 1387 { 1388 register char c; 1389 register int num; 1390 1391 if (strp == NULL || !is_digit(c = *strp)) 1392 return NULL; 1393 num = 0; 1394 do { 1395 num = num * 10 + (c - '0'); 1396 if (num > max) 1397 return NULL; /* illegal value */ 1398 c = *++strp; 1399 } while (is_digit(c)); 1400 if (num < min) 1401 return NULL; /* illegal value */ 1402 *nump = num; 1403 return strp; 1404 } 1405 1406 /* 1407 ** Given a pointer into a timezone string, extract a number of seconds, 1408 ** in hh[:mm[:ss]] form, from the string. 1409 ** If any error occurs, return NULL. 1410 ** Otherwise, return a pointer to the first character not part of the number 1411 ** of seconds. 1412 */ 1413 1414 static const char * 1415 getsecs(register const char *strp, int_fast32_t *const secsp) 1416 { 1417 int num; 1418 int_fast32_t secsperhour = SECSPERHOUR; 1419 1420 /* 1421 ** 'HOURSPERDAY * DAYSPERWEEK - 1' allows quasi-POSIX rules like 1422 ** "M10.4.6/26", which does not conform to POSIX, 1423 ** but which specifies the equivalent of 1424 ** "02:00 on the first Sunday on or after 23 Oct". 1425 */ 1426 strp = getnum(strp, &num, 0, HOURSPERDAY * DAYSPERWEEK - 1); 1427 if (strp == NULL) 1428 return NULL; 1429 *secsp = num * secsperhour; 1430 if (*strp == ':') { 1431 ++strp; 1432 strp = getnum(strp, &num, 0, MINSPERHOUR - 1); 1433 if (strp == NULL) 1434 return NULL; 1435 *secsp += num * SECSPERMIN; 1436 if (*strp == ':') { 1437 ++strp; 1438 /* 'SECSPERMIN' allows for leap seconds. */ 1439 strp = getnum(strp, &num, 0, SECSPERMIN); 1440 if (strp == NULL) 1441 return NULL; 1442 *secsp += num; 1443 } 1444 } 1445 return strp; 1446 } 1447 1448 /* 1449 ** Given a pointer into a timezone string, extract an offset, in 1450 ** [+-]hh[:mm[:ss]] form, from the string. 1451 ** If any error occurs, return NULL. 1452 ** Otherwise, return a pointer to the first character not part of the time. 1453 */ 1454 1455 static const char * 1456 getoffset(register const char *strp, int_fast32_t *const offsetp) 1457 { 1458 register bool neg = false; 1459 1460 if (*strp == '-') { 1461 neg = true; 1462 ++strp; 1463 } else if (*strp == '+') 1464 ++strp; 1465 strp = getsecs(strp, offsetp); 1466 if (strp == NULL) 1467 return NULL; /* illegal time */ 1468 if (neg) 1469 *offsetp = -*offsetp; 1470 return strp; 1471 } 1472 1473 /* 1474 ** Given a pointer into a timezone string, extract a rule in the form 1475 ** date[/time]. See POSIX Base Definitions section 8.3 variable TZ 1476 ** for the format of "date" and "time". 1477 ** If a valid rule is not found, return NULL. 1478 ** Otherwise, return a pointer to the first character not part of the rule. 1479 */ 1480 1481 static const char * 1482 getrule(const char *strp, register struct rule *const rulep) 1483 { 1484 if (*strp == 'J') { 1485 /* 1486 ** Julian day. 1487 */ 1488 rulep->r_type = JULIAN_DAY; 1489 ++strp; 1490 strp = getnum(strp, &rulep->r_day, 1, DAYSPERNYEAR); 1491 } else if (*strp == 'M') { 1492 /* 1493 ** Month, week, day. 1494 */ 1495 rulep->r_type = MONTH_NTH_DAY_OF_WEEK; 1496 ++strp; 1497 strp = getnum(strp, &rulep->r_mon, 1, MONSPERYEAR); 1498 if (strp == NULL) 1499 return NULL; 1500 if (*strp++ != '.') 1501 return NULL; 1502 strp = getnum(strp, &rulep->r_week, 1, 5); 1503 if (strp == NULL) 1504 return NULL; 1505 if (*strp++ != '.') 1506 return NULL; 1507 strp = getnum(strp, &rulep->r_day, 0, DAYSPERWEEK - 1); 1508 } else if (is_digit(*strp)) { 1509 /* 1510 ** Day of year. 1511 */ 1512 rulep->r_type = DAY_OF_YEAR; 1513 strp = getnum(strp, &rulep->r_day, 0, DAYSPERLYEAR - 1); 1514 } else return NULL; /* invalid format */ 1515 if (strp == NULL) 1516 return NULL; 1517 if (*strp == '/') { 1518 /* 1519 ** Time specified. 1520 */ 1521 ++strp; 1522 strp = getoffset(strp, &rulep->r_time); 1523 } else rulep->r_time = 2 * SECSPERHOUR; /* default = 2:00:00 */ 1524 return strp; 1525 } 1526 1527 /* 1528 ** Given a year, a rule, and the offset from UT at the time that rule takes 1529 ** effect, calculate the year-relative time that rule takes effect. 1530 */ 1531 1532 static int_fast32_t 1533 transtime(const int year, register const struct rule *const rulep, 1534 const int_fast32_t offset) 1535 { 1536 register bool leapyear; 1537 register int_fast32_t value; 1538 register int i; 1539 int d, m1, yy0, yy1, yy2, dow; 1540 1541 leapyear = isleap(year); 1542 switch (rulep->r_type) { 1543 1544 case JULIAN_DAY: 1545 /* 1546 ** Jn - Julian day, 1 == January 1, 60 == March 1 even in leap 1547 ** years. 1548 ** In non-leap years, or if the day number is 59 or less, just 1549 ** add SECSPERDAY times the day number-1 to the time of 1550 ** January 1, midnight, to get the day. 1551 */ 1552 value = (rulep->r_day - 1) * SECSPERDAY; 1553 if (leapyear && rulep->r_day >= 60) 1554 value += SECSPERDAY; 1555 break; 1556 1557 case DAY_OF_YEAR: 1558 /* 1559 ** n - day of year. 1560 ** Just add SECSPERDAY times the day number to the time of 1561 ** January 1, midnight, to get the day. 1562 */ 1563 value = rulep->r_day * SECSPERDAY; 1564 break; 1565 1566 case MONTH_NTH_DAY_OF_WEEK: 1567 /* 1568 ** Mm.n.d - nth "dth day" of month m. 1569 */ 1570 1571 /* 1572 ** Use Zeller's Congruence to get day-of-week of first day of 1573 ** month. 1574 */ 1575 m1 = (rulep->r_mon + 9) % 12 + 1; 1576 yy0 = (rulep->r_mon <= 2) ? (year - 1) : year; 1577 yy1 = yy0 / 100; 1578 yy2 = yy0 % 100; 1579 dow = ((26 * m1 - 2) / 10 + 1580 1 + yy2 + yy2 / 4 + yy1 / 4 - 2 * yy1) % 7; 1581 if (dow < 0) 1582 dow += DAYSPERWEEK; 1583 1584 /* 1585 ** "dow" is the day-of-week of the first day of the month. Get 1586 ** the day-of-month (zero-origin) of the first "dow" day of the 1587 ** month. 1588 */ 1589 d = rulep->r_day - dow; 1590 if (d < 0) 1591 d += DAYSPERWEEK; 1592 for (i = 1; i < rulep->r_week; ++i) { 1593 if (d + DAYSPERWEEK >= 1594 mon_lengths[leapyear][rulep->r_mon - 1]) 1595 break; 1596 d += DAYSPERWEEK; 1597 } 1598 1599 /* 1600 ** "d" is the day-of-month (zero-origin) of the day we want. 1601 */ 1602 value = d * SECSPERDAY; 1603 for (i = 0; i < rulep->r_mon - 1; ++i) 1604 value += mon_lengths[leapyear][i] * SECSPERDAY; 1605 break; 1606 1607 default: unreachable(); 1608 } 1609 1610 /* 1611 ** "value" is the year-relative time of 00:00:00 UT on the day in 1612 ** question. To get the year-relative time of the specified local 1613 ** time on that day, add the transition time and the current offset 1614 ** from UT. 1615 */ 1616 return value + rulep->r_time + offset; 1617 } 1618 1619 /* 1620 ** Given a POSIX.1 proleptic TZ string, fill in the rule tables as 1621 ** appropriate. 1622 */ 1623 1624 static bool 1625 tzparse(const char *name, struct state *sp, struct state const *basep) 1626 { 1627 const char * stdname; 1628 const char * dstname; 1629 int_fast32_t stdoffset; 1630 int_fast32_t dstoffset; 1631 register char * cp; 1632 ptrdiff_t stdlen, dstlen, charcnt; 1633 time_t atlo = TIME_T_MIN, leaplo = TIME_T_MIN; 1634 1635 stdname = name; 1636 if (*name == '<') { 1637 name++; 1638 stdname = name; 1639 name = getqzname(name, '>'); 1640 if (*name != '>') 1641 return false; 1642 stdlen = name - stdname; 1643 name++; 1644 } else { 1645 name = getzname(name); 1646 stdlen = name - stdname; 1647 } 1648 if (! (0 < stdlen && stdlen <= TZNAME_MAXIMUM)) 1649 return false; 1650 name = getoffset(name, &stdoffset); 1651 if (name == NULL) 1652 return false; 1653 charcnt = stdlen + 1; 1654 if (basep) { 1655 if (0 < basep->timecnt) 1656 atlo = basep->ats[basep->timecnt - 1]; 1657 set_leapcount(sp, leapcount(basep)); 1658 if (0 < leapcount(sp)) { 1659 int i; 1660 for (i = 0; i < leapcount(sp); i++) 1661 set_lsinfo(sp, i, lsinfo(basep, i)); 1662 leaplo = lsinfo(sp, leapcount(sp) - 1).ls_trans; 1663 } 1664 } else 1665 set_leapcount(sp, 0); /* So, we're off a little. */ 1666 sp->goback = sp->goahead = false; 1667 if (*name != '\0') { 1668 struct rule start, end; 1669 int year, yearbeg, yearlim, timecnt; 1670 time_t janfirst; 1671 int_fast32_t janoffset = 0; 1672 1673 if (*name == '<') { 1674 dstname = ++name; 1675 name = getqzname(name, '>'); 1676 if (*name != '>') 1677 return false; 1678 dstlen = name - dstname; 1679 name++; 1680 } else { 1681 dstname = name; 1682 name = getzname(name); 1683 dstlen = name - dstname; /* length of DST abbr. */ 1684 } 1685 if (! (0 < dstlen && dstlen <= TZNAME_MAXIMUM)) 1686 return false; 1687 charcnt += dstlen + 1; 1688 if (*name != '\0' && *name != ',' && *name != ';') { 1689 name = getoffset(name, &dstoffset); 1690 if (name == NULL) 1691 return false; 1692 } else dstoffset = stdoffset - SECSPERHOUR; 1693 1694 if (*name == '\0') 1695 name = TZDEFRULESTRING; 1696 if (! (*name == ',' || *name == ';')) 1697 return false; 1698 1699 name = getrule(name + 1, &start); 1700 if (!name) 1701 return false; 1702 if (*name++ != ',') 1703 return false; 1704 name = getrule(name, &end); 1705 if (!name || *name) 1706 return false; 1707 sp->typecnt = 2; /* standard time and DST */ 1708 /* 1709 ** Two transitions per year, from EPOCH_YEAR forward. 1710 */ 1711 init_ttinfo(&sp->ttis[0], -stdoffset, false, 0); 1712 init_ttinfo(&sp->ttis[1], -dstoffset, true, stdlen + 1); 1713 timecnt = 0; 1714 janfirst = 0; 1715 yearbeg = EPOCH_YEAR; 1716 1717 do { 1718 int_fast32_t yearsecs 1719 = year_lengths[isleap(yearbeg - 1)] * SECSPERDAY; 1720 time_t janfirst1 = janfirst; 1721 yearbeg--; 1722 if (increment_overflow_time(&janfirst1, -yearsecs)) { 1723 janoffset = -yearsecs; 1724 break; 1725 } 1726 janfirst = janfirst1; 1727 } while (atlo < janfirst 1728 && EPOCH_YEAR - YEARSPERREPEAT / 2 < yearbeg); 1729 1730 while (true) { 1731 int_fast32_t yearsecs 1732 = year_lengths[isleap(yearbeg)] * SECSPERDAY; 1733 int yearbeg1 = yearbeg; 1734 time_t janfirst1 = janfirst; 1735 if (increment_overflow_time(&janfirst1, yearsecs) 1736 || increment_overflow(&yearbeg1, 1) 1737 || atlo <= janfirst1) 1738 break; 1739 yearbeg = yearbeg1; 1740 janfirst = janfirst1; 1741 } 1742 1743 yearlim = yearbeg; 1744 if (increment_overflow(&yearlim, years_of_observations)) 1745 yearlim = INT_MAX; 1746 for (year = yearbeg; year < yearlim; year++) { 1747 int_fast32_t 1748 starttime = transtime(year, &start, stdoffset), 1749 endtime = transtime(year, &end, dstoffset), 1750 yearsecs = year_lengths[isleap(year)] * SECSPERDAY; 1751 bool reversed = endtime < starttime; 1752 if (reversed) { 1753 int_fast32_t swap = starttime; 1754 starttime = endtime; 1755 endtime = swap; 1756 } 1757 if (reversed 1758 || (starttime < endtime 1759 && endtime - starttime < yearsecs)) { 1760 if (TZ_MAX_TIMES - 2 < timecnt) 1761 break; 1762 sp->ats[timecnt] = janfirst; 1763 if (! increment_overflow_time(&sp->ats[timecnt], 1764 janoffset + starttime) 1765 && atlo <= sp->ats[timecnt]) 1766 sp->types[timecnt++] = !reversed; 1767 sp->ats[timecnt] = janfirst; 1768 if (! increment_overflow_time(&sp->ats[timecnt], 1769 janoffset + endtime) 1770 && atlo <= sp->ats[timecnt]) { 1771 sp->types[timecnt++] = reversed; 1772 } 1773 } 1774 if (endtime < leaplo) { 1775 yearlim = year; 1776 if (increment_overflow(&yearlim, years_of_observations)) 1777 yearlim = INT_MAX; 1778 } 1779 if (increment_overflow_time(&janfirst, janoffset + yearsecs)) 1780 break; 1781 janoffset = 0; 1782 } 1783 sp->timecnt = timecnt; 1784 if (! timecnt) { 1785 sp->ttis[0] = sp->ttis[1]; 1786 sp->typecnt = 1; /* Perpetual DST. */ 1787 } else if (years_of_observations <= year - yearbeg) 1788 sp->goback = sp->goahead = true; 1789 } else { 1790 dstlen = 0; 1791 sp->typecnt = 1; /* only standard time */ 1792 sp->timecnt = 0; 1793 init_ttinfo(&sp->ttis[0], -stdoffset, false, 0); 1794 } 1795 sp->charcnt = charcnt; 1796 cp = sp->chars; 1797 cp = mempcpy(cp, stdname, stdlen); 1798 *cp++ = '\0'; 1799 if (dstlen != 0) { 1800 cp = mempcpy(cp, dstname, dstlen); 1801 *cp = '\0'; 1802 } 1803 return true; 1804 } 1805 1806 static void 1807 gmtload(struct state *const sp) 1808 { 1809 if (!TZ_RUNTIME_LEAPS || tzload(etc_utc, sp, TZLOAD_TZSTRING) != 0) 1810 tzparse("UTC0", sp, NULL); 1811 } 1812 1813 #if !USE_TIMEX_T || !defined TM_GMTOFF 1814 1815 /* Return true if primary cached time zone data are fresh, 1816 i.e., if this function is known to have recently returned false. 1817 A call is recent if it occurred less than tz_change_interval seconds ago. 1818 NOW should be the current time. */ 1819 static bool 1820 fresh_tzdata(monotime_t now) 1821 { 1822 /* If nonzero, the time of the last false return. */ 1823 static monotime_t last_checked; 1824 1825 if (last_checked && now - last_checked < tz_change_interval) 1826 return true; 1827 last_checked = now; 1828 return false; 1829 } 1830 1831 /* Initialize *SP to a value appropriate for the TZ setting NAME. 1832 Respect TZLOADFLAGS. 1833 Return 0 on success, an errno value on failure. */ 1834 static int 1835 zoneinit(struct state *sp, char const *name, char tzloadflags) 1836 { 1837 if (name && ! name[0]) { 1838 /* 1839 ** User wants it fast rather than right. 1840 */ 1841 set_leapcount(sp, 0); /* so, we're off a little */ 1842 sp->timecnt = 0; 1843 sp->typecnt = 0; 1844 sp->charcnt = 0; 1845 sp->goback = sp->goahead = false; 1846 init_ttinfo(&sp->ttis[0], 0, false, 0); 1847 strcpy(sp->chars, utc); 1848 return 0; 1849 } else { 1850 int err = tzload(name, sp, tzloadflags); 1851 if (err != 0 && name && name[0] != ':' && !(tzloadflags & TZLOAD_TZDIR_SUB) 1852 && tzparse(name, sp, NULL)) 1853 err = 0; 1854 if (err == 0) 1855 err = scrub_abbrs(sp); 1856 return err; 1857 } 1858 } 1859 1860 /* If THREADED, upgrade a read lock to a write lock. 1861 Return 0 on success, a positive errno value otherwise. */ 1862 static int 1863 rd2wrlock(ATTRIBUTE_MAYBE_UNUSED bool threaded) 1864 { 1865 # if THREAD_RWLOCK 1866 if (threaded) { 1867 dounlock(); 1868 return pthread_rwlock_wrlock(&locallock); 1869 } 1870 # endif 1871 return 0; 1872 } 1873 1874 /* Like tzset(), but in a critical section. 1875 If THREADED && THREAD_RWLOCK the caller has a read lock, 1876 and this function might upgrade it to a write lock. 1877 If WALL, act as if TZ is unset; although always false in this file, 1878 a wrapper .c file's obsolete and ineffective tzsetwall function can use it. 1879 If tz_change_interval is positive the time is NOW; otherwise ignore NOW. */ 1880 static void 1881 tzset_unlocked(bool threaded, bool wall, monotime_t now) 1882 { 1883 char const *name; 1884 struct state *sp; 1885 char tzloadflags; 1886 size_t namelen; 1887 bool writing = false; 1888 1889 for (;;) { 1890 name = wall ? NULL : getenv("TZ"); 1891 sp = lclptr; 1892 tzloadflags = TZLOAD_FROMENV | TZLOAD_TZSTRING; 1893 namelen = sizeof lcl_TZname + 1; /* placeholder for no name */ 1894 1895 if (name) { 1896 namelen = strnlen(name, sizeof lcl_TZname); 1897 1898 /* Abbreviate a string like "/usr/share/zoneinfo/America/Los_Angeles" 1899 to its shorter equivalent "America/Los_Angeles". */ 1900 if (!SUPPRESS_TZDIR && tzdirslashlen < namelen 1901 && memcmp(name, tzdirslash, tzdirslashlen) == 0) { 1902 char const *p = name + tzdirslashlen; 1903 while (*p == '/') 1904 p++; 1905 if (*p && *p != ':') { 1906 name = p; 1907 namelen = strnlen(name, sizeof lcl_TZname); 1908 tzloadflags |= TZLOAD_TZDIR_SUB; 1909 } 1910 } 1911 } 1912 1913 if ((tz_change_interval <= 0 ? tz_change_interval < 0 : fresh_tzdata(now)) 1914 && (name 1915 ? 0 < lcl_is_set && strcmp(lcl_TZname, name) == 0 1916 : lcl_is_set < 0)) 1917 return; 1918 1919 if (!THREAD_RWLOCK || writing) 1920 break; 1921 if (rd2wrlock(threaded) != 0) 1922 return; 1923 writing = true; 1924 } 1925 1926 # if ALL_STATE 1927 if (! sp) 1928 lclptr = sp = malloc(sizeof *lclptr); 1929 # endif 1930 if (sp) { 1931 int err = zoneinit(sp, name, tzloadflags); 1932 if (err != 0) { 1933 zoneinit(sp, "", 0); 1934 /* Abbreviate with "-00" if there was an error. 1935 Do not treat a missing TZDEFAULT file as an error. */ 1936 if (name || err != ENOENT) 1937 strcpy(sp->chars, UNSPEC); 1938 } 1939 if (namelen < sizeof lcl_TZname) { 1940 char *cp = lcl_TZname; 1941 cp = mempcpy(cp, name, namelen); 1942 *cp = '\0'; 1943 } 1944 } 1945 settzname(); 1946 lcl_is_set = (sizeof lcl_TZname > namelen) - (sizeof lcl_TZname < namelen); 1947 } 1948 1949 #endif 1950 1951 #if !defined TM_GMTOFF || !USE_TIMEX_T 1952 1953 /* If tz_change_interval is positive, 1954 return the current time as a monotonically nondecreasing value. 1955 Otherwise the return value does not matter. */ 1956 static monotime_t 1957 get_monotonic_time(void) 1958 { 1959 struct timespec now; 1960 now.tv_sec = 0; 1961 if (0 < tz_change_interval) 1962 clock_gettime(CLOCK_MONOTONIC_COARSE, &now); 1963 return now.tv_sec; 1964 } 1965 #endif 1966 1967 #if !USE_TIMEX_T 1968 1969 void 1970 tzset(void) 1971 { 1972 monotime_t now = get_monotonic_time(); 1973 int err = lock(); 1974 if (0 < err) { 1975 errno = err; 1976 return; 1977 } 1978 tzset_unlocked(!err, false, now); 1979 unlock(!err); 1980 } 1981 #endif 1982 1983 #ifdef __FreeBSD__ 1984 void 1985 freebsd13_tzsetwall(void) 1986 { 1987 monotime_t now = get_monotonic_time(); 1988 int err = lock(); 1989 if (0 < err) { 1990 errno = err; 1991 return; 1992 } 1993 tzset_unlocked(!err, true, now); 1994 unlock(!err); 1995 } 1996 __sym_compat(tzsetwall, freebsd13_tzsetwall, FBSD_1.0); 1997 __warn_references(tzsetwall, 1998 "warning: tzsetwall() is deprecated, use tzset() instead."); 1999 #endif /* __FreeBSD__ */ 2000 static void 2001 gmtcheck1(void) 2002 { 2003 #if ALL_STATE 2004 gmtptr = malloc(sizeof *gmtptr); 2005 #endif 2006 if (gmtptr) 2007 gmtload(gmtptr); 2008 } 2009 2010 static void 2011 gmtcheck(void) 2012 { 2013 static once_t gmt_once = ONCE_INIT; 2014 once(&gmt_once, gmtcheck1); 2015 } 2016 2017 #if NETBSD_INSPIRED && !USE_TIMEX_T 2018 2019 timezone_t 2020 tzalloc(char const *name) 2021 { 2022 timezone_t sp = malloc(sizeof *sp); 2023 if (sp) { 2024 int err = zoneinit(sp, name, TZLOAD_TZSTRING); 2025 if (err != 0) { 2026 free(sp); 2027 errno = err; 2028 return NULL; 2029 } 2030 } else if (!HAVE_MALLOC_ERRNO) 2031 errno = ENOMEM; 2032 return sp; 2033 } 2034 2035 #ifndef FREE_PRESERVES_ERRNO 2036 # if ((defined _POSIX_VERSION && 202405 <= _POSIX_VERSION) \ 2037 || (defined __GLIBC__ && 2 < __GLIBC__ + (33 <= __GLIBC_MINOR__)) \ 2038 || defined __OpenBSD__ || defined __sun) 2039 # define FREE_PRESERVES_ERRNO 1 2040 # else 2041 # define FREE_PRESERVES_ERRNO 0 2042 # endif 2043 #endif 2044 2045 void 2046 tzfree(timezone_t sp) 2047 { 2048 int err; 2049 if (!FREE_PRESERVES_ERRNO) 2050 err = errno; 2051 free(sp); 2052 if (!FREE_PRESERVES_ERRNO) 2053 errno = err; 2054 } 2055 2056 /* 2057 ** NetBSD 6.1.4 has ctime_rz, but omit it because C23 deprecates ctime and 2058 ** POSIX.1-2024 removes ctime_r. Both have potential security problems that 2059 ** ctime_rz would share. Callers can instead use localtime_rz + strftime. 2060 ** 2061 ** NetBSD 6.1.4 has tzgetname, but omit it because it doesn't work 2062 ** in zones with three or more time zone abbreviations. 2063 ** Callers can instead use localtime_rz + strftime. 2064 */ 2065 2066 #endif 2067 2068 #if !USE_TIMEX_T || !defined TM_GMTOFF 2069 2070 /* 2071 ** The easy way to behave "as if no library function calls" localtime 2072 ** is to not call it, so we drop its guts into "localsub", which can be 2073 ** freely called. (And no, the PANS doesn't require the above behavior, 2074 ** but it *is* desirable.) 2075 ** 2076 ** If successful and SETNAME is nonzero, 2077 ** set the applicable parts of tzname, timezone and altzone; 2078 ** however, it's OK to omit this step for proleptic TZ strings 2079 ** since in that case tzset should have already done this step correctly. 2080 ** SETNAME's type is int_fast32_t for compatibility with gmtsub, 2081 ** but it is actually a boolean and its value should be 0 or 1. 2082 */ 2083 2084 /*ARGSUSED*/ 2085 static struct tm * 2086 localsub(struct state const *sp, time_t const *timep, int_fast32_t setname, 2087 struct tm *const tmp) 2088 { 2089 register const struct ttinfo * ttisp; 2090 register int i; 2091 register struct tm * result; 2092 const time_t t = *timep; 2093 2094 if (sp == NULL) { 2095 /* Don't bother to set tzname etc.; tzset has already done it. */ 2096 return gmtsub(gmtptr, timep, 0, tmp); 2097 } 2098 if ((sp->goback && t < sp->ats[0]) || 2099 (sp->goahead && t > sp->ats[sp->timecnt - 1])) { 2100 time_t newt; 2101 register time_t seconds; 2102 register time_t years; 2103 2104 if (t < sp->ats[0]) 2105 seconds = sp->ats[0] - t; 2106 else seconds = t - sp->ats[sp->timecnt - 1]; 2107 --seconds; 2108 2109 /* Beware integer overflow, as SECONDS might 2110 be close to the maximum time_t. */ 2111 years = seconds / SECSPERREPEAT * YEARSPERREPEAT; 2112 seconds = years * AVGSECSPERYEAR; 2113 years += YEARSPERREPEAT; 2114 if (t < sp->ats[0]) 2115 newt = t + seconds + SECSPERREPEAT; 2116 else 2117 newt = t - seconds - SECSPERREPEAT; 2118 2119 if (newt < sp->ats[0] || 2120 newt > sp->ats[sp->timecnt - 1]) 2121 return NULL; /* "cannot happen" */ 2122 result = localsub(sp, &newt, setname, tmp); 2123 if (result) { 2124 # if defined ckd_add && defined ckd_sub 2125 if (t < sp->ats[0] 2126 ? ckd_sub(&result->tm_year, 2127 result->tm_year, years) 2128 : ckd_add(&result->tm_year, 2129 result->tm_year, years)) 2130 return NULL; 2131 # else 2132 register int_fast64_t newy; 2133 2134 newy = result->tm_year; 2135 if (t < sp->ats[0]) 2136 newy -= years; 2137 else newy += years; 2138 if (! (INT_MIN <= newy && newy <= INT_MAX)) 2139 return NULL; 2140 result->tm_year = newy; 2141 # endif 2142 } 2143 return result; 2144 } 2145 if (sp->timecnt == 0 || t < sp->ats[0]) { 2146 i = 0; 2147 } else { 2148 register int lo = 1; 2149 register int hi = sp->timecnt; 2150 2151 while (lo < hi) { 2152 register int mid = (lo + hi) >> 1; 2153 2154 if (t < sp->ats[mid]) 2155 hi = mid; 2156 else lo = mid + 1; 2157 } 2158 i = sp->types[lo - 1]; 2159 } 2160 ttisp = &sp->ttis[i]; 2161 /* 2162 ** To get (wrong) behavior that's compatible with System V Release 2.0 2163 ** you'd replace the statement below with 2164 ** t += ttisp->tt_utoff; 2165 ** timesub(&t, 0, sp, tmp); 2166 */ 2167 result = timesub(&t, ttisp->tt_utoff, sp, tmp); 2168 if (result) { 2169 result->tm_isdst = ttisp->tt_isdst; 2170 # ifdef TM_ZONE 2171 result->TM_ZONE = UNCONST(&sp->chars[ttisp->tt_desigidx]); 2172 # endif 2173 if (setname) 2174 update_tzname_etc(sp, ttisp); 2175 } 2176 return result; 2177 } 2178 #endif 2179 2180 #if !USE_TIMEX_T 2181 2182 /* Return TMP, or a thread-specific struct tm * selected by WHICH. */ 2183 static struct tm * 2184 tm_multi(struct tm *tmp, ATTRIBUTE_MAYBE_UNUSED enum tm_multi which) 2185 { 2186 # if THREAD_SAFE && THREAD_TM_MULTI 2187 /* It is OK to check is_threaded() separately here; even if it 2188 returns a different value in other places in the caller, 2189 this function's behavior is still valid. */ 2190 if (is_threaded()) { 2191 /* Try to get a thread-specific struct tm *. 2192 Fall back on TMP if this fails. */ 2193 static pthread_once_t tm_multi_once = PTHREAD_ONCE_INIT; 2194 pthread_once(&tm_multi_once, tm_multi_key_init); 2195 if (!tm_multi_key_err) { 2196 struct tm *p = pthread_getspecific(tm_multi_key); 2197 if (!p) { 2198 p = malloc(N_TM_MULTI * sizeof *p); 2199 if (p && pthread_setspecific(tm_multi_key, p) != 0) { 2200 free(p); 2201 p = NULL; 2202 } 2203 } 2204 if (p) 2205 return &p[which]; 2206 } 2207 } 2208 # endif 2209 return tmp; 2210 } 2211 2212 # if NETBSD_INSPIRED 2213 struct tm * 2214 localtime_rz(struct state *restrict sp, time_t const *restrict timep, 2215 struct tm *restrict tmp) 2216 { 2217 return localsub(sp, timep, 0, tmp); 2218 } 2219 # endif 2220 2221 static struct tm * 2222 localtime_tzset(time_t const *timep, struct tm *tmp, bool setname) 2223 { 2224 monotime_t now = get_monotonic_time(); 2225 int err = lock(); 2226 if (0 < err) { 2227 errno = err; 2228 return NULL; 2229 } 2230 if (0 <= tz_change_interval || setname || !lcl_is_set) 2231 tzset_unlocked(!err, false, now); 2232 tmp = localsub(lclptr, timep, setname, tmp); 2233 unlock(!err); 2234 return tmp; 2235 } 2236 2237 struct tm * 2238 localtime(const time_t *timep) 2239 { 2240 # if !SUPPORT_C89 2241 static struct tm tm; 2242 # endif 2243 return localtime_tzset(timep, tm_multi(&tm, LOCALTIME_TM_MULTI), true); 2244 } 2245 2246 struct tm * 2247 localtime_r(const time_t *restrict timep, struct tm *restrict tmp) 2248 { 2249 return localtime_tzset(timep, tmp, false); 2250 } 2251 #endif 2252 2253 /* 2254 ** gmtsub is to gmtime as localsub is to localtime. 2255 */ 2256 2257 static struct tm * 2258 gmtsub(ATTRIBUTE_MAYBE_UNUSED struct state const *sp, time_t const *timep, 2259 int_fast32_t offset, struct tm *tmp) 2260 { 2261 register struct tm * result; 2262 2263 result = timesub(timep, offset, gmtptr, tmp); 2264 #ifdef TM_ZONE 2265 /* 2266 ** Could get fancy here and deliver something such as 2267 ** "+xx" or "-xx" if offset is non-zero, 2268 ** but this is no time for a treasure hunt. 2269 */ 2270 tmp->TM_ZONE = UNCONST(offset ? wildabbr 2271 : gmtptr ? gmtptr->chars : utc); 2272 #endif /* defined TM_ZONE */ 2273 return result; 2274 } 2275 2276 #if !USE_TIMEX_T 2277 2278 /* 2279 * Re-entrant version of gmtime. 2280 */ 2281 2282 struct tm * 2283 gmtime_r(time_t const *restrict timep, struct tm *restrict tmp) 2284 { 2285 gmtcheck(); 2286 return gmtsub(gmtptr, timep, 0, tmp); 2287 } 2288 2289 struct tm * 2290 gmtime(const time_t *timep) 2291 { 2292 # if !SUPPORT_C89 2293 static struct tm tm; 2294 # endif 2295 return gmtime_r(timep, tm_multi(&tm, GMTIME_TM_MULTI)); 2296 } 2297 2298 # if STD_INSPIRED 2299 2300 /* This function is obsolescent and may disappear in future releases. 2301 Callers can instead use localtime_rz with a fixed-offset zone. */ 2302 2303 struct tm * 2304 offtime_r(time_t const *restrict timep, long offset, struct tm *restrict tmp) 2305 { 2306 gmtcheck(); 2307 return gmtsub(gmtptr, timep, offset, tmp); 2308 } 2309 2310 struct tm * 2311 offtime(time_t const *timep, long offset) 2312 { 2313 # if !SUPPORT_C89 2314 static struct tm tm; 2315 # endif 2316 return offtime_r(timep, offset, tm_multi(&tm, OFFTIME_TM_MULTI)); 2317 } 2318 2319 # endif 2320 #endif 2321 2322 /* 2323 ** Return the number of leap years through the end of the given year 2324 ** where, to make the math easy, the answer for year zero is defined as zero. 2325 */ 2326 2327 static time_t 2328 leaps_thru_end_of_nonneg(time_t y) 2329 { 2330 return y / 4 - y / 100 + y / 400; 2331 } 2332 2333 static time_t 2334 leaps_thru_end_of(time_t y) 2335 { 2336 return (y < 0 2337 ? -1 - leaps_thru_end_of_nonneg(-1 - y) 2338 : leaps_thru_end_of_nonneg(y)); 2339 } 2340 2341 static struct tm * 2342 timesub(const time_t *timep, int_fast32_t offset, 2343 const struct state *sp, struct tm *tmp) 2344 { 2345 register time_t tdays; 2346 register const int * ip; 2347 int_fast32_2s corr; 2348 register int i; 2349 int_fast32_t idays, rem, dayoff, dayrem; 2350 time_t y; 2351 2352 /* If less than SECSPERMIN, the number of seconds since the 2353 most recent positive leap second; otherwise, do not add 1 2354 to localtime tm_sec because of leap seconds. */ 2355 time_t secs_since_posleap = SECSPERMIN; 2356 2357 corr = 0; 2358 i = sp ? leapcount(sp) : 0; 2359 while (--i >= 0) { 2360 struct lsinfo ls = lsinfo(sp, i); 2361 if (ls.ls_trans <= *timep) { 2362 corr = ls.ls_corr; 2363 if ((i == 0 ? 0 : lsinfo(sp, i - 1).ls_corr) < corr) 2364 secs_since_posleap = *timep - ls.ls_trans; 2365 break; 2366 } 2367 } 2368 2369 /* Calculate the year, avoiding integer overflow even if 2370 time_t is unsigned. */ 2371 tdays = *timep / SECSPERDAY; 2372 rem = *timep % SECSPERDAY; 2373 rem += offset % SECSPERDAY - corr % SECSPERDAY + 3 * SECSPERDAY; 2374 dayoff = offset / SECSPERDAY - corr / SECSPERDAY + rem / SECSPERDAY - 3; 2375 rem %= SECSPERDAY; 2376 /* y = (EPOCH_YEAR 2377 + floor((tdays + dayoff) / DAYSPERREPEAT) * YEARSPERREPEAT), 2378 sans overflow. But calculate against 1570 (EPOCH_YEAR - 2379 YEARSPERREPEAT) instead of against 1970 so that things work 2380 for localtime values before 1970 when time_t is unsigned. */ 2381 dayrem = tdays % DAYSPERREPEAT; 2382 dayrem += dayoff % DAYSPERREPEAT; 2383 y = (EPOCH_YEAR - YEARSPERREPEAT 2384 + ((1 + dayoff / DAYSPERREPEAT + dayrem / DAYSPERREPEAT 2385 - ((dayrem % DAYSPERREPEAT) < 0) 2386 + tdays / DAYSPERREPEAT) 2387 * YEARSPERREPEAT)); 2388 /* idays = (tdays + dayoff) mod DAYSPERREPEAT, sans overflow. */ 2389 idays = tdays % DAYSPERREPEAT; 2390 idays += dayoff % DAYSPERREPEAT + 2 * DAYSPERREPEAT; 2391 idays %= DAYSPERREPEAT; 2392 /* Increase Y and decrease IDAYS until IDAYS is in range for Y. */ 2393 while (year_lengths[isleap(y)] <= idays) { 2394 int tdelta = idays / DAYSPERLYEAR; 2395 int_fast32_t ydelta = tdelta + !tdelta; 2396 time_t newy = y + ydelta; 2397 register int leapdays; 2398 leapdays = leaps_thru_end_of(newy - 1) - 2399 leaps_thru_end_of(y - 1); 2400 idays -= ydelta * DAYSPERNYEAR; 2401 idays -= leapdays; 2402 y = newy; 2403 } 2404 2405 #ifdef ckd_add 2406 if (ckd_add(&tmp->tm_year, y, -TM_YEAR_BASE)) { 2407 errno = EOVERFLOW; 2408 return NULL; 2409 } 2410 #else 2411 if (!TYPE_SIGNED(time_t) && y < TM_YEAR_BASE) { 2412 int signed_y = y; 2413 tmp->tm_year = signed_y - TM_YEAR_BASE; 2414 } else if ((!TYPE_SIGNED(time_t) || INT_MIN + TM_YEAR_BASE <= y) 2415 && y - TM_YEAR_BASE <= INT_MAX) 2416 tmp->tm_year = y - TM_YEAR_BASE; 2417 else { 2418 errno = EOVERFLOW; 2419 return NULL; 2420 } 2421 #endif 2422 tmp->tm_yday = idays; 2423 /* 2424 ** The "extra" mods below avoid overflow problems. 2425 */ 2426 tmp->tm_wday = (TM_WDAY_BASE 2427 + ((tmp->tm_year % DAYSPERWEEK) 2428 * (DAYSPERNYEAR % DAYSPERWEEK)) 2429 + leaps_thru_end_of(y - 1) 2430 - leaps_thru_end_of(TM_YEAR_BASE - 1) 2431 + idays); 2432 tmp->tm_wday %= DAYSPERWEEK; 2433 if (tmp->tm_wday < 0) 2434 tmp->tm_wday += DAYSPERWEEK; 2435 tmp->tm_hour = rem / SECSPERHOUR; 2436 rem %= SECSPERHOUR; 2437 tmp->tm_min = rem / SECSPERMIN; 2438 tmp->tm_sec = rem % SECSPERMIN; 2439 2440 /* Use "... ??:??:60" at the end of the localtime minute containing 2441 the second just before the positive leap second. */ 2442 tmp->tm_sec += secs_since_posleap <= tmp->tm_sec; 2443 2444 ip = mon_lengths[isleap(y)]; 2445 for (tmp->tm_mon = 0; idays >= ip[tmp->tm_mon]; ++(tmp->tm_mon)) 2446 idays -= ip[tmp->tm_mon]; 2447 tmp->tm_mday = idays + 1; 2448 tmp->tm_isdst = 0; 2449 #ifdef TM_GMTOFF 2450 tmp->TM_GMTOFF = offset; 2451 #endif /* defined TM_GMTOFF */ 2452 return tmp; 2453 } 2454 2455 /* 2456 ** Adapted from code provided by Robert Elz, who writes: 2457 ** The "best" way to do mktime I think is based on an idea of Bob 2458 ** Kridle's (so its said...) from a long time ago. 2459 ** It does a binary search of the time_t space. Since time_t's are 2460 ** just 32 bits, its a max of 32 iterations (even at 64 bits it 2461 ** would still be very reasonable). 2462 */ 2463 2464 #ifndef WRONG 2465 # define WRONG (-1) 2466 #endif /* !defined WRONG */ 2467 2468 /* 2469 ** Normalize logic courtesy Paul Eggert. 2470 */ 2471 2472 static bool 2473 increment_overflow(int *ip, int j) 2474 { 2475 #ifdef ckd_add 2476 return ckd_add(ip, *ip, j); 2477 #else 2478 register int const i = *ip; 2479 2480 /* 2481 ** If i >= 0 there can only be overflow if i + j > INT_MAX 2482 ** or if j > INT_MAX - i; given i >= 0, INT_MAX - i cannot overflow. 2483 ** If i < 0 there can only be overflow if i + j < INT_MIN 2484 ** or if j < INT_MIN - i; given i < 0, INT_MIN - i cannot overflow. 2485 */ 2486 if ((i >= 0) ? (j > INT_MAX - i) : (j < INT_MIN - i)) 2487 return true; 2488 *ip += j; 2489 return false; 2490 #endif 2491 } 2492 2493 static bool 2494 increment_overflow_64(int *ip, int_fast64_t j) 2495 { 2496 #ifdef ckd_add 2497 return ckd_add(ip, *ip, j); 2498 #else 2499 if (j < 0 ? *ip < INT_MIN - j : INT_MAX - j < *ip) 2500 return true; 2501 *ip += j; 2502 return false; 2503 #endif 2504 } 2505 2506 static bool 2507 increment_overflow_time_iinntt(time_t *tp, iinntt j) 2508 { 2509 #ifdef ckd_add 2510 return ckd_add(tp, *tp, j); 2511 #else 2512 if (j < 0 2513 ? (TYPE_SIGNED(time_t) ? *tp < TIME_T_MIN - j : *tp <= -1 - j) 2514 : TIME_T_MAX - j < *tp) 2515 return true; 2516 *tp += j; 2517 return false; 2518 #endif 2519 } 2520 2521 static bool 2522 increment_overflow_time_64(time_t *tp, int_fast64_t j) 2523 { 2524 #ifdef ckd_add 2525 return ckd_add(tp, *tp, j); 2526 #else 2527 if (j < 0 2528 ? (TYPE_SIGNED(time_t) ? *tp < TIME_T_MIN - j : *tp <= -1 - j) 2529 : TIME_T_MAX - j < *tp) 2530 return true; 2531 *tp += j; 2532 return false; 2533 #endif 2534 } 2535 2536 static bool 2537 increment_overflow_time(time_t *tp, int_fast32_2s j) 2538 { 2539 #ifdef ckd_add 2540 return ckd_add(tp, *tp, j); 2541 #else 2542 /* 2543 ** This is like 2544 ** 'if (! (TIME_T_MIN <= *tp + j && *tp + j <= TIME_T_MAX)) ...', 2545 ** except that it does the right thing even if *tp + j would overflow. 2546 */ 2547 if (! (j < 0 2548 ? (TYPE_SIGNED(time_t) ? TIME_T_MIN - j <= *tp : -1 - j < *tp) 2549 : *tp <= TIME_T_MAX - j)) 2550 return true; 2551 *tp += j; 2552 return false; 2553 #endif 2554 } 2555 2556 /* Return A - B, where both are in the range -2**31 + 1 .. 2**31 - 1. 2557 The result cannot overflow. */ 2558 static int_fast64_t 2559 utoff_diff (int_fast32_t a, int_fast32_t b) 2560 { 2561 int_fast64_t aa = a; 2562 return aa - b; 2563 } 2564 2565 static int 2566 tmcomp(register const struct tm *const atmp, 2567 register const struct tm *const btmp) 2568 { 2569 register int result; 2570 2571 if (atmp->tm_year != btmp->tm_year) 2572 return atmp->tm_year < btmp->tm_year ? -1 : 1; 2573 if ((result = (atmp->tm_mon - btmp->tm_mon)) == 0 && 2574 (result = (atmp->tm_mday - btmp->tm_mday)) == 0 && 2575 (result = (atmp->tm_hour - btmp->tm_hour)) == 0 && 2576 (result = (atmp->tm_min - btmp->tm_min)) == 0) 2577 result = atmp->tm_sec - btmp->tm_sec; 2578 return result; 2579 } 2580 2581 /* Copy to *DEST from *SRC. Copy only the members needed for mktime, 2582 as other members might not be initialized. */ 2583 static void 2584 mktmcpy(struct tm *dest, struct tm const *src) 2585 { 2586 dest->tm_sec = src->tm_sec; 2587 dest->tm_min = src->tm_min; 2588 dest->tm_hour = src->tm_hour; 2589 dest->tm_mday = src->tm_mday; 2590 dest->tm_mon = src->tm_mon; 2591 dest->tm_year = src->tm_year; 2592 dest->tm_isdst = src->tm_isdst; 2593 #if defined TM_GMTOFF && ! UNINIT_TRAP 2594 dest->TM_GMTOFF = src->TM_GMTOFF; 2595 #endif 2596 } 2597 2598 static time_t 2599 time2sub(struct tm *const tmp, 2600 struct tm *funcp(struct state const *, time_t const *, 2601 int_fast32_t, struct tm *), 2602 struct state const *sp, 2603 const int_fast32_t offset, 2604 bool *okayp, 2605 bool do_norm_secs) 2606 { 2607 register int dir; 2608 register int i, j; 2609 register time_t lo; 2610 register time_t hi; 2611 iinntt y, mday, hour, min, saved_seconds; 2612 time_t newt; 2613 time_t t; 2614 struct tm yourtm, mytm; 2615 2616 *okayp = false; 2617 mktmcpy(&yourtm, tmp); 2618 2619 min = yourtm.tm_min; 2620 if (do_norm_secs) { 2621 min += yourtm.tm_sec / SECSPERMIN; 2622 yourtm.tm_sec %= SECSPERMIN; 2623 if (yourtm.tm_sec < 0) { 2624 yourtm.tm_sec += SECSPERMIN; 2625 min--; 2626 } 2627 } 2628 2629 hour = yourtm.tm_hour; 2630 hour += min / MINSPERHOUR; 2631 yourtm.tm_min = min % MINSPERHOUR; 2632 if (yourtm.tm_min < 0) { 2633 yourtm.tm_min += MINSPERHOUR; 2634 hour--; 2635 } 2636 2637 mday = yourtm.tm_mday; 2638 mday += hour / HOURSPERDAY; 2639 yourtm.tm_hour = hour % HOURSPERDAY; 2640 if (yourtm.tm_hour < 0) { 2641 yourtm.tm_hour += HOURSPERDAY; 2642 mday--; 2643 } 2644 2645 y = yourtm.tm_year; 2646 y += yourtm.tm_mon / MONSPERYEAR; 2647 yourtm.tm_mon %= MONSPERYEAR; 2648 if (yourtm.tm_mon < 0) { 2649 yourtm.tm_mon += MONSPERYEAR; 2650 y--; 2651 } 2652 2653 /* 2654 ** Turn y into an actual year number for now. 2655 ** It is converted back to an offset from TM_YEAR_BASE later. 2656 */ 2657 y += TM_YEAR_BASE; 2658 2659 while (mday <= 0) { 2660 iinntt li = y - (yourtm.tm_mon <= 1); 2661 mday += year_lengths[isleap(li)]; 2662 y--; 2663 } 2664 while (DAYSPERLYEAR < mday) { 2665 iinntt li = y + (1 < yourtm.tm_mon); 2666 mday -= year_lengths[isleap(li)]; 2667 y++; 2668 } 2669 yourtm.tm_mday = mday; 2670 for ( ; ; ) { 2671 i = mon_lengths[isleap(y)][yourtm.tm_mon]; 2672 if (yourtm.tm_mday <= i) 2673 break; 2674 yourtm.tm_mday -= i; 2675 if (++yourtm.tm_mon >= MONSPERYEAR) { 2676 yourtm.tm_mon = 0; 2677 y++; 2678 } 2679 } 2680 #ifdef ckd_add 2681 if (ckd_add(&yourtm.tm_year, y, -TM_YEAR_BASE)) 2682 return WRONG; 2683 #else 2684 y -= TM_YEAR_BASE; 2685 if (! (INT_MIN <= y && y <= INT_MAX)) 2686 return WRONG; 2687 yourtm.tm_year = y; 2688 #endif 2689 if (yourtm.tm_sec >= 0 && yourtm.tm_sec < SECSPERMIN) 2690 saved_seconds = 0; 2691 else if (yourtm.tm_year < EPOCH_YEAR - TM_YEAR_BASE) { 2692 /* 2693 ** We can't set tm_sec to 0, because that might push the 2694 ** time below the minimum representable time. 2695 ** Set tm_sec to 59 instead. 2696 ** This assumes that the minimum representable time is 2697 ** not in the same minute that a leap second was deleted from, 2698 ** which is a safer assumption than using 58 would be. 2699 */ 2700 saved_seconds = yourtm.tm_sec; 2701 saved_seconds -= SECSPERMIN - 1; 2702 yourtm.tm_sec = SECSPERMIN - 1; 2703 } else { 2704 saved_seconds = yourtm.tm_sec; 2705 yourtm.tm_sec = 0; 2706 } 2707 /* 2708 ** Do a binary search (this works whatever time_t's type is). 2709 */ 2710 lo = TIME_T_MIN; 2711 hi = TIME_T_MAX; 2712 for ( ; ; ) { 2713 t = lo / 2 + hi / 2; 2714 if (t < lo) 2715 t = lo; 2716 else if (t > hi) 2717 t = hi; 2718 if (! funcp(sp, &t, offset, &mytm)) { 2719 /* 2720 ** Assume that t is too extreme to be represented in 2721 ** a struct tm; arrange things so that it is less 2722 ** extreme on the next pass. 2723 */ 2724 dir = (t > 0) ? 1 : -1; 2725 } else dir = tmcomp(&mytm, &yourtm); 2726 if (dir != 0) { 2727 if (t == lo) { 2728 if (t == TIME_T_MAX) 2729 return WRONG; 2730 ++t; 2731 ++lo; 2732 } else if (t == hi) { 2733 if (t == TIME_T_MIN) 2734 return WRONG; 2735 --t; 2736 --hi; 2737 } 2738 if (lo > hi) 2739 return WRONG; 2740 if (dir > 0) 2741 hi = t; 2742 else lo = t; 2743 continue; 2744 } 2745 #if defined TM_GMTOFF && ! UNINIT_TRAP 2746 if (mytm.TM_GMTOFF != yourtm.TM_GMTOFF 2747 && (yourtm.TM_GMTOFF < 0 2748 ? (-SECSPERDAY <= yourtm.TM_GMTOFF 2749 && (mytm.TM_GMTOFF <= 2750 (min(INT_FAST32_MAX, LONG_MAX) 2751 + yourtm.TM_GMTOFF))) 2752 : (yourtm.TM_GMTOFF <= SECSPERDAY 2753 && ((max(INT_FAST32_MIN, LONG_MIN) 2754 + yourtm.TM_GMTOFF) 2755 <= mytm.TM_GMTOFF)))) { 2756 /* MYTM matches YOURTM except with the wrong UT offset. 2757 YOURTM.TM_GMTOFF is plausible, so try it instead. 2758 It's OK if YOURTM.TM_GMTOFF contains uninitialized data, 2759 since the guess gets checked. */ 2760 time_t altt = t; 2761 int_fast64_t offdiff; 2762 bool v; 2763 # ifdef ckd_sub 2764 v = ckd_sub(&offdiff, mytm.TM_GMTOFF, yourtm.TM_GMTOFF); 2765 # else 2766 /* A ckd_sub approximation that is good enough here. */ 2767 v = !(-TWO_31_MINUS_1 <= yourtm.TM_GMTOFF 2768 && yourtm.TM_GMTOFF <= TWO_31_MINUS_1); 2769 if (!v) 2770 offdiff = utoff_diff(mytm.TM_GMTOFF, yourtm.TM_GMTOFF); 2771 # endif 2772 if (!v && !increment_overflow_time_64(&altt, offdiff)) { 2773 struct tm alttm; 2774 if (funcp(sp, &altt, offset, &alttm) 2775 && alttm.tm_isdst == mytm.tm_isdst 2776 && alttm.TM_GMTOFF == yourtm.TM_GMTOFF 2777 && tmcomp(&alttm, &yourtm) == 0) { 2778 t = altt; 2779 mytm = alttm; 2780 } 2781 } 2782 } 2783 #endif 2784 if (yourtm.tm_isdst < 0 || mytm.tm_isdst == yourtm.tm_isdst) 2785 break; 2786 /* 2787 ** Right time, wrong type. 2788 ** Hunt for right time, right type. 2789 ** It's okay to guess wrong since the guess 2790 ** gets checked. 2791 */ 2792 if (sp == NULL) 2793 return WRONG; 2794 for (i = sp->typecnt - 1; i >= 0; --i) { 2795 if (sp->ttis[i].tt_isdst != yourtm.tm_isdst) 2796 continue; 2797 for (j = sp->typecnt - 1; j >= 0; --j) { 2798 if (sp->ttis[j].tt_isdst == yourtm.tm_isdst) 2799 continue; 2800 if (ttunspecified(sp, j)) 2801 continue; 2802 newt = t; 2803 if (increment_overflow_time_64 2804 (&newt, 2805 utoff_diff(sp->ttis[j].tt_utoff, 2806 sp->ttis[i].tt_utoff))) 2807 continue; 2808 if (! funcp(sp, &newt, offset, &mytm)) 2809 continue; 2810 if (tmcomp(&mytm, &yourtm) != 0) 2811 continue; 2812 if (mytm.tm_isdst != yourtm.tm_isdst) 2813 continue; 2814 /* 2815 ** We have a match. 2816 */ 2817 t = newt; 2818 goto label; 2819 } 2820 } 2821 return WRONG; 2822 } 2823 label: 2824 if (increment_overflow_time_iinntt(&t, saved_seconds)) 2825 return WRONG; 2826 if (funcp(sp, &t, offset, tmp)) 2827 *okayp = true; 2828 return t; 2829 } 2830 2831 static time_t 2832 time2(struct tm * const tmp, 2833 struct tm *funcp(struct state const *, time_t const *, 2834 int_fast32_t, struct tm *), 2835 struct state const *sp, 2836 const int_fast32_t offset, 2837 bool *okayp) 2838 { 2839 time_t t; 2840 2841 /* 2842 ** First try without normalization of seconds 2843 ** (in case tm_sec contains a value associated with a leap second). 2844 ** If that fails, try with normalization of seconds. 2845 */ 2846 t = time2sub(tmp, funcp, sp, offset, okayp, false); 2847 return *okayp ? t : time2sub(tmp, funcp, sp, offset, okayp, true); 2848 } 2849 2850 static time_t 2851 time1(struct tm *const tmp, 2852 struct tm *funcp(struct state const *, time_t const *, 2853 int_fast32_t, struct tm *), 2854 struct state const *sp, 2855 const int_fast32_t offset) 2856 { 2857 register time_t t; 2858 register int samei, otheri; 2859 register int sameind, otherind; 2860 register int i; 2861 register int nseen; 2862 char seen[TZ_MAX_TYPES]; 2863 unsigned char types[TZ_MAX_TYPES]; 2864 bool okay; 2865 2866 if (tmp == NULL) { 2867 errno = EINVAL; 2868 return WRONG; 2869 } 2870 if (tmp->tm_isdst > 1) 2871 tmp->tm_isdst = 1; 2872 t = time2(tmp, funcp, sp, offset, &okay); 2873 if (okay) 2874 return t; 2875 if (tmp->tm_isdst < 0) 2876 #ifdef PCTS 2877 /* 2878 ** POSIX Conformance Test Suite code courtesy Grant Sullivan. 2879 */ 2880 tmp->tm_isdst = 0; /* reset to std and try again */ 2881 #else 2882 return t; 2883 #endif /* !defined PCTS */ 2884 /* 2885 ** We're supposed to assume that somebody took a time of one type 2886 ** and did some math on it that yielded a "struct tm" that's bad. 2887 ** We try to divine the type they started from and adjust to the 2888 ** type they need. 2889 */ 2890 if (sp == NULL) 2891 return WRONG; 2892 for (i = 0; i < sp->typecnt; ++i) 2893 seen[i] = false; 2894 nseen = 0; 2895 for (i = sp->timecnt - 1; i >= 0; --i) 2896 if (!seen[sp->types[i]] && !ttunspecified(sp, sp->types[i])) { 2897 seen[sp->types[i]] = true; 2898 types[nseen++] = sp->types[i]; 2899 } 2900 for (sameind = 0; sameind < nseen; ++sameind) { 2901 samei = types[sameind]; 2902 if (sp->ttis[samei].tt_isdst != tmp->tm_isdst) 2903 continue; 2904 for (otherind = 0; otherind < nseen; ++otherind) { 2905 otheri = types[otherind]; 2906 if (sp->ttis[otheri].tt_isdst != tmp->tm_isdst) { 2907 int sec = tmp->tm_sec; 2908 if (!increment_overflow_64 2909 (&tmp->tm_sec, 2910 utoff_diff(sp->ttis[otheri].tt_utoff, 2911 sp->ttis[samei].tt_utoff))) { 2912 tmp->tm_isdst = !tmp->tm_isdst; 2913 t = time2(tmp, funcp, sp, offset, &okay); 2914 if (okay) 2915 return t; 2916 tmp->tm_isdst = !tmp->tm_isdst; 2917 } 2918 tmp->tm_sec = sec; 2919 } 2920 } 2921 } 2922 return WRONG; 2923 } 2924 2925 #if !defined TM_GMTOFF || !USE_TIMEX_T 2926 2927 static time_t 2928 mktime_tzname(struct state *sp, struct tm *tmp, bool setname) 2929 { 2930 if (sp) 2931 return time1(tmp, localsub, sp, setname); 2932 else { 2933 gmtcheck(); 2934 return time1(tmp, gmtsub, gmtptr, 0); 2935 } 2936 } 2937 2938 # if USE_TIMEX_T 2939 static 2940 # endif 2941 time_t 2942 mktime(struct tm *tmp) 2943 { 2944 monotime_t now = get_monotonic_time(); 2945 time_t t; 2946 int err = lock(); 2947 if (0 < err) { 2948 errno = err; 2949 return -1; 2950 } 2951 tzset_unlocked(!err, false, now); 2952 t = mktime_tzname(lclptr, tmp, true); 2953 unlock(!err); 2954 return t; 2955 } 2956 2957 #endif 2958 2959 #if NETBSD_INSPIRED && !USE_TIMEX_T 2960 time_t 2961 mktime_z(struct state *restrict sp, struct tm *restrict tmp) 2962 { 2963 return mktime_tzname(sp, tmp, false); 2964 } 2965 #endif 2966 2967 #if STD_INSPIRED && !USE_TIMEX_T 2968 /* This function is obsolescent and may disappear in future releases. 2969 Callers can instead use mktime. */ 2970 time_t 2971 timelocal(struct tm *tmp) 2972 { 2973 if (tmp != NULL) 2974 tmp->tm_isdst = -1; /* in case it wasn't initialized */ 2975 return mktime(tmp); 2976 } 2977 #endif 2978 2979 #if defined TM_GMTOFF || !USE_TIMEX_T 2980 2981 # ifndef EXTERN_TIMEOFF 2982 # ifndef timeoff 2983 # define timeoff my_timeoff /* Don't collide with OpenBSD 7.4 <time.h>. */ 2984 # endif 2985 # define EXTERN_TIMEOFF static 2986 # endif 2987 2988 /* This function is obsolescent and may disappear in future releases. 2989 Callers can instead use mktime_z with a fixed-offset zone. */ 2990 EXTERN_TIMEOFF time_t 2991 timeoff(struct tm *tmp, long offset) 2992 { 2993 if (tmp) 2994 tmp->tm_isdst = 0; 2995 gmtcheck(); 2996 return time1(tmp, gmtsub, gmtptr, offset); 2997 } 2998 #endif 2999 3000 #if !USE_TIMEX_T 3001 time_t 3002 timegm(struct tm *tmp) 3003 { 3004 time_t t; 3005 struct tm tmcpy; 3006 mktmcpy(&tmcpy, tmp); 3007 tmcpy.tm_wday = -1; 3008 t = timeoff(&tmcpy, 0); 3009 if (0 <= tmcpy.tm_wday) 3010 *tmp = tmcpy; 3011 return t; 3012 } 3013 #endif 3014 3015 static int_fast32_2s 3016 leapcorr(struct state const *sp, time_t t) 3017 { 3018 register int i; 3019 3020 i = leapcount(sp); 3021 while (--i >= 0) { 3022 struct lsinfo ls = lsinfo(sp, i); 3023 if (ls.ls_trans <= t) 3024 return ls.ls_corr; 3025 } 3026 return 0; 3027 } 3028 3029 /* 3030 ** XXX--is the below the right way to conditionalize?? 3031 */ 3032 3033 #if !USE_TIMEX_T 3034 # if STD_INSPIRED 3035 3036 static bool 3037 decrement_overflow_time(time_t *tp, int_fast32_2s j) 3038 { 3039 #ifdef ckd_sub 3040 return ckd_sub(tp, *tp, j); 3041 #else 3042 if (! (j < 0 3043 ? *tp <= TIME_T_MAX + j 3044 : (TYPE_SIGNED(time_t) ? TIME_T_MIN + j <= *tp : j <= *tp))) 3045 return true; 3046 *tp -= j; 3047 return false; 3048 #endif 3049 } 3050 3051 /* NETBSD_INSPIRED_EXTERN functions are exported to callers if 3052 NETBSD_INSPIRED is defined, and are private otherwise. */ 3053 # if NETBSD_INSPIRED 3054 # define NETBSD_INSPIRED_EXTERN 3055 # else 3056 # define NETBSD_INSPIRED_EXTERN static 3057 # endif 3058 3059 /* 3060 ** IEEE Std 1003.1 (POSIX) says that 536457599 3061 ** shall correspond to "Wed Dec 31 23:59:59 UTC 1986", which 3062 ** is not the case if we are accounting for leap seconds. 3063 ** So, we provide the following conversion routines for use 3064 ** when exchanging timestamps with POSIX conforming systems. 3065 */ 3066 3067 NETBSD_INSPIRED_EXTERN time_t 3068 time2posix_z(struct state *sp, time_t t) 3069 { 3070 if (decrement_overflow_time(&t, leapcorr(sp, t))) { 3071 /* Overflow near maximum time_t value with negative correction. 3072 This can happen with unrealistic-but-valid TZif files. */ 3073 errno = EOVERFLOW; 3074 return -1; 3075 } 3076 return t; 3077 } 3078 3079 time_t 3080 time2posix(time_t t) 3081 { 3082 monotime_t now = get_monotonic_time(); 3083 int err = lock(); 3084 if (0 < err) { 3085 errno = err; 3086 return -1; 3087 } 3088 if (0 <= tz_change_interval || !lcl_is_set) 3089 tzset_unlocked(!err, false, now); 3090 if (lclptr) 3091 t = time2posix_z(lclptr, t); 3092 unlock(!err); 3093 return t; 3094 } 3095 3096 NETBSD_INSPIRED_EXTERN time_t 3097 posix2time_z(struct state *sp, time_t t) 3098 { 3099 int i; 3100 for (i = leapcount(sp); 0 <= --i; ) { 3101 struct lsinfo ls = lsinfo(sp, i); 3102 time_t t_corr = t; 3103 3104 if (increment_overflow_time(&t_corr, ls.ls_corr)) { 3105 if (0 <= ls.ls_corr) { 3106 /* Overflow near maximum time_t value with positive correction. 3107 This can happen with ordinary TZif files with leap seconds. */ 3108 errno = EOVERFLOW; 3109 return -1; 3110 } else { 3111 /* A negative correction overflowed, so keep going. 3112 This can happen with unrealistic-but-valid TZif files. */ 3113 } 3114 } else if (ls.ls_trans <= t_corr) 3115 return (t_corr 3116 - (ls.ls_trans == t_corr 3117 && (i == 0 ? 0 : lsinfo(sp, i - 1).ls_corr) < ls.ls_corr)); 3118 } 3119 return t; 3120 } 3121 3122 time_t 3123 posix2time(time_t t) 3124 { 3125 monotime_t now = get_monotonic_time(); 3126 int err = lock(); 3127 if (0 < err) { 3128 errno = err; 3129 return -1; 3130 } 3131 if (0 <= tz_change_interval || !lcl_is_set) 3132 tzset_unlocked(!err, false, now); 3133 if (lclptr) 3134 t = posix2time_z(lclptr, t); 3135 unlock(!err); 3136 return t; 3137 } 3138 3139 # endif /* STD_INSPIRED */ 3140 3141 # if TZ_TIME_T 3142 3143 # if !USG_COMPAT 3144 # define timezone 0 3145 # endif 3146 3147 /* Convert from the underlying system's time_t to the ersatz time_tz, 3148 which is called 'time_t' in this file. Typically, this merely 3149 converts the time's integer width. On some platforms, the system 3150 time is local time not UT, or uses some epoch other than the POSIX 3151 epoch. 3152 3153 Although this code appears to define a function named 'time' that 3154 returns time_t, the macros in private.h cause this code to actually 3155 define a function named 'tz_time' that returns tz_time_t. The call 3156 to sys_time invokes the underlying system's 'time' function. */ 3157 3158 time_t 3159 time(time_t *p) 3160 { 3161 time_t r = sys_time(NULL); 3162 if (r != (time_t) -1) { 3163 iinntt offset = EPOCH_LOCAL ? timezone : 0; 3164 if (offset < IINNTT_MIN + EPOCH_OFFSET 3165 || increment_overflow_time_iinntt(&r, offset - EPOCH_OFFSET)) { 3166 errno = EOVERFLOW; 3167 r = -1; 3168 } 3169 } 3170 if (p) 3171 *p = r; 3172 return r; 3173 } 3174 3175 # endif 3176 #endif 3177