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