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