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