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 tzloadflags &= ~TZLOAD_FROMENV; 619 } 620 621 if (name[0] == ':') 622 ++name; 623 #ifndef __FreeBSD__ 624 #ifdef SUPPRESS_TZDIR 625 /* Do not prepend TZDIR. This is intended for specialized 626 applications only, due to its security implications. */ 627 doaccess = true; 628 #else 629 doaccess = name[0] == '/'; 630 #endif 631 if (!doaccess) { 632 char const *dot; 633 if (sizeof lsp->fullname - sizeof tzdirslash <= strlen(name)) 634 return ENAMETOOLONG; 635 636 /* Create a string "TZDIR/NAME". Using sprintf here 637 would pull in stdio (and would fail if the 638 resulting string length exceeded INT_MAX!). */ 639 memcpy(lsp->fullname, tzdirslash, sizeof tzdirslash); 640 strcpy(lsp->fullname + sizeof tzdirslash, name); 641 642 /* Set doaccess if NAME contains a ".." file name 643 component, as such a name could read a file outside 644 the TZDIR virtual subtree. */ 645 for (dot = name; (dot = strchr(dot, '.')); dot++) 646 if ((dot == name || dot[-1] == '/') && dot[1] == '.' 647 && (dot[2] == '/' || !dot[2])) { 648 doaccess = true; 649 break; 650 } 651 652 name = lsp->fullname; 653 } 654 if (doaccess && (tzloadflags & TZLOAD_FROMENV)) { 655 /* Check for security violations and for devices whose mere 656 opening could have unwanted side effects. Although these 657 checks are racy, they're better than nothing and there is 658 no portable way to fix the races. */ 659 if (access(name, R_OK) < 0) 660 return errno; 661 #ifdef S_ISREG 662 { 663 struct stat st; 664 if (stat(name, &st) < 0) 665 return errno; 666 if (!S_ISREG(st.st_mode)) 667 return EINVAL; 668 } 669 #endif 670 } 671 fid = _open(name, (O_RDONLY | O_BINARY | O_CLOEXEC | O_CLOFORK 672 | O_IGNORE_CTTY | O_NOCTTY)); 673 #else /* __FreeBSD__ */ 674 if ((tzloadflags & TZLOAD_FROMENV) && strcmp(name, TZDEFAULT) == 0) 675 tzloadflags &= ~TZLOAD_FROMENV; 676 relname = name; 677 if (strncmp(relname, TZDIR "/", strlen(TZDIR) + 1) == 0) 678 relname += strlen(TZDIR) + 1; 679 dd = _open(TZDIR, O_DIRECTORY | O_RDONLY); 680 if ((tzloadflags & TZLOAD_FROMENV) && issetugid()) { 681 if (dd < 0) 682 return errno; 683 if (fstatat(dd, name, &sb, AT_RESOLVE_BENEATH) < 0) { 684 fid = -1; 685 } else if (!S_ISREG(sb.st_mode)) { 686 fid = -1; 687 errno = EINVAL; 688 } else { 689 fid = _openat(dd, relname, O_RDONLY | O_BINARY, AT_RESOLVE_BENEATH); 690 } 691 } else { 692 if (dd < 0) { 693 relname = name; 694 dd = AT_FDCWD; 695 } 696 fid = _openat(dd, relname, O_RDONLY | O_BINARY, 0); 697 } 698 if (dd != AT_FDCWD && dd >= 0) { 699 serrno = errno; 700 _close(dd); 701 errno = serrno; 702 } 703 #endif /* __FreeBSD__ */ 704 if (fid < 0) 705 return errno; 706 707 #ifdef DETECT_TZ_CHANGES 708 if (tzloadflags) { 709 /* 710 * Detect if the timezone file has changed. Check tzloadflags 711 * to ignore TZDEFRULES; the tzfile_changed() function can only 712 * keep state for a single file. 713 */ 714 switch (tzfile_changed(name, fid)) { 715 case -1: 716 serrno = errno; 717 _close(fid); 718 return serrno; 719 case 0: 720 _close(fid); 721 return 0; 722 case 1: 723 break; 724 } 725 } 726 #endif /* DETECT_TZ_CHANGES */ 727 nread = _read(fid, up->buf, sizeof up->buf); 728 if (nread < tzheadsize) { 729 int err = nread < 0 ? errno : EINVAL; 730 _close(fid); 731 return err; 732 } 733 if (_close(fid) < 0) 734 return errno; 735 for (stored = 4; stored <= 8; stored *= 2) { 736 char version = up->tzhead.tzh_version[0]; 737 bool skip_datablock = stored == 4 && version; 738 int_fast32_t datablock_size; 739 int_fast32_t ttisstdcnt = detzcode(up->tzhead.tzh_ttisstdcnt); 740 int_fast32_t ttisutcnt = detzcode(up->tzhead.tzh_ttisutcnt); 741 int_fast64_t prevtr = -1; 742 int_fast32_t prevcorr; 743 int_fast32_t leapcnt = detzcode(up->tzhead.tzh_leapcnt); 744 int_fast32_t timecnt = detzcode(up->tzhead.tzh_timecnt); 745 int_fast32_t typecnt = detzcode(up->tzhead.tzh_typecnt); 746 int_fast32_t charcnt = detzcode(up->tzhead.tzh_charcnt); 747 char const *p = up->buf + tzheadsize; 748 /* Although tzfile(5) currently requires typecnt to be nonzero, 749 support future formats that may allow zero typecnt 750 in files that have a TZ string and no transitions. */ 751 if (! (0 <= leapcnt && leapcnt < TZ_MAX_LEAPS 752 && 0 <= typecnt && typecnt < TZ_MAX_TYPES 753 && 0 <= timecnt && timecnt < TZ_MAX_TIMES 754 && 0 <= charcnt && charcnt < TZ_MAX_CHARS 755 && 0 <= ttisstdcnt && ttisstdcnt < TZ_MAX_TYPES 756 && 0 <= ttisutcnt && ttisutcnt < TZ_MAX_TYPES)) 757 return EINVAL; 758 datablock_size 759 = (timecnt * stored /* ats */ 760 + timecnt /* types */ 761 + typecnt * 6 /* ttinfos */ 762 + charcnt /* chars */ 763 + leapcnt * (stored + 4) /* lsinfos */ 764 + ttisstdcnt /* ttisstds */ 765 + ttisutcnt); /* ttisuts */ 766 if (nread < tzheadsize + datablock_size) 767 return EINVAL; 768 if (skip_datablock) 769 p += datablock_size; 770 else { 771 if (! ((ttisstdcnt == typecnt || ttisstdcnt == 0) 772 && (ttisutcnt == typecnt || ttisutcnt == 0))) 773 return EINVAL; 774 775 sp->leapcnt = leapcnt; 776 sp->timecnt = timecnt; 777 sp->typecnt = typecnt; 778 sp->charcnt = charcnt; 779 780 /* Read transitions, discarding those out of time_t range. 781 But pretend the last transition before TIME_T_MIN 782 occurred at TIME_T_MIN. */ 783 timecnt = 0; 784 for (i = 0; i < sp->timecnt; ++i) { 785 int_fast64_t at 786 = stored == 4 ? detzcode(p) : detzcode64(p); 787 sp->types[i] = at <= TIME_T_MAX; 788 if (sp->types[i]) { 789 time_t attime 790 = ((TYPE_SIGNED(time_t) ? at < TIME_T_MIN : at < 0) 791 ? TIME_T_MIN : at); 792 if (timecnt && attime <= sp->ats[timecnt - 1]) { 793 if (attime < sp->ats[timecnt - 1]) 794 return EINVAL; 795 sp->types[i - 1] = 0; 796 timecnt--; 797 } 798 sp->ats[timecnt++] = attime; 799 } 800 p += stored; 801 } 802 803 timecnt = 0; 804 for (i = 0; i < sp->timecnt; ++i) { 805 unsigned char typ = *p++; 806 if (sp->typecnt <= typ) 807 return EINVAL; 808 if (sp->types[i]) 809 sp->types[timecnt++] = typ; 810 } 811 sp->timecnt = timecnt; 812 for (i = 0; i < sp->typecnt; ++i) { 813 register struct ttinfo * ttisp; 814 unsigned char isdst, desigidx; 815 816 ttisp = &sp->ttis[i]; 817 ttisp->tt_utoff = detzcode(p); 818 p += 4; 819 isdst = *p++; 820 if (! (isdst < 2)) 821 return EINVAL; 822 ttisp->tt_isdst = isdst; 823 desigidx = *p++; 824 if (! (desigidx < sp->charcnt)) 825 return EINVAL; 826 ttisp->tt_desigidx = desigidx; 827 } 828 for (i = 0; i < sp->charcnt; ++i) 829 sp->chars[i] = *p++; 830 /* Ensure '\0'-terminated, and make it safe to call 831 ttunspecified later. */ 832 memset(&sp->chars[i], 0, CHARS_EXTRA); 833 834 /* Read leap seconds, discarding those out of time_t range. */ 835 leapcnt = 0; 836 for (i = 0; i < sp->leapcnt; ++i) { 837 int_fast64_t tr = stored == 4 ? detzcode(p) : detzcode64(p); 838 int_fast32_t corr = detzcode(p + stored); 839 p += stored + 4; 840 841 /* Leap seconds cannot occur before the Epoch, 842 or out of order. */ 843 if (tr <= prevtr) 844 return EINVAL; 845 846 /* To avoid other botches in this code, each leap second's 847 correction must differ from the previous one's by 1 848 second or less, except that the first correction can be 849 any value; these requirements are more generous than 850 RFC 9636, to allow future RFC extensions. */ 851 if (! (i == 0 852 || (prevcorr < corr 853 ? corr == prevcorr + 1 854 : (corr == prevcorr 855 || corr == prevcorr - 1)))) 856 return EINVAL; 857 prevtr = tr; 858 prevcorr = corr; 859 860 if (tr <= TIME_T_MAX) { 861 sp->lsis[leapcnt].ls_trans = tr; 862 sp->lsis[leapcnt].ls_corr = corr; 863 leapcnt++; 864 } 865 } 866 sp->leapcnt = leapcnt; 867 868 for (i = 0; i < sp->typecnt; ++i) { 869 register struct ttinfo * ttisp; 870 871 ttisp = &sp->ttis[i]; 872 if (ttisstdcnt == 0) 873 ttisp->tt_ttisstd = false; 874 else { 875 if (*p != true && *p != false) 876 return EINVAL; 877 ttisp->tt_ttisstd = *p++; 878 } 879 } 880 for (i = 0; i < sp->typecnt; ++i) { 881 register struct ttinfo * ttisp; 882 883 ttisp = &sp->ttis[i]; 884 if (ttisutcnt == 0) 885 ttisp->tt_ttisut = false; 886 else { 887 if (*p != true && *p != false) 888 return EINVAL; 889 ttisp->tt_ttisut = *p++; 890 } 891 } 892 } 893 894 nread -= p - up->buf; 895 memmove(up->buf, p, nread); 896 897 /* If this is an old file, we're done. */ 898 if (!version) 899 break; 900 } 901 if ((tzloadflags & TZLOAD_TZSTRING) && nread > 2 && 902 up->buf[0] == '\n' && up->buf[nread - 1] == '\n' && 903 sp->typecnt + 2 <= TZ_MAX_TYPES) { 904 struct state *ts = &lsp->u.st; 905 906 up->buf[nread - 1] = '\0'; 907 if (tzparse(&up->buf[1], ts, sp)) { 908 909 /* Attempt to reuse existing abbreviations. 910 Without this, America/Anchorage would be right on 911 the edge after 2037 when TZ_MAX_CHARS is 50, as 912 sp->charcnt equals 40 (for LMT AST AWT APT AHST 913 AHDT YST AKDT AKST) and ts->charcnt equals 10 914 (for AKST AKDT). Reusing means sp->charcnt can 915 stay 40 in this example. */ 916 int gotabbr = 0; 917 int charcnt = sp->charcnt; 918 for (i = 0; i < ts->typecnt; i++) { 919 char *tsabbr = ts->chars + ts->ttis[i].tt_desigidx; 920 int j; 921 for (j = 0; j < charcnt; j++) 922 if (strcmp(sp->chars + j, tsabbr) == 0) { 923 ts->ttis[i].tt_desigidx = j; 924 gotabbr++; 925 break; 926 } 927 if (! (j < charcnt)) { 928 int tsabbrlen = strlen(tsabbr); 929 if (j + tsabbrlen < TZ_MAX_CHARS) { 930 strcpy(sp->chars + j, tsabbr); 931 charcnt = j + tsabbrlen + 1; 932 ts->ttis[i].tt_desigidx = j; 933 gotabbr++; 934 } 935 } 936 } 937 if (gotabbr == ts->typecnt) { 938 sp->charcnt = charcnt; 939 940 /* Ignore any trailing, no-op transitions generated 941 by zic as they don't help here and can run afoul 942 of bugs in zic 2016j or earlier. */ 943 while (1 < sp->timecnt 944 && (sp->types[sp->timecnt - 1] 945 == sp->types[sp->timecnt - 2])) 946 sp->timecnt--; 947 948 sp->goahead = ts->goahead; 949 950 for (i = 0; i < ts->timecnt; i++) { 951 time_t t = ts->ats[i]; 952 if (increment_overflow_time(&t, leapcorr(sp, t)) 953 || (0 < sp->timecnt 954 && t <= sp->ats[sp->timecnt - 1])) 955 continue; 956 if (TZ_MAX_TIMES <= sp->timecnt) { 957 sp->goahead = false; 958 break; 959 } 960 sp->ats[sp->timecnt] = t; 961 sp->types[sp->timecnt] = (sp->typecnt 962 + ts->types[i]); 963 sp->timecnt++; 964 } 965 for (i = 0; i < ts->typecnt; i++) 966 sp->ttis[sp->typecnt++] = ts->ttis[i]; 967 } 968 } 969 } 970 if (sp->typecnt == 0) 971 return EINVAL; 972 973 return 0; 974 } 975 976 /* Load tz data from the file named NAME into *SP. Respect TZLOADFLAGS. 977 Return 0 on success, an errno value on failure. */ 978 static int 979 tzload(char const *name, struct state *sp, char tzloadflags) 980 { 981 #ifdef ALL_STATE 982 union local_storage *lsp = malloc(sizeof *lsp); 983 if (!lsp) { 984 return HAVE_MALLOC_ERRNO ? errno : ENOMEM; 985 } else { 986 int err = tzloadbody(name, sp, tzloadflags, lsp); 987 free(lsp); 988 return err; 989 } 990 #else 991 union local_storage ls; 992 return tzloadbody(name, sp, tzloadflags, &ls); 993 #endif 994 } 995 996 static const int mon_lengths[2][MONSPERYEAR] = { 997 { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }, 998 { 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 } 999 }; 1000 1001 static const int year_lengths[2] = { 1002 DAYSPERNYEAR, DAYSPERLYEAR 1003 }; 1004 1005 /* Is C an ASCII digit? */ 1006 static bool 1007 is_digit(char c) 1008 { 1009 return '0' <= c && c <= '9'; 1010 } 1011 1012 /* 1013 ** Given a pointer into a timezone string, scan until a character that is not 1014 ** a valid character in a time zone abbreviation is found. 1015 ** Return a pointer to that character. 1016 */ 1017 1018 ATTRIBUTE_PURE_114833 static const char * 1019 getzname(register const char *strp) 1020 { 1021 register char c; 1022 1023 while ((c = *strp) != '\0' && !is_digit(c) && c != ',' && c != '-' && 1024 c != '+') 1025 ++strp; 1026 return strp; 1027 } 1028 1029 /* 1030 ** Given a pointer into an extended timezone string, scan until the ending 1031 ** delimiter of the time zone abbreviation is located. 1032 ** Return a pointer to the delimiter. 1033 ** 1034 ** As with getzname above, the legal character set is actually quite 1035 ** restricted, with other characters producing undefined results. 1036 ** We don't do any checking here; checking is done later in common-case code. 1037 */ 1038 1039 ATTRIBUTE_PURE_114833 static const char * 1040 getqzname(register const char *strp, const int delim) 1041 { 1042 register int c; 1043 1044 while ((c = *strp) != '\0' && c != delim) 1045 ++strp; 1046 return strp; 1047 } 1048 1049 /* 1050 ** Given a pointer into a timezone string, extract a number from that string. 1051 ** Check that the number is within a specified range; if it is not, return 1052 ** NULL. 1053 ** Otherwise, return a pointer to the first character not part of the number. 1054 */ 1055 1056 static const char * 1057 getnum(register const char *strp, int *const nump, const int min, const int max) 1058 { 1059 register char c; 1060 register int num; 1061 1062 if (strp == NULL || !is_digit(c = *strp)) 1063 return NULL; 1064 num = 0; 1065 do { 1066 num = num * 10 + (c - '0'); 1067 if (num > max) 1068 return NULL; /* illegal value */ 1069 c = *++strp; 1070 } while (is_digit(c)); 1071 if (num < min) 1072 return NULL; /* illegal value */ 1073 *nump = num; 1074 return strp; 1075 } 1076 1077 /* 1078 ** Given a pointer into a timezone string, extract a number of seconds, 1079 ** in 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 number 1082 ** of seconds. 1083 */ 1084 1085 static const char * 1086 getsecs(register const char *strp, int_fast32_t *const secsp) 1087 { 1088 int num; 1089 int_fast32_t secsperhour = SECSPERHOUR; 1090 1091 /* 1092 ** 'HOURSPERDAY * DAYSPERWEEK - 1' allows quasi-POSIX rules like 1093 ** "M10.4.6/26", which does not conform to POSIX, 1094 ** but which specifies the equivalent of 1095 ** "02:00 on the first Sunday on or after 23 Oct". 1096 */ 1097 strp = getnum(strp, &num, 0, HOURSPERDAY * DAYSPERWEEK - 1); 1098 if (strp == NULL) 1099 return NULL; 1100 *secsp = num * secsperhour; 1101 if (*strp == ':') { 1102 ++strp; 1103 strp = getnum(strp, &num, 0, MINSPERHOUR - 1); 1104 if (strp == NULL) 1105 return NULL; 1106 *secsp += num * SECSPERMIN; 1107 if (*strp == ':') { 1108 ++strp; 1109 /* 'SECSPERMIN' allows for leap seconds. */ 1110 strp = getnum(strp, &num, 0, SECSPERMIN); 1111 if (strp == NULL) 1112 return NULL; 1113 *secsp += num; 1114 } 1115 } 1116 return strp; 1117 } 1118 1119 /* 1120 ** Given a pointer into a timezone string, extract an offset, in 1121 ** [+-]hh[:mm[:ss]] form, from the string. 1122 ** If any error occurs, return NULL. 1123 ** Otherwise, return a pointer to the first character not part of the time. 1124 */ 1125 1126 static const char * 1127 getoffset(register const char *strp, int_fast32_t *const offsetp) 1128 { 1129 register bool neg = false; 1130 1131 if (*strp == '-') { 1132 neg = true; 1133 ++strp; 1134 } else if (*strp == '+') 1135 ++strp; 1136 strp = getsecs(strp, offsetp); 1137 if (strp == NULL) 1138 return NULL; /* illegal time */ 1139 if (neg) 1140 *offsetp = -*offsetp; 1141 return strp; 1142 } 1143 1144 /* 1145 ** Given a pointer into a timezone string, extract a rule in the form 1146 ** date[/time]. See POSIX Base Definitions section 8.3 variable TZ 1147 ** for the format of "date" and "time". 1148 ** If a valid rule is not found, return NULL. 1149 ** Otherwise, return a pointer to the first character not part of the rule. 1150 */ 1151 1152 static const char * 1153 getrule(const char *strp, register struct rule *const rulep) 1154 { 1155 if (*strp == 'J') { 1156 /* 1157 ** Julian day. 1158 */ 1159 rulep->r_type = JULIAN_DAY; 1160 ++strp; 1161 strp = getnum(strp, &rulep->r_day, 1, DAYSPERNYEAR); 1162 } else if (*strp == 'M') { 1163 /* 1164 ** Month, week, day. 1165 */ 1166 rulep->r_type = MONTH_NTH_DAY_OF_WEEK; 1167 ++strp; 1168 strp = getnum(strp, &rulep->r_mon, 1, MONSPERYEAR); 1169 if (strp == NULL) 1170 return NULL; 1171 if (*strp++ != '.') 1172 return NULL; 1173 strp = getnum(strp, &rulep->r_week, 1, 5); 1174 if (strp == NULL) 1175 return NULL; 1176 if (*strp++ != '.') 1177 return NULL; 1178 strp = getnum(strp, &rulep->r_day, 0, DAYSPERWEEK - 1); 1179 } else if (is_digit(*strp)) { 1180 /* 1181 ** Day of year. 1182 */ 1183 rulep->r_type = DAY_OF_YEAR; 1184 strp = getnum(strp, &rulep->r_day, 0, DAYSPERLYEAR - 1); 1185 } else return NULL; /* invalid format */ 1186 if (strp == NULL) 1187 return NULL; 1188 if (*strp == '/') { 1189 /* 1190 ** Time specified. 1191 */ 1192 ++strp; 1193 strp = getoffset(strp, &rulep->r_time); 1194 } else rulep->r_time = 2 * SECSPERHOUR; /* default = 2:00:00 */ 1195 return strp; 1196 } 1197 1198 /* 1199 ** Given a year, a rule, and the offset from UT at the time that rule takes 1200 ** effect, calculate the year-relative time that rule takes effect. 1201 */ 1202 1203 static int_fast32_t 1204 transtime(const int year, register const struct rule *const rulep, 1205 const int_fast32_t offset) 1206 { 1207 register bool leapyear; 1208 register int_fast32_t value; 1209 register int i; 1210 int d, m1, yy0, yy1, yy2, dow; 1211 1212 leapyear = isleap(year); 1213 switch (rulep->r_type) { 1214 1215 case JULIAN_DAY: 1216 /* 1217 ** Jn - Julian day, 1 == January 1, 60 == March 1 even in leap 1218 ** years. 1219 ** In non-leap years, or if the day number is 59 or less, just 1220 ** add SECSPERDAY times the day number-1 to the time of 1221 ** January 1, midnight, to get the day. 1222 */ 1223 value = (rulep->r_day - 1) * SECSPERDAY; 1224 if (leapyear && rulep->r_day >= 60) 1225 value += SECSPERDAY; 1226 break; 1227 1228 case DAY_OF_YEAR: 1229 /* 1230 ** n - day of year. 1231 ** Just add SECSPERDAY times the day number to the time of 1232 ** January 1, midnight, to get the day. 1233 */ 1234 value = rulep->r_day * SECSPERDAY; 1235 break; 1236 1237 case MONTH_NTH_DAY_OF_WEEK: 1238 /* 1239 ** Mm.n.d - nth "dth day" of month m. 1240 */ 1241 1242 /* 1243 ** Use Zeller's Congruence to get day-of-week of first day of 1244 ** month. 1245 */ 1246 m1 = (rulep->r_mon + 9) % 12 + 1; 1247 yy0 = (rulep->r_mon <= 2) ? (year - 1) : year; 1248 yy1 = yy0 / 100; 1249 yy2 = yy0 % 100; 1250 dow = ((26 * m1 - 2) / 10 + 1251 1 + yy2 + yy2 / 4 + yy1 / 4 - 2 * yy1) % 7; 1252 if (dow < 0) 1253 dow += DAYSPERWEEK; 1254 1255 /* 1256 ** "dow" is the day-of-week of the first day of the month. Get 1257 ** the day-of-month (zero-origin) of the first "dow" day of the 1258 ** month. 1259 */ 1260 d = rulep->r_day - dow; 1261 if (d < 0) 1262 d += DAYSPERWEEK; 1263 for (i = 1; i < rulep->r_week; ++i) { 1264 if (d + DAYSPERWEEK >= 1265 mon_lengths[leapyear][rulep->r_mon - 1]) 1266 break; 1267 d += DAYSPERWEEK; 1268 } 1269 1270 /* 1271 ** "d" is the day-of-month (zero-origin) of the day we want. 1272 */ 1273 value = d * SECSPERDAY; 1274 for (i = 0; i < rulep->r_mon - 1; ++i) 1275 value += mon_lengths[leapyear][i] * SECSPERDAY; 1276 break; 1277 1278 default: unreachable(); 1279 } 1280 1281 /* 1282 ** "value" is the year-relative time of 00:00:00 UT on the day in 1283 ** question. To get the year-relative time of the specified local 1284 ** time on that day, add the transition time and the current offset 1285 ** from UT. 1286 */ 1287 return value + rulep->r_time + offset; 1288 } 1289 1290 /* 1291 ** Given a POSIX.1 proleptic TZ string, fill in the rule tables as 1292 ** appropriate. 1293 */ 1294 1295 static bool 1296 tzparse(const char *name, struct state *sp, struct state const *basep) 1297 { 1298 const char * stdname; 1299 const char * dstname; 1300 int_fast32_t stdoffset; 1301 int_fast32_t dstoffset; 1302 register char * cp; 1303 register bool load_ok; 1304 ptrdiff_t stdlen, dstlen, charcnt; 1305 time_t atlo = TIME_T_MIN, leaplo = TIME_T_MIN; 1306 1307 stdname = name; 1308 if (*name == '<') { 1309 name++; 1310 stdname = name; 1311 name = getqzname(name, '>'); 1312 if (*name != '>') 1313 return false; 1314 stdlen = name - stdname; 1315 name++; 1316 } else { 1317 name = getzname(name); 1318 stdlen = name - stdname; 1319 } 1320 if (! (0 < stdlen && stdlen <= TZNAME_MAXIMUM)) 1321 return false; 1322 name = getoffset(name, &stdoffset); 1323 if (name == NULL) 1324 return false; 1325 charcnt = stdlen + 1; 1326 if (basep) { 1327 if (0 < basep->timecnt) 1328 atlo = basep->ats[basep->timecnt - 1]; 1329 load_ok = false; 1330 sp->leapcnt = basep->leapcnt; 1331 memcpy(sp->lsis, basep->lsis, sp->leapcnt * sizeof *sp->lsis); 1332 } else { 1333 load_ok = tzload(TZDEFRULES, sp, 0) == 0; 1334 if (!load_ok) 1335 sp->leapcnt = 0; /* So, we're off a little. */ 1336 } 1337 if (0 < sp->leapcnt) 1338 leaplo = sp->lsis[sp->leapcnt - 1].ls_trans; 1339 sp->goback = sp->goahead = false; 1340 if (*name != '\0') { 1341 if (*name == '<') { 1342 dstname = ++name; 1343 name = getqzname(name, '>'); 1344 if (*name != '>') 1345 return false; 1346 dstlen = name - dstname; 1347 name++; 1348 } else { 1349 dstname = name; 1350 name = getzname(name); 1351 dstlen = name - dstname; /* length of DST abbr. */ 1352 } 1353 if (! (0 < dstlen && dstlen <= TZNAME_MAXIMUM)) 1354 return false; 1355 charcnt += dstlen + 1; 1356 if (*name != '\0' && *name != ',' && *name != ';') { 1357 name = getoffset(name, &dstoffset); 1358 if (name == NULL) 1359 return false; 1360 } else dstoffset = stdoffset - SECSPERHOUR; 1361 if (*name == '\0' && !load_ok) 1362 name = TZDEFRULESTRING; 1363 if (*name == ',' || *name == ';') { 1364 struct rule start; 1365 struct rule end; 1366 register int year; 1367 register int timecnt; 1368 time_t janfirst; 1369 int_fast32_t janoffset = 0; 1370 int yearbeg, yearlim; 1371 1372 ++name; 1373 if ((name = getrule(name, &start)) == NULL) 1374 return false; 1375 if (*name++ != ',') 1376 return false; 1377 if ((name = getrule(name, &end)) == NULL) 1378 return false; 1379 if (*name != '\0') 1380 return false; 1381 sp->typecnt = 2; /* standard time and DST */ 1382 /* 1383 ** Two transitions per year, from EPOCH_YEAR forward. 1384 */ 1385 init_ttinfo(&sp->ttis[0], -stdoffset, false, 0); 1386 init_ttinfo(&sp->ttis[1], -dstoffset, true, stdlen + 1); 1387 timecnt = 0; 1388 janfirst = 0; 1389 yearbeg = EPOCH_YEAR; 1390 1391 do { 1392 int_fast32_t yearsecs 1393 = year_lengths[isleap(yearbeg - 1)] * SECSPERDAY; 1394 time_t janfirst1 = janfirst; 1395 yearbeg--; 1396 if (increment_overflow_time(&janfirst1, -yearsecs)) { 1397 janoffset = -yearsecs; 1398 break; 1399 } 1400 janfirst = janfirst1; 1401 } while (atlo < janfirst 1402 && EPOCH_YEAR - YEARSPERREPEAT / 2 < yearbeg); 1403 1404 while (true) { 1405 int_fast32_t yearsecs 1406 = year_lengths[isleap(yearbeg)] * SECSPERDAY; 1407 int yearbeg1 = yearbeg; 1408 time_t janfirst1 = janfirst; 1409 if (increment_overflow_time(&janfirst1, yearsecs) 1410 || increment_overflow(&yearbeg1, 1) 1411 || atlo <= janfirst1) 1412 break; 1413 yearbeg = yearbeg1; 1414 janfirst = janfirst1; 1415 } 1416 1417 yearlim = yearbeg; 1418 if (increment_overflow(&yearlim, years_of_observations)) 1419 yearlim = INT_MAX; 1420 for (year = yearbeg; year < yearlim; year++) { 1421 int_fast32_t 1422 starttime = transtime(year, &start, stdoffset), 1423 endtime = transtime(year, &end, dstoffset); 1424 int_fast32_t 1425 yearsecs = (year_lengths[isleap(year)] 1426 * SECSPERDAY); 1427 bool reversed = endtime < starttime; 1428 if (reversed) { 1429 int_fast32_t swap = starttime; 1430 starttime = endtime; 1431 endtime = swap; 1432 } 1433 if (reversed 1434 || (starttime < endtime 1435 && endtime - starttime < yearsecs)) { 1436 if (TZ_MAX_TIMES - 2 < timecnt) 1437 break; 1438 sp->ats[timecnt] = janfirst; 1439 if (! increment_overflow_time 1440 (&sp->ats[timecnt], 1441 janoffset + starttime) 1442 && atlo <= sp->ats[timecnt]) 1443 sp->types[timecnt++] = !reversed; 1444 sp->ats[timecnt] = janfirst; 1445 if (! increment_overflow_time 1446 (&sp->ats[timecnt], 1447 janoffset + endtime) 1448 && atlo <= sp->ats[timecnt]) { 1449 sp->types[timecnt++] = reversed; 1450 } 1451 } 1452 if (endtime < leaplo) { 1453 yearlim = year; 1454 if (increment_overflow(&yearlim, 1455 years_of_observations)) 1456 yearlim = INT_MAX; 1457 } 1458 if (increment_overflow_time 1459 (&janfirst, janoffset + yearsecs)) 1460 break; 1461 janoffset = 0; 1462 } 1463 sp->timecnt = timecnt; 1464 if (! timecnt) { 1465 sp->ttis[0] = sp->ttis[1]; 1466 sp->typecnt = 1; /* Perpetual DST. */ 1467 } else if (years_of_observations <= year - yearbeg) 1468 sp->goback = sp->goahead = true; 1469 } else { 1470 register int_fast32_t theirstdoffset; 1471 register int_fast32_t theirdstoffset; 1472 register int_fast32_t theiroffset; 1473 register bool isdst; 1474 register int i; 1475 register int j; 1476 1477 if (*name != '\0') 1478 return false; 1479 /* 1480 ** Initial values of theirstdoffset and theirdstoffset. 1481 */ 1482 theirstdoffset = 0; 1483 for (i = 0; i < sp->timecnt; ++i) { 1484 j = sp->types[i]; 1485 if (!sp->ttis[j].tt_isdst) { 1486 theirstdoffset = 1487 - sp->ttis[j].tt_utoff; 1488 break; 1489 } 1490 } 1491 theirdstoffset = 0; 1492 for (i = 0; i < sp->timecnt; ++i) { 1493 j = sp->types[i]; 1494 if (sp->ttis[j].tt_isdst) { 1495 theirdstoffset = 1496 - sp->ttis[j].tt_utoff; 1497 break; 1498 } 1499 } 1500 /* 1501 ** Initially we're assumed to be in standard time. 1502 */ 1503 isdst = false; 1504 /* 1505 ** Now juggle transition times and types 1506 ** tracking offsets as you do. 1507 */ 1508 for (i = 0; i < sp->timecnt; ++i) { 1509 j = sp->types[i]; 1510 sp->types[i] = sp->ttis[j].tt_isdst; 1511 if (sp->ttis[j].tt_ttisut) { 1512 /* No adjustment to transition time */ 1513 } else { 1514 /* 1515 ** If daylight saving time is in 1516 ** effect, and the transition time was 1517 ** not specified as standard time, add 1518 ** the daylight saving time offset to 1519 ** the transition time; otherwise, add 1520 ** the standard time offset to the 1521 ** transition time. 1522 */ 1523 /* 1524 ** Transitions from DST to DDST 1525 ** will effectively disappear since 1526 ** proleptic TZ strings have only one 1527 ** DST offset. 1528 */ 1529 if (isdst && !sp->ttis[j].tt_ttisstd) { 1530 sp->ats[i] += dstoffset - 1531 theirdstoffset; 1532 } else { 1533 sp->ats[i] += stdoffset - 1534 theirstdoffset; 1535 } 1536 } 1537 theiroffset = -sp->ttis[j].tt_utoff; 1538 if (sp->ttis[j].tt_isdst) 1539 theirdstoffset = theiroffset; 1540 else theirstdoffset = theiroffset; 1541 } 1542 /* 1543 ** Finally, fill in ttis. 1544 */ 1545 init_ttinfo(&sp->ttis[0], -stdoffset, false, 0); 1546 init_ttinfo(&sp->ttis[1], -dstoffset, true, stdlen + 1); 1547 sp->typecnt = 2; 1548 } 1549 } else { 1550 dstlen = 0; 1551 sp->typecnt = 1; /* only standard time */ 1552 sp->timecnt = 0; 1553 init_ttinfo(&sp->ttis[0], -stdoffset, false, 0); 1554 } 1555 sp->charcnt = charcnt; 1556 cp = sp->chars; 1557 memcpy(cp, stdname, stdlen); 1558 cp += stdlen; 1559 *cp++ = '\0'; 1560 if (dstlen != 0) { 1561 memcpy(cp, dstname, dstlen); 1562 *(cp + dstlen) = '\0'; 1563 } 1564 return true; 1565 } 1566 1567 static void 1568 gmtload(struct state *const sp) 1569 { 1570 if (tzload(etc_utc, sp, TZLOAD_TZSTRING) != 0) 1571 tzparse("UTC0", sp, NULL); 1572 } 1573 1574 #ifdef DETECT_TZ_CHANGES 1575 /* 1576 * Check if the time zone data we have is still fresh. 1577 */ 1578 static int 1579 tzdata_is_fresh(void) 1580 { 1581 static time_t last_checked; 1582 struct timespec now; 1583 1584 if (clock_gettime(CLOCK_MONOTONIC, &now) < 0) 1585 return 0; 1586 1587 if ((now.tv_sec - last_checked >= __tz_change_interval) || 1588 (last_checked > now.tv_sec)) { 1589 last_checked = now.tv_sec; 1590 return 1; 1591 } 1592 1593 return 0; 1594 } 1595 #endif /* DETECT_TZ_CHANGES */ 1596 1597 #if !USE_TIMEX_T || !defined TM_GMTOFF 1598 1599 /* Initialize *SP to a value appropriate for the TZ setting NAME. 1600 Respect TZLOADFLAGS. 1601 Return 0 on success, an errno value on failure. */ 1602 static int 1603 zoneinit(struct state *sp, char const *name, char tzloadflags) 1604 { 1605 if (name && ! name[0]) { 1606 /* 1607 ** User wants it fast rather than right. 1608 */ 1609 sp->leapcnt = 0; /* so, we're off a little */ 1610 sp->timecnt = 0; 1611 sp->typecnt = 0; 1612 sp->charcnt = 0; 1613 sp->goback = sp->goahead = false; 1614 init_ttinfo(&sp->ttis[0], 0, false, 0); 1615 strcpy(sp->chars, utc); 1616 return 0; 1617 } else { 1618 int err = tzload(name, sp, tzloadflags); 1619 if (err != 0 && name && name[0] != ':' && tzparse(name, sp, NULL)) 1620 err = 0; 1621 if (err == 0) 1622 err = scrub_abbrs(sp); 1623 return err; 1624 } 1625 } 1626 1627 static void 1628 tzset_unlocked(void) 1629 { 1630 char const *name = getenv("TZ"); 1631 #ifdef __FreeBSD__ 1632 tzset_unlocked_name(name); 1633 } 1634 static void 1635 tzset_unlocked_name(char const *name) 1636 { 1637 #endif 1638 struct state *sp = lclptr; 1639 int lcl = name ? strlen(name) < sizeof lcl_TZname : -1; 1640 if (lcl < 0 1641 ? lcl_is_set < 0 1642 : 0 < lcl_is_set && strcmp(lcl_TZname, name) == 0) 1643 #ifdef DETECT_TZ_CHANGES 1644 if (tzdata_is_fresh() == 0) 1645 #endif /* DETECT_TZ_CHANGES */ 1646 return; 1647 # ifdef ALL_STATE 1648 if (! sp) 1649 lclptr = sp = malloc(sizeof *lclptr); 1650 # endif 1651 if (sp) { 1652 if (zoneinit(sp, name, TZLOAD_FROMENV | TZLOAD_TZSTRING) != 0) { 1653 zoneinit(sp, "", 0); 1654 strcpy(sp->chars, UNSPEC); 1655 } 1656 if (0 < lcl) 1657 strcpy(lcl_TZname, name); 1658 } 1659 settzname(); 1660 lcl_is_set = lcl; 1661 } 1662 1663 #endif 1664 1665 #if !USE_TIMEX_T 1666 void 1667 tzset(void) 1668 { 1669 if (lock() != 0) 1670 return; 1671 tzset_unlocked(); 1672 unlock(); 1673 } 1674 #endif 1675 1676 #ifdef __FreeBSD__ 1677 void 1678 freebsd13_tzsetwall(void) 1679 { 1680 if (lock() != 0) 1681 return; 1682 tzset_unlocked_name(NULL); 1683 unlock(); 1684 } 1685 __sym_compat(tzsetwall, freebsd13_tzsetwall, FBSD_1.0); 1686 __warn_references(tzsetwall, 1687 "warning: tzsetwall() is deprecated, use tzset() instead."); 1688 #endif /* __FreeBSD__ */ 1689 static void 1690 gmtcheck(void) 1691 { 1692 static bool gmt_is_set; 1693 if (lock() != 0) 1694 return; 1695 if (! gmt_is_set) { 1696 #ifdef ALL_STATE 1697 gmtptr = malloc(sizeof *gmtptr); 1698 #endif 1699 if (gmtptr) 1700 gmtload(gmtptr); 1701 gmt_is_set = true; 1702 } 1703 unlock(); 1704 } 1705 #ifdef __FreeBSD__ 1706 #define gmtcheck() _once(&gmt_once, gmtcheck) 1707 #endif 1708 1709 #if NETBSD_INSPIRED && !USE_TIMEX_T 1710 1711 timezone_t 1712 tzalloc(char const *name) 1713 { 1714 timezone_t sp = malloc(sizeof *sp); 1715 if (sp) { 1716 int err = zoneinit(sp, name, TZLOAD_TZSTRING); 1717 if (err != 0) { 1718 free(sp); 1719 errno = err; 1720 return NULL; 1721 } 1722 } else if (!HAVE_MALLOC_ERRNO) 1723 errno = ENOMEM; 1724 return sp; 1725 } 1726 1727 void 1728 tzfree(timezone_t sp) 1729 { 1730 free(sp); 1731 } 1732 1733 /* 1734 ** NetBSD 6.1.4 has ctime_rz, but omit it because C23 deprecates ctime and 1735 ** POSIX.1-2024 removes ctime_r. Both have potential security problems that 1736 ** ctime_rz would share. Callers can instead use localtime_rz + strftime. 1737 ** 1738 ** NetBSD 6.1.4 has tzgetname, but omit it because it doesn't work 1739 ** in zones with three or more time zone abbreviations. 1740 ** Callers can instead use localtime_rz + strftime. 1741 */ 1742 1743 #endif 1744 1745 #if !USE_TIMEX_T || !defined TM_GMTOFF 1746 1747 /* 1748 ** The easy way to behave "as if no library function calls" localtime 1749 ** is to not call it, so we drop its guts into "localsub", which can be 1750 ** freely called. (And no, the PANS doesn't require the above behavior, 1751 ** but it *is* desirable.) 1752 ** 1753 ** If successful and SETNAME is nonzero, 1754 ** set the applicable parts of tzname, timezone and altzone; 1755 ** however, it's OK to omit this step for proleptic TZ strings 1756 ** since in that case tzset should have already done this step correctly. 1757 ** SETNAME's type is int_fast32_t for compatibility with gmtsub, 1758 ** but it is actually a boolean and its value should be 0 or 1. 1759 */ 1760 1761 /*ARGSUSED*/ 1762 static struct tm * 1763 localsub(struct state const *sp, time_t const *timep, int_fast32_t setname, 1764 struct tm *const tmp) 1765 { 1766 register const struct ttinfo * ttisp; 1767 register int i; 1768 register struct tm * result; 1769 const time_t t = *timep; 1770 1771 if (sp == NULL) { 1772 /* Don't bother to set tzname etc.; tzset has already done it. */ 1773 return gmtsub(gmtptr, timep, 0, tmp); 1774 } 1775 if ((sp->goback && t < sp->ats[0]) || 1776 (sp->goahead && t > sp->ats[sp->timecnt - 1])) { 1777 time_t newt; 1778 register time_t seconds; 1779 register time_t years; 1780 1781 if (t < sp->ats[0]) 1782 seconds = sp->ats[0] - t; 1783 else seconds = t - sp->ats[sp->timecnt - 1]; 1784 --seconds; 1785 1786 /* Beware integer overflow, as SECONDS might 1787 be close to the maximum time_t. */ 1788 years = seconds / SECSPERREPEAT * YEARSPERREPEAT; 1789 seconds = years * AVGSECSPERYEAR; 1790 years += YEARSPERREPEAT; 1791 if (t < sp->ats[0]) 1792 newt = t + seconds + SECSPERREPEAT; 1793 else 1794 newt = t - seconds - SECSPERREPEAT; 1795 1796 if (newt < sp->ats[0] || 1797 newt > sp->ats[sp->timecnt - 1]) 1798 return NULL; /* "cannot happen" */ 1799 result = localsub(sp, &newt, setname, tmp); 1800 if (result) { 1801 # if defined ckd_add && defined ckd_sub 1802 if (t < sp->ats[0] 1803 ? ckd_sub(&result->tm_year, 1804 result->tm_year, years) 1805 : ckd_add(&result->tm_year, 1806 result->tm_year, years)) 1807 return NULL; 1808 # else 1809 register int_fast64_t newy; 1810 1811 newy = result->tm_year; 1812 if (t < sp->ats[0]) 1813 newy -= years; 1814 else newy += years; 1815 if (! (INT_MIN <= newy && newy <= INT_MAX)) 1816 return NULL; 1817 result->tm_year = newy; 1818 # endif 1819 } 1820 return result; 1821 } 1822 if (sp->timecnt == 0 || t < sp->ats[0]) { 1823 i = 0; 1824 } else { 1825 register int lo = 1; 1826 register int hi = sp->timecnt; 1827 1828 while (lo < hi) { 1829 register int mid = (lo + hi) >> 1; 1830 1831 if (t < sp->ats[mid]) 1832 hi = mid; 1833 else lo = mid + 1; 1834 } 1835 i = sp->types[lo - 1]; 1836 } 1837 ttisp = &sp->ttis[i]; 1838 /* 1839 ** To get (wrong) behavior that's compatible with System V Release 2.0 1840 ** you'd replace the statement below with 1841 ** t += ttisp->tt_utoff; 1842 ** timesub(&t, 0L, sp, tmp); 1843 */ 1844 result = timesub(&t, ttisp->tt_utoff, sp, tmp); 1845 if (result) { 1846 result->tm_isdst = ttisp->tt_isdst; 1847 # ifdef TM_ZONE 1848 result->TM_ZONE = UNCONST(&sp->chars[ttisp->tt_desigidx]); 1849 # endif 1850 if (setname) 1851 update_tzname_etc(sp, ttisp); 1852 } 1853 return result; 1854 } 1855 #endif 1856 1857 #if !USE_TIMEX_T 1858 1859 # if NETBSD_INSPIRED 1860 struct tm * 1861 localtime_rz(struct state *restrict sp, time_t const *restrict timep, 1862 struct tm *restrict tmp) 1863 { 1864 return localsub(sp, timep, 0, tmp); 1865 } 1866 # endif 1867 1868 static struct tm * 1869 localtime_tzset(time_t const *timep, struct tm *tmp, bool setname) 1870 { 1871 int err = lock(); 1872 if (err) { 1873 errno = err; 1874 return NULL; 1875 } 1876 #ifndef DETECT_TZ_CHANGES 1877 if (setname || !lcl_is_set) 1878 #endif /* DETECT_TZ_CHANGES */ 1879 tzset_unlocked(); 1880 tmp = localsub(lclptr, timep, setname, tmp); 1881 unlock(); 1882 return tmp; 1883 } 1884 1885 #ifdef __FreeBSD__ 1886 static void 1887 localtime_key_init(void) 1888 { 1889 localtime_key_error = _pthread_key_create(&localtime_key, free); 1890 } 1891 #endif /* __FreeBSD__ */ 1892 struct tm * 1893 localtime(const time_t *timep) 1894 { 1895 # if !SUPPORT_C89 1896 static struct tm tm; 1897 # endif 1898 #ifdef __FreeBSD__ 1899 struct tm *p_tm = &tm; 1900 1901 if (__isthreaded != 0) { 1902 _pthread_once(&localtime_once, localtime_key_init); 1903 if (localtime_key_error != 0) { 1904 errno = localtime_key_error; 1905 return (NULL); 1906 } 1907 if ((p_tm = _pthread_getspecific(localtime_key)) == NULL) { 1908 if ((p_tm = malloc(sizeof(*p_tm))) == NULL) { 1909 return (NULL); 1910 } 1911 if (_pthread_setspecific(localtime_key, p_tm) != 0) { 1912 free(p_tm); 1913 return (NULL); 1914 } 1915 } 1916 } 1917 #endif /* __FreeBSD__ */ 1918 return localtime_tzset(timep, p_tm, true); 1919 } 1920 1921 struct tm * 1922 localtime_r(const time_t *restrict timep, struct tm *restrict tmp) 1923 { 1924 return localtime_tzset(timep, tmp, false); 1925 } 1926 #endif 1927 1928 /* 1929 ** gmtsub is to gmtime as localsub is to localtime. 1930 */ 1931 1932 static struct tm * 1933 gmtsub(ATTRIBUTE_MAYBE_UNUSED struct state const *sp, time_t const *timep, 1934 int_fast32_t offset, struct tm *tmp) 1935 { 1936 register struct tm * result; 1937 1938 result = timesub(timep, offset, gmtptr, tmp); 1939 #ifdef TM_ZONE 1940 /* 1941 ** Could get fancy here and deliver something such as 1942 ** "+xx" or "-xx" if offset is non-zero, 1943 ** but this is no time for a treasure hunt. 1944 */ 1945 tmp->TM_ZONE = UNCONST(offset ? wildabbr 1946 : gmtptr ? gmtptr->chars : utc); 1947 #endif /* defined TM_ZONE */ 1948 return result; 1949 } 1950 1951 #if !USE_TIMEX_T 1952 1953 /* 1954 * Re-entrant version of gmtime. 1955 */ 1956 1957 struct tm * 1958 gmtime_r(time_t const *restrict timep, struct tm *restrict tmp) 1959 { 1960 gmtcheck(); 1961 return gmtsub(gmtptr, timep, 0, tmp); 1962 } 1963 1964 #ifdef __FreeBSD__ 1965 static void 1966 gmtime_key_init(void) 1967 { 1968 gmtime_key_error = _pthread_key_create(&gmtime_key, free); 1969 } 1970 #endif /* __FreeBSD__ */ 1971 struct tm * 1972 gmtime(const time_t *timep) 1973 { 1974 # if !SUPPORT_C89 1975 static struct tm tm; 1976 # endif 1977 #ifdef __FreeBSD__ 1978 struct tm *p_tm = &tm; 1979 1980 if (__isthreaded != 0) { 1981 _pthread_once(&gmtime_once, gmtime_key_init); 1982 if (gmtime_key_error != 0) { 1983 errno = gmtime_key_error; 1984 return (NULL); 1985 } 1986 if ((p_tm = _pthread_getspecific(gmtime_key)) == NULL) { 1987 if ((p_tm = malloc(sizeof(*p_tm))) == NULL) { 1988 return (NULL); 1989 } 1990 if (_pthread_setspecific(gmtime_key, p_tm) != 0) { 1991 free(p_tm); 1992 return (NULL); 1993 } 1994 } 1995 } 1996 #endif /* __FreeBSD__ */ 1997 return gmtime_r(timep, p_tm); 1998 } 1999 2000 # if STD_INSPIRED 2001 2002 /* This function is obsolescent and may disappear in future releases. 2003 Callers can instead use localtime_rz with a fixed-offset zone. */ 2004 2005 struct tm * 2006 offtime_r(time_t const *restrict timep, long offset, struct tm *restrict tmp) 2007 { 2008 gmtcheck(); 2009 return gmtsub(gmtptr, timep, offset, tmp); 2010 } 2011 2012 #ifdef __FreeBSD__ 2013 static void 2014 offtime_key_init(void) 2015 { 2016 offtime_key_error = _pthread_key_create(&offtime_key, free); 2017 } 2018 #endif /* __FreeBSD__ */ 2019 struct tm * 2020 offtime(const time_t *timep, long offset) 2021 { 2022 # if !SUPPORT_C89 2023 static struct tm tm; 2024 # endif 2025 #ifdef __FreeBSD__ 2026 struct tm *p_tm = &tm; 2027 2028 if (__isthreaded != 0) { 2029 _pthread_once(&offtime_once, offtime_key_init); 2030 if (offtime_key_error != 0) { 2031 errno = offtime_key_error; 2032 return (NULL); 2033 } 2034 if ((p_tm = _pthread_getspecific(offtime_key)) == NULL) { 2035 if ((p_tm = malloc(sizeof(*p_tm))) == NULL) { 2036 return (NULL); 2037 } 2038 if (_pthread_setspecific(offtime_key, p_tm) != 0) { 2039 free(p_tm); 2040 return (NULL); 2041 } 2042 } 2043 } 2044 #endif 2045 return offtime_r(timep, offset, p_tm); 2046 } 2047 2048 # endif 2049 #endif 2050 2051 /* 2052 ** Return the number of leap years through the end of the given year 2053 ** where, to make the math easy, the answer for year zero is defined as zero. 2054 */ 2055 2056 static time_t 2057 leaps_thru_end_of_nonneg(time_t y) 2058 { 2059 return y / 4 - y / 100 + y / 400; 2060 } 2061 2062 static time_t 2063 leaps_thru_end_of(time_t y) 2064 { 2065 return (y < 0 2066 ? -1 - leaps_thru_end_of_nonneg(-1 - y) 2067 : leaps_thru_end_of_nonneg(y)); 2068 } 2069 2070 static struct tm * 2071 timesub(const time_t *timep, int_fast32_t offset, 2072 const struct state *sp, struct tm *tmp) 2073 { 2074 register const struct lsinfo * lp; 2075 register time_t tdays; 2076 register const int * ip; 2077 register int_fast32_t corr; 2078 register int i; 2079 int_fast32_t idays, rem, dayoff, dayrem; 2080 time_t y; 2081 2082 /* If less than SECSPERMIN, the number of seconds since the 2083 most recent positive leap second; otherwise, do not add 1 2084 to localtime tm_sec because of leap seconds. */ 2085 time_t secs_since_posleap = SECSPERMIN; 2086 2087 corr = 0; 2088 i = (sp == NULL) ? 0 : sp->leapcnt; 2089 while (--i >= 0) { 2090 lp = &sp->lsis[i]; 2091 if (*timep >= lp->ls_trans) { 2092 corr = lp->ls_corr; 2093 if ((i == 0 ? 0 : lp[-1].ls_corr) < corr) 2094 secs_since_posleap = *timep - lp->ls_trans; 2095 break; 2096 } 2097 } 2098 2099 /* Calculate the year, avoiding integer overflow even if 2100 time_t is unsigned. */ 2101 tdays = *timep / SECSPERDAY; 2102 rem = *timep % SECSPERDAY; 2103 rem += offset % SECSPERDAY - corr % SECSPERDAY + 3 * SECSPERDAY; 2104 dayoff = offset / SECSPERDAY - corr / SECSPERDAY + rem / SECSPERDAY - 3; 2105 rem %= SECSPERDAY; 2106 /* y = (EPOCH_YEAR 2107 + floor((tdays + dayoff) / DAYSPERREPEAT) * YEARSPERREPEAT), 2108 sans overflow. But calculate against 1570 (EPOCH_YEAR - 2109 YEARSPERREPEAT) instead of against 1970 so that things work 2110 for localtime values before 1970 when time_t is unsigned. */ 2111 dayrem = tdays % DAYSPERREPEAT; 2112 dayrem += dayoff % DAYSPERREPEAT; 2113 y = (EPOCH_YEAR - YEARSPERREPEAT 2114 + ((1 + dayoff / DAYSPERREPEAT + dayrem / DAYSPERREPEAT 2115 - ((dayrem % DAYSPERREPEAT) < 0) 2116 + tdays / DAYSPERREPEAT) 2117 * YEARSPERREPEAT)); 2118 /* idays = (tdays + dayoff) mod DAYSPERREPEAT, sans overflow. */ 2119 idays = tdays % DAYSPERREPEAT; 2120 idays += dayoff % DAYSPERREPEAT + 2 * DAYSPERREPEAT; 2121 idays %= DAYSPERREPEAT; 2122 /* Increase Y and decrease IDAYS until IDAYS is in range for Y. */ 2123 while (year_lengths[isleap(y)] <= idays) { 2124 int tdelta = idays / DAYSPERLYEAR; 2125 int_fast32_t ydelta = tdelta + !tdelta; 2126 time_t newy = y + ydelta; 2127 register int leapdays; 2128 leapdays = leaps_thru_end_of(newy - 1) - 2129 leaps_thru_end_of(y - 1); 2130 idays -= ydelta * DAYSPERNYEAR; 2131 idays -= leapdays; 2132 y = newy; 2133 } 2134 2135 #ifdef ckd_add 2136 if (ckd_add(&tmp->tm_year, y, -TM_YEAR_BASE)) { 2137 errno = EOVERFLOW; 2138 return NULL; 2139 } 2140 #else 2141 if (!TYPE_SIGNED(time_t) && y < TM_YEAR_BASE) { 2142 int signed_y = y; 2143 tmp->tm_year = signed_y - TM_YEAR_BASE; 2144 } else if ((!TYPE_SIGNED(time_t) || INT_MIN + TM_YEAR_BASE <= y) 2145 && y - TM_YEAR_BASE <= INT_MAX) 2146 tmp->tm_year = y - TM_YEAR_BASE; 2147 else { 2148 errno = EOVERFLOW; 2149 return NULL; 2150 } 2151 #endif 2152 tmp->tm_yday = idays; 2153 /* 2154 ** The "extra" mods below avoid overflow problems. 2155 */ 2156 tmp->tm_wday = (TM_WDAY_BASE 2157 + ((tmp->tm_year % DAYSPERWEEK) 2158 * (DAYSPERNYEAR % DAYSPERWEEK)) 2159 + leaps_thru_end_of(y - 1) 2160 - leaps_thru_end_of(TM_YEAR_BASE - 1) 2161 + idays); 2162 tmp->tm_wday %= DAYSPERWEEK; 2163 if (tmp->tm_wday < 0) 2164 tmp->tm_wday += DAYSPERWEEK; 2165 tmp->tm_hour = rem / SECSPERHOUR; 2166 rem %= SECSPERHOUR; 2167 tmp->tm_min = rem / SECSPERMIN; 2168 tmp->tm_sec = rem % SECSPERMIN; 2169 2170 /* Use "... ??:??:60" at the end of the localtime minute containing 2171 the second just before the positive leap second. */ 2172 tmp->tm_sec += secs_since_posleap <= tmp->tm_sec; 2173 2174 ip = mon_lengths[isleap(y)]; 2175 for (tmp->tm_mon = 0; idays >= ip[tmp->tm_mon]; ++(tmp->tm_mon)) 2176 idays -= ip[tmp->tm_mon]; 2177 tmp->tm_mday = idays + 1; 2178 tmp->tm_isdst = 0; 2179 #ifdef TM_GMTOFF 2180 tmp->TM_GMTOFF = offset; 2181 #endif /* defined TM_GMTOFF */ 2182 return tmp; 2183 } 2184 2185 /* 2186 ** Adapted from code provided by Robert Elz, who writes: 2187 ** The "best" way to do mktime I think is based on an idea of Bob 2188 ** Kridle's (so its said...) from a long time ago. 2189 ** It does a binary search of the time_t space. Since time_t's are 2190 ** just 32 bits, its a max of 32 iterations (even at 64 bits it 2191 ** would still be very reasonable). 2192 */ 2193 2194 #ifndef WRONG 2195 # define WRONG (-1) 2196 #endif /* !defined WRONG */ 2197 2198 /* 2199 ** Normalize logic courtesy Paul Eggert. 2200 */ 2201 2202 static bool 2203 increment_overflow(int *ip, int j) 2204 { 2205 #ifdef ckd_add 2206 return ckd_add(ip, *ip, j); 2207 #else 2208 register int const i = *ip; 2209 2210 /* 2211 ** If i >= 0 there can only be overflow if i + j > INT_MAX 2212 ** or if j > INT_MAX - i; given i >= 0, INT_MAX - i cannot overflow. 2213 ** If i < 0 there can only be overflow if i + j < INT_MIN 2214 ** or if j < INT_MIN - i; given i < 0, INT_MIN - i cannot overflow. 2215 */ 2216 if ((i >= 0) ? (j > INT_MAX - i) : (j < INT_MIN - i)) 2217 return true; 2218 *ip += j; 2219 return false; 2220 #endif 2221 } 2222 2223 static bool 2224 increment_overflow_time_iinntt(time_t *tp, iinntt j) 2225 { 2226 #ifdef ckd_add 2227 return ckd_add(tp, *tp, j); 2228 #else 2229 if (j < 0 2230 ? (TYPE_SIGNED(time_t) ? *tp < TIME_T_MIN - j : *tp <= -1 - j) 2231 : TIME_T_MAX - j < *tp) 2232 return true; 2233 *tp += j; 2234 return false; 2235 #endif 2236 } 2237 2238 static bool 2239 increment_overflow_time(time_t *tp, int_fast32_t j) 2240 { 2241 #ifdef ckd_add 2242 return ckd_add(tp, *tp, j); 2243 #else 2244 /* 2245 ** This is like 2246 ** 'if (! (TIME_T_MIN <= *tp + j && *tp + j <= TIME_T_MAX)) ...', 2247 ** except that it does the right thing even if *tp + j would overflow. 2248 */ 2249 if (! (j < 0 2250 ? (TYPE_SIGNED(time_t) ? TIME_T_MIN - j <= *tp : -1 - j < *tp) 2251 : *tp <= TIME_T_MAX - j)) 2252 return true; 2253 *tp += j; 2254 return false; 2255 #endif 2256 } 2257 2258 static int 2259 tmcomp(register const struct tm *const atmp, 2260 register const struct tm *const btmp) 2261 { 2262 register int result; 2263 2264 if (atmp->tm_year != btmp->tm_year) 2265 return atmp->tm_year < btmp->tm_year ? -1 : 1; 2266 if ((result = (atmp->tm_mon - btmp->tm_mon)) == 0 && 2267 (result = (atmp->tm_mday - btmp->tm_mday)) == 0 && 2268 (result = (atmp->tm_hour - btmp->tm_hour)) == 0 && 2269 (result = (atmp->tm_min - btmp->tm_min)) == 0) 2270 result = atmp->tm_sec - btmp->tm_sec; 2271 return result; 2272 } 2273 2274 /* Copy to *DEST from *SRC. Copy only the members needed for mktime, 2275 as other members might not be initialized. */ 2276 static void 2277 mktmcpy(struct tm *dest, struct tm const *src) 2278 { 2279 dest->tm_sec = src->tm_sec; 2280 dest->tm_min = src->tm_min; 2281 dest->tm_hour = src->tm_hour; 2282 dest->tm_mday = src->tm_mday; 2283 dest->tm_mon = src->tm_mon; 2284 dest->tm_year = src->tm_year; 2285 dest->tm_isdst = src->tm_isdst; 2286 #if defined TM_GMTOFF && ! UNINIT_TRAP 2287 dest->TM_GMTOFF = src->TM_GMTOFF; 2288 #endif 2289 } 2290 2291 static time_t 2292 time2sub(struct tm *const tmp, 2293 struct tm *(*funcp)(struct state const *, time_t const *, 2294 int_fast32_t, struct tm *), 2295 struct state const *sp, 2296 const int_fast32_t offset, 2297 bool *okayp, 2298 bool do_norm_secs) 2299 { 2300 register int dir; 2301 register int i, j; 2302 register time_t lo; 2303 register time_t hi; 2304 iinntt y, mday, hour, min, saved_seconds; 2305 time_t newt; 2306 time_t t; 2307 struct tm yourtm, mytm; 2308 2309 *okayp = false; 2310 mktmcpy(&yourtm, tmp); 2311 2312 min = yourtm.tm_min; 2313 if (do_norm_secs) { 2314 min += yourtm.tm_sec / SECSPERMIN; 2315 yourtm.tm_sec %= SECSPERMIN; 2316 if (yourtm.tm_sec < 0) { 2317 yourtm.tm_sec += SECSPERMIN; 2318 min--; 2319 } 2320 } 2321 2322 hour = yourtm.tm_hour; 2323 hour += min / MINSPERHOUR; 2324 yourtm.tm_min = min % MINSPERHOUR; 2325 if (yourtm.tm_min < 0) { 2326 yourtm.tm_min += MINSPERHOUR; 2327 hour--; 2328 } 2329 2330 mday = yourtm.tm_mday; 2331 mday += hour / HOURSPERDAY; 2332 yourtm.tm_hour = hour % HOURSPERDAY; 2333 if (yourtm.tm_hour < 0) { 2334 yourtm.tm_hour += HOURSPERDAY; 2335 mday--; 2336 } 2337 2338 y = yourtm.tm_year; 2339 y += yourtm.tm_mon / MONSPERYEAR; 2340 yourtm.tm_mon %= MONSPERYEAR; 2341 if (yourtm.tm_mon < 0) { 2342 yourtm.tm_mon += MONSPERYEAR; 2343 y--; 2344 } 2345 2346 /* 2347 ** Turn y into an actual year number for now. 2348 ** It is converted back to an offset from TM_YEAR_BASE later. 2349 */ 2350 y += TM_YEAR_BASE; 2351 2352 while (mday <= 0) { 2353 iinntt li = y - (yourtm.tm_mon <= 1); 2354 mday += year_lengths[isleap(li)]; 2355 y--; 2356 } 2357 while (DAYSPERLYEAR < mday) { 2358 iinntt li = y + (1 < yourtm.tm_mon); 2359 mday -= year_lengths[isleap(li)]; 2360 y++; 2361 } 2362 yourtm.tm_mday = mday; 2363 for ( ; ; ) { 2364 i = mon_lengths[isleap(y)][yourtm.tm_mon]; 2365 if (yourtm.tm_mday <= i) 2366 break; 2367 yourtm.tm_mday -= i; 2368 if (++yourtm.tm_mon >= MONSPERYEAR) { 2369 yourtm.tm_mon = 0; 2370 y++; 2371 } 2372 } 2373 #ifdef ckd_add 2374 if (ckd_add(&yourtm.tm_year, y, -TM_YEAR_BASE)) 2375 return WRONG; 2376 #else 2377 y -= TM_YEAR_BASE; 2378 if (! (INT_MIN <= y && y <= INT_MAX)) 2379 return WRONG; 2380 yourtm.tm_year = y; 2381 #endif 2382 if (yourtm.tm_sec >= 0 && yourtm.tm_sec < SECSPERMIN) 2383 saved_seconds = 0; 2384 else if (yourtm.tm_year < EPOCH_YEAR - TM_YEAR_BASE) { 2385 /* 2386 ** We can't set tm_sec to 0, because that might push the 2387 ** time below the minimum representable time. 2388 ** Set tm_sec to 59 instead. 2389 ** This assumes that the minimum representable time is 2390 ** not in the same minute that a leap second was deleted from, 2391 ** which is a safer assumption than using 58 would be. 2392 */ 2393 saved_seconds = yourtm.tm_sec; 2394 saved_seconds -= SECSPERMIN - 1; 2395 yourtm.tm_sec = SECSPERMIN - 1; 2396 } else { 2397 saved_seconds = yourtm.tm_sec; 2398 yourtm.tm_sec = 0; 2399 } 2400 /* 2401 ** Do a binary search (this works whatever time_t's type is). 2402 */ 2403 lo = TIME_T_MIN; 2404 hi = TIME_T_MAX; 2405 for ( ; ; ) { 2406 t = lo / 2 + hi / 2; 2407 if (t < lo) 2408 t = lo; 2409 else if (t > hi) 2410 t = hi; 2411 if (! funcp(sp, &t, offset, &mytm)) { 2412 /* 2413 ** Assume that t is too extreme to be represented in 2414 ** a struct tm; arrange things so that it is less 2415 ** extreme on the next pass. 2416 */ 2417 dir = (t > 0) ? 1 : -1; 2418 } else dir = tmcomp(&mytm, &yourtm); 2419 if (dir != 0) { 2420 if (t == lo) { 2421 if (t == TIME_T_MAX) 2422 return WRONG; 2423 ++t; 2424 ++lo; 2425 } else if (t == hi) { 2426 if (t == TIME_T_MIN) 2427 return WRONG; 2428 --t; 2429 --hi; 2430 } 2431 if (lo > hi) 2432 return WRONG; 2433 if (dir > 0) 2434 hi = t; 2435 else lo = t; 2436 continue; 2437 } 2438 #if defined TM_GMTOFF && ! UNINIT_TRAP 2439 if (mytm.TM_GMTOFF != yourtm.TM_GMTOFF 2440 && (yourtm.TM_GMTOFF < 0 2441 ? (-SECSPERDAY <= yourtm.TM_GMTOFF 2442 && (mytm.TM_GMTOFF <= 2443 (min(INT_FAST32_MAX, LONG_MAX) 2444 + yourtm.TM_GMTOFF))) 2445 : (yourtm.TM_GMTOFF <= SECSPERDAY 2446 && ((max(INT_FAST32_MIN, LONG_MIN) 2447 + yourtm.TM_GMTOFF) 2448 <= mytm.TM_GMTOFF)))) { 2449 /* MYTM matches YOURTM except with the wrong UT offset. 2450 YOURTM.TM_GMTOFF is plausible, so try it instead. 2451 It's OK if YOURTM.TM_GMTOFF contains uninitialized data, 2452 since the guess gets checked. */ 2453 time_t altt = t; 2454 int_fast32_t diff = mytm.TM_GMTOFF - yourtm.TM_GMTOFF; 2455 if (!increment_overflow_time(&altt, diff)) { 2456 struct tm alttm; 2457 if (funcp(sp, &altt, offset, &alttm) 2458 && alttm.tm_isdst == mytm.tm_isdst 2459 && alttm.TM_GMTOFF == yourtm.TM_GMTOFF 2460 && tmcomp(&alttm, &yourtm) == 0) { 2461 t = altt; 2462 mytm = alttm; 2463 } 2464 } 2465 } 2466 #endif 2467 if (yourtm.tm_isdst < 0 || mytm.tm_isdst == yourtm.tm_isdst) 2468 break; 2469 /* 2470 ** Right time, wrong type. 2471 ** Hunt for right time, right type. 2472 ** It's okay to guess wrong since the guess 2473 ** gets checked. 2474 */ 2475 if (sp == NULL) 2476 return WRONG; 2477 for (i = sp->typecnt - 1; i >= 0; --i) { 2478 if (sp->ttis[i].tt_isdst != yourtm.tm_isdst) 2479 continue; 2480 for (j = sp->typecnt - 1; j >= 0; --j) { 2481 if (sp->ttis[j].tt_isdst == yourtm.tm_isdst) 2482 continue; 2483 if (ttunspecified(sp, j)) 2484 continue; 2485 newt = (t + sp->ttis[j].tt_utoff 2486 - sp->ttis[i].tt_utoff); 2487 if (! funcp(sp, &newt, offset, &mytm)) 2488 continue; 2489 if (tmcomp(&mytm, &yourtm) != 0) 2490 continue; 2491 if (mytm.tm_isdst != yourtm.tm_isdst) 2492 continue; 2493 /* 2494 ** We have a match. 2495 */ 2496 t = newt; 2497 goto label; 2498 } 2499 } 2500 return WRONG; 2501 } 2502 label: 2503 if (increment_overflow_time_iinntt(&t, saved_seconds)) 2504 return WRONG; 2505 if (funcp(sp, &t, offset, tmp)) 2506 *okayp = true; 2507 return t; 2508 } 2509 2510 static time_t 2511 time2(struct tm * const tmp, 2512 struct tm *(*funcp)(struct state const *, time_t const *, 2513 int_fast32_t, struct tm *), 2514 struct state const *sp, 2515 const int_fast32_t offset, 2516 bool *okayp) 2517 { 2518 time_t t; 2519 2520 /* 2521 ** First try without normalization of seconds 2522 ** (in case tm_sec contains a value associated with a leap second). 2523 ** If that fails, try with normalization of seconds. 2524 */ 2525 t = time2sub(tmp, funcp, sp, offset, okayp, false); 2526 return *okayp ? t : time2sub(tmp, funcp, sp, offset, okayp, true); 2527 } 2528 2529 static time_t 2530 time1(struct tm *const tmp, 2531 struct tm *(*funcp)(struct state const *, time_t const *, 2532 int_fast32_t, struct tm *), 2533 struct state const *sp, 2534 const int_fast32_t offset) 2535 { 2536 register time_t t; 2537 register int samei, otheri; 2538 register int sameind, otherind; 2539 register int i; 2540 register int nseen; 2541 char seen[TZ_MAX_TYPES]; 2542 unsigned char types[TZ_MAX_TYPES]; 2543 bool okay; 2544 2545 if (tmp == NULL) { 2546 errno = EINVAL; 2547 return WRONG; 2548 } 2549 if (tmp->tm_isdst > 1) 2550 tmp->tm_isdst = 1; 2551 t = time2(tmp, funcp, sp, offset, &okay); 2552 if (okay) 2553 return t; 2554 if (tmp->tm_isdst < 0) 2555 #ifdef PCTS 2556 /* 2557 ** POSIX Conformance Test Suite code courtesy Grant Sullivan. 2558 */ 2559 tmp->tm_isdst = 0; /* reset to std and try again */ 2560 #else 2561 return t; 2562 #endif /* !defined PCTS */ 2563 /* 2564 ** We're supposed to assume that somebody took a time of one type 2565 ** and did some math on it that yielded a "struct tm" that's bad. 2566 ** We try to divine the type they started from and adjust to the 2567 ** type they need. 2568 */ 2569 if (sp == NULL) 2570 return WRONG; 2571 for (i = 0; i < sp->typecnt; ++i) 2572 seen[i] = false; 2573 nseen = 0; 2574 for (i = sp->timecnt - 1; i >= 0; --i) 2575 if (!seen[sp->types[i]] && !ttunspecified(sp, sp->types[i])) { 2576 seen[sp->types[i]] = true; 2577 types[nseen++] = sp->types[i]; 2578 } 2579 for (sameind = 0; sameind < nseen; ++sameind) { 2580 samei = types[sameind]; 2581 if (sp->ttis[samei].tt_isdst != tmp->tm_isdst) 2582 continue; 2583 for (otherind = 0; otherind < nseen; ++otherind) { 2584 otheri = types[otherind]; 2585 if (sp->ttis[otheri].tt_isdst == tmp->tm_isdst) 2586 continue; 2587 tmp->tm_sec += (sp->ttis[otheri].tt_utoff 2588 - sp->ttis[samei].tt_utoff); 2589 tmp->tm_isdst = !tmp->tm_isdst; 2590 t = time2(tmp, funcp, sp, offset, &okay); 2591 if (okay) 2592 return t; 2593 tmp->tm_sec -= (sp->ttis[otheri].tt_utoff 2594 - sp->ttis[samei].tt_utoff); 2595 tmp->tm_isdst = !tmp->tm_isdst; 2596 } 2597 } 2598 return WRONG; 2599 } 2600 2601 #if !defined TM_GMTOFF || !USE_TIMEX_T 2602 2603 static time_t 2604 mktime_tzname(struct state *sp, struct tm *tmp, bool setname) 2605 { 2606 if (sp) 2607 return time1(tmp, localsub, sp, setname); 2608 else { 2609 gmtcheck(); 2610 return time1(tmp, gmtsub, gmtptr, 0); 2611 } 2612 } 2613 2614 # if USE_TIMEX_T 2615 static 2616 # endif 2617 time_t 2618 mktime(struct tm *tmp) 2619 { 2620 time_t t; 2621 int err = lock(); 2622 if (err) { 2623 errno = err; 2624 return -1; 2625 } 2626 tzset_unlocked(); 2627 t = mktime_tzname(lclptr, tmp, true); 2628 unlock(); 2629 return t; 2630 } 2631 2632 #endif 2633 2634 #if NETBSD_INSPIRED && !USE_TIMEX_T 2635 time_t 2636 mktime_z(struct state *restrict sp, struct tm *restrict tmp) 2637 { 2638 return mktime_tzname(sp, tmp, false); 2639 } 2640 #endif 2641 2642 #if STD_INSPIRED && !USE_TIMEX_T 2643 /* This function is obsolescent and may disappear in future releases. 2644 Callers can instead use mktime. */ 2645 time_t 2646 timelocal(struct tm *tmp) 2647 { 2648 if (tmp != NULL) 2649 tmp->tm_isdst = -1; /* in case it wasn't initialized */ 2650 return mktime(tmp); 2651 } 2652 #endif 2653 2654 #if defined TM_GMTOFF || !USE_TIMEX_T 2655 2656 # ifndef EXTERN_TIMEOFF 2657 # ifndef timeoff 2658 # define timeoff my_timeoff /* Don't collide with OpenBSD 7.4 <time.h>. */ 2659 # endif 2660 # define EXTERN_TIMEOFF static 2661 # endif 2662 2663 /* This function is obsolescent and may disappear in future releases. 2664 Callers can instead use mktime_z with a fixed-offset zone. */ 2665 EXTERN_TIMEOFF time_t 2666 timeoff(struct tm *tmp, long offset) 2667 { 2668 if (tmp) 2669 tmp->tm_isdst = 0; 2670 gmtcheck(); 2671 return time1(tmp, gmtsub, gmtptr, offset); 2672 } 2673 #endif 2674 2675 #if !USE_TIMEX_T 2676 time_t 2677 timegm(struct tm *tmp) 2678 { 2679 time_t t; 2680 struct tm tmcpy; 2681 mktmcpy(&tmcpy, tmp); 2682 tmcpy.tm_wday = -1; 2683 t = timeoff(&tmcpy, 0); 2684 if (0 <= tmcpy.tm_wday) 2685 *tmp = tmcpy; 2686 return t; 2687 } 2688 #endif 2689 2690 static int_fast32_t 2691 leapcorr(struct state const *sp, time_t t) 2692 { 2693 register struct lsinfo const * lp; 2694 register int i; 2695 2696 i = sp->leapcnt; 2697 while (--i >= 0) { 2698 lp = &sp->lsis[i]; 2699 if (t >= lp->ls_trans) 2700 return lp->ls_corr; 2701 } 2702 return 0; 2703 } 2704 2705 /* 2706 ** XXX--is the below the right way to conditionalize?? 2707 */ 2708 2709 #if !USE_TIMEX_T 2710 # if STD_INSPIRED 2711 2712 /* NETBSD_INSPIRED_EXTERN functions are exported to callers if 2713 NETBSD_INSPIRED is defined, and are private otherwise. */ 2714 # if NETBSD_INSPIRED 2715 # define NETBSD_INSPIRED_EXTERN 2716 # else 2717 # define NETBSD_INSPIRED_EXTERN static 2718 # endif 2719 2720 /* 2721 ** IEEE Std 1003.1 (POSIX) says that 536457599 2722 ** shall correspond to "Wed Dec 31 23:59:59 UTC 1986", which 2723 ** is not the case if we are accounting for leap seconds. 2724 ** So, we provide the following conversion routines for use 2725 ** when exchanging timestamps with POSIX conforming systems. 2726 */ 2727 2728 NETBSD_INSPIRED_EXTERN time_t 2729 time2posix_z(struct state *sp, time_t t) 2730 { 2731 return t - leapcorr(sp, t); 2732 } 2733 2734 time_t 2735 time2posix(time_t t) 2736 { 2737 int err = lock(); 2738 if (err) { 2739 errno = err; 2740 return -1; 2741 } 2742 #ifndef DETECT_TZ_CHANGES 2743 if (!lcl_is_set) 2744 #endif /* DETECT_TZ_CHANGES */ 2745 tzset_unlocked(); 2746 if (lclptr) 2747 t = time2posix_z(lclptr, t); 2748 unlock(); 2749 return t; 2750 } 2751 2752 NETBSD_INSPIRED_EXTERN time_t 2753 posix2time_z(struct state *sp, time_t t) 2754 { 2755 time_t x; 2756 time_t y; 2757 /* 2758 ** For a positive leap second hit, the result 2759 ** is not unique. For a negative leap second 2760 ** hit, the corresponding time doesn't exist, 2761 ** so we return an adjacent second. 2762 */ 2763 x = t + leapcorr(sp, t); 2764 y = x - leapcorr(sp, x); 2765 if (y < t) { 2766 do { 2767 x++; 2768 y = x - leapcorr(sp, x); 2769 } while (y < t); 2770 x -= y != t; 2771 } else if (y > t) { 2772 do { 2773 --x; 2774 y = x - leapcorr(sp, x); 2775 } while (y > t); 2776 x += y != t; 2777 } 2778 return x; 2779 } 2780 2781 time_t 2782 posix2time(time_t t) 2783 { 2784 int err = lock(); 2785 if (err) { 2786 errno = err; 2787 return -1; 2788 } 2789 #ifndef DETECT_TZ_CHANGES 2790 if (!lcl_is_set) 2791 #endif /* DETECT_TZ_CHANGES */ 2792 tzset_unlocked(); 2793 if (lclptr) 2794 t = posix2time_z(lclptr, t); 2795 unlock(); 2796 return t; 2797 } 2798 2799 # endif /* STD_INSPIRED */ 2800 2801 # if TZ_TIME_T 2802 2803 # if !USG_COMPAT 2804 # define timezone 0 2805 # endif 2806 2807 /* Convert from the underlying system's time_t to the ersatz time_tz, 2808 which is called 'time_t' in this file. Typically, this merely 2809 converts the time's integer width. On some platforms, the system 2810 time is local time not UT, or uses some epoch other than the POSIX 2811 epoch. 2812 2813 Although this code appears to define a function named 'time' that 2814 returns time_t, the macros in private.h cause this code to actually 2815 define a function named 'tz_time' that returns tz_time_t. The call 2816 to sys_time invokes the underlying system's 'time' function. */ 2817 2818 time_t 2819 time(time_t *p) 2820 { 2821 time_t r = sys_time(0); 2822 if (r != (time_t) -1) { 2823 iinntt offset = EPOCH_LOCAL ? timezone : 0; 2824 if (offset < IINNTT_MIN + EPOCH_OFFSET 2825 || increment_overflow_time_iinntt(&r, offset - EPOCH_OFFSET)) { 2826 errno = EOVERFLOW; 2827 r = -1; 2828 } 2829 } 2830 if (p) 2831 *p = r; 2832 return r; 2833 } 2834 2835 # endif 2836 #endif 2837