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 int err = zoneinit(sp, name, TZLOAD_FROMENV | TZLOAD_TZSTRING); 1653 if (err != 0) { 1654 zoneinit(sp, "", 0); 1655 /* Abbreviate with "-00" if there was an error. 1656 Do not treat a missing TZDEFAULT file as an error. */ 1657 if (name || err != ENOENT) 1658 strcpy(sp->chars, UNSPEC); 1659 } 1660 if (0 < lcl) 1661 strcpy(lcl_TZname, name); 1662 } 1663 settzname(); 1664 lcl_is_set = lcl; 1665 } 1666 1667 #endif 1668 1669 #if !USE_TIMEX_T 1670 void 1671 tzset(void) 1672 { 1673 if (lock() != 0) 1674 return; 1675 tzset_unlocked(); 1676 unlock(); 1677 } 1678 #endif 1679 1680 #ifdef __FreeBSD__ 1681 void 1682 freebsd13_tzsetwall(void) 1683 { 1684 if (lock() != 0) 1685 return; 1686 tzset_unlocked_name(NULL); 1687 unlock(); 1688 } 1689 __sym_compat(tzsetwall, freebsd13_tzsetwall, FBSD_1.0); 1690 __warn_references(tzsetwall, 1691 "warning: tzsetwall() is deprecated, use tzset() instead."); 1692 #endif /* __FreeBSD__ */ 1693 static void 1694 gmtcheck(void) 1695 { 1696 static bool gmt_is_set; 1697 if (lock() != 0) 1698 return; 1699 if (! gmt_is_set) { 1700 #ifdef ALL_STATE 1701 gmtptr = malloc(sizeof *gmtptr); 1702 #endif 1703 if (gmtptr) 1704 gmtload(gmtptr); 1705 gmt_is_set = true; 1706 } 1707 unlock(); 1708 } 1709 #ifdef __FreeBSD__ 1710 #define gmtcheck() _once(&gmt_once, gmtcheck) 1711 #endif 1712 1713 #if NETBSD_INSPIRED && !USE_TIMEX_T 1714 1715 timezone_t 1716 tzalloc(char const *name) 1717 { 1718 timezone_t sp = malloc(sizeof *sp); 1719 if (sp) { 1720 int err = zoneinit(sp, name, TZLOAD_TZSTRING); 1721 if (err != 0) { 1722 free(sp); 1723 errno = err; 1724 return NULL; 1725 } 1726 } else if (!HAVE_MALLOC_ERRNO) 1727 errno = ENOMEM; 1728 return sp; 1729 } 1730 1731 void 1732 tzfree(timezone_t sp) 1733 { 1734 free(sp); 1735 } 1736 1737 /* 1738 ** NetBSD 6.1.4 has ctime_rz, but omit it because C23 deprecates ctime and 1739 ** POSIX.1-2024 removes ctime_r. Both have potential security problems that 1740 ** ctime_rz would share. Callers can instead use localtime_rz + strftime. 1741 ** 1742 ** NetBSD 6.1.4 has tzgetname, but omit it because it doesn't work 1743 ** in zones with three or more time zone abbreviations. 1744 ** Callers can instead use localtime_rz + strftime. 1745 */ 1746 1747 #endif 1748 1749 #if !USE_TIMEX_T || !defined TM_GMTOFF 1750 1751 /* 1752 ** The easy way to behave "as if no library function calls" localtime 1753 ** is to not call it, so we drop its guts into "localsub", which can be 1754 ** freely called. (And no, the PANS doesn't require the above behavior, 1755 ** but it *is* desirable.) 1756 ** 1757 ** If successful and SETNAME is nonzero, 1758 ** set the applicable parts of tzname, timezone and altzone; 1759 ** however, it's OK to omit this step for proleptic TZ strings 1760 ** since in that case tzset should have already done this step correctly. 1761 ** SETNAME's type is int_fast32_t for compatibility with gmtsub, 1762 ** but it is actually a boolean and its value should be 0 or 1. 1763 */ 1764 1765 /*ARGSUSED*/ 1766 static struct tm * 1767 localsub(struct state const *sp, time_t const *timep, int_fast32_t setname, 1768 struct tm *const tmp) 1769 { 1770 register const struct ttinfo * ttisp; 1771 register int i; 1772 register struct tm * result; 1773 const time_t t = *timep; 1774 1775 if (sp == NULL) { 1776 /* Don't bother to set tzname etc.; tzset has already done it. */ 1777 return gmtsub(gmtptr, timep, 0, tmp); 1778 } 1779 if ((sp->goback && t < sp->ats[0]) || 1780 (sp->goahead && t > sp->ats[sp->timecnt - 1])) { 1781 time_t newt; 1782 register time_t seconds; 1783 register time_t years; 1784 1785 if (t < sp->ats[0]) 1786 seconds = sp->ats[0] - t; 1787 else seconds = t - sp->ats[sp->timecnt - 1]; 1788 --seconds; 1789 1790 /* Beware integer overflow, as SECONDS might 1791 be close to the maximum time_t. */ 1792 years = seconds / SECSPERREPEAT * YEARSPERREPEAT; 1793 seconds = years * AVGSECSPERYEAR; 1794 years += YEARSPERREPEAT; 1795 if (t < sp->ats[0]) 1796 newt = t + seconds + SECSPERREPEAT; 1797 else 1798 newt = t - seconds - SECSPERREPEAT; 1799 1800 if (newt < sp->ats[0] || 1801 newt > sp->ats[sp->timecnt - 1]) 1802 return NULL; /* "cannot happen" */ 1803 result = localsub(sp, &newt, setname, tmp); 1804 if (result) { 1805 # if defined ckd_add && defined ckd_sub 1806 if (t < sp->ats[0] 1807 ? ckd_sub(&result->tm_year, 1808 result->tm_year, years) 1809 : ckd_add(&result->tm_year, 1810 result->tm_year, years)) 1811 return NULL; 1812 # else 1813 register int_fast64_t newy; 1814 1815 newy = result->tm_year; 1816 if (t < sp->ats[0]) 1817 newy -= years; 1818 else newy += years; 1819 if (! (INT_MIN <= newy && newy <= INT_MAX)) 1820 return NULL; 1821 result->tm_year = newy; 1822 # endif 1823 } 1824 return result; 1825 } 1826 if (sp->timecnt == 0 || t < sp->ats[0]) { 1827 i = 0; 1828 } else { 1829 register int lo = 1; 1830 register int hi = sp->timecnt; 1831 1832 while (lo < hi) { 1833 register int mid = (lo + hi) >> 1; 1834 1835 if (t < sp->ats[mid]) 1836 hi = mid; 1837 else lo = mid + 1; 1838 } 1839 i = sp->types[lo - 1]; 1840 } 1841 ttisp = &sp->ttis[i]; 1842 /* 1843 ** To get (wrong) behavior that's compatible with System V Release 2.0 1844 ** you'd replace the statement below with 1845 ** t += ttisp->tt_utoff; 1846 ** timesub(&t, 0L, sp, tmp); 1847 */ 1848 result = timesub(&t, ttisp->tt_utoff, sp, tmp); 1849 if (result) { 1850 result->tm_isdst = ttisp->tt_isdst; 1851 # ifdef TM_ZONE 1852 result->TM_ZONE = UNCONST(&sp->chars[ttisp->tt_desigidx]); 1853 # endif 1854 if (setname) 1855 update_tzname_etc(sp, ttisp); 1856 } 1857 return result; 1858 } 1859 #endif 1860 1861 #if !USE_TIMEX_T 1862 1863 # if NETBSD_INSPIRED 1864 struct tm * 1865 localtime_rz(struct state *restrict sp, time_t const *restrict timep, 1866 struct tm *restrict tmp) 1867 { 1868 return localsub(sp, timep, 0, tmp); 1869 } 1870 # endif 1871 1872 static struct tm * 1873 localtime_tzset(time_t const *timep, struct tm *tmp, bool setname) 1874 { 1875 int err = lock(); 1876 if (err) { 1877 errno = err; 1878 return NULL; 1879 } 1880 #ifndef DETECT_TZ_CHANGES 1881 if (setname || !lcl_is_set) 1882 #endif /* DETECT_TZ_CHANGES */ 1883 tzset_unlocked(); 1884 tmp = localsub(lclptr, timep, setname, tmp); 1885 unlock(); 1886 return tmp; 1887 } 1888 1889 #ifdef __FreeBSD__ 1890 static void 1891 localtime_key_init(void) 1892 { 1893 localtime_key_error = _pthread_key_create(&localtime_key, free); 1894 } 1895 #endif /* __FreeBSD__ */ 1896 struct tm * 1897 localtime(const time_t *timep) 1898 { 1899 # if !SUPPORT_C89 1900 static struct tm tm; 1901 # endif 1902 #ifdef __FreeBSD__ 1903 struct tm *p_tm = &tm; 1904 1905 if (__isthreaded != 0) { 1906 _pthread_once(&localtime_once, localtime_key_init); 1907 if (localtime_key_error != 0) { 1908 errno = localtime_key_error; 1909 return (NULL); 1910 } 1911 if ((p_tm = _pthread_getspecific(localtime_key)) == NULL) { 1912 if ((p_tm = malloc(sizeof(*p_tm))) == NULL) { 1913 return (NULL); 1914 } 1915 if (_pthread_setspecific(localtime_key, p_tm) != 0) { 1916 free(p_tm); 1917 return (NULL); 1918 } 1919 } 1920 } 1921 #endif /* __FreeBSD__ */ 1922 return localtime_tzset(timep, p_tm, true); 1923 } 1924 1925 struct tm * 1926 localtime_r(const time_t *restrict timep, struct tm *restrict tmp) 1927 { 1928 return localtime_tzset(timep, tmp, false); 1929 } 1930 #endif 1931 1932 /* 1933 ** gmtsub is to gmtime as localsub is to localtime. 1934 */ 1935 1936 static struct tm * 1937 gmtsub(ATTRIBUTE_MAYBE_UNUSED struct state const *sp, time_t const *timep, 1938 int_fast32_t offset, struct tm *tmp) 1939 { 1940 register struct tm * result; 1941 1942 result = timesub(timep, offset, gmtptr, tmp); 1943 #ifdef TM_ZONE 1944 /* 1945 ** Could get fancy here and deliver something such as 1946 ** "+xx" or "-xx" if offset is non-zero, 1947 ** but this is no time for a treasure hunt. 1948 */ 1949 tmp->TM_ZONE = UNCONST(offset ? wildabbr 1950 : gmtptr ? gmtptr->chars : utc); 1951 #endif /* defined TM_ZONE */ 1952 return result; 1953 } 1954 1955 #if !USE_TIMEX_T 1956 1957 /* 1958 * Re-entrant version of gmtime. 1959 */ 1960 1961 struct tm * 1962 gmtime_r(time_t const *restrict timep, struct tm *restrict tmp) 1963 { 1964 gmtcheck(); 1965 return gmtsub(gmtptr, timep, 0, tmp); 1966 } 1967 1968 #ifdef __FreeBSD__ 1969 static void 1970 gmtime_key_init(void) 1971 { 1972 gmtime_key_error = _pthread_key_create(&gmtime_key, free); 1973 } 1974 #endif /* __FreeBSD__ */ 1975 struct tm * 1976 gmtime(const time_t *timep) 1977 { 1978 # if !SUPPORT_C89 1979 static struct tm tm; 1980 # endif 1981 #ifdef __FreeBSD__ 1982 struct tm *p_tm = &tm; 1983 1984 if (__isthreaded != 0) { 1985 _pthread_once(&gmtime_once, gmtime_key_init); 1986 if (gmtime_key_error != 0) { 1987 errno = gmtime_key_error; 1988 return (NULL); 1989 } 1990 if ((p_tm = _pthread_getspecific(gmtime_key)) == NULL) { 1991 if ((p_tm = malloc(sizeof(*p_tm))) == NULL) { 1992 return (NULL); 1993 } 1994 if (_pthread_setspecific(gmtime_key, p_tm) != 0) { 1995 free(p_tm); 1996 return (NULL); 1997 } 1998 } 1999 } 2000 #endif /* __FreeBSD__ */ 2001 return gmtime_r(timep, p_tm); 2002 } 2003 2004 # if STD_INSPIRED 2005 2006 /* This function is obsolescent and may disappear in future releases. 2007 Callers can instead use localtime_rz with a fixed-offset zone. */ 2008 2009 struct tm * 2010 offtime_r(time_t const *restrict timep, long offset, struct tm *restrict tmp) 2011 { 2012 gmtcheck(); 2013 return gmtsub(gmtptr, timep, offset, tmp); 2014 } 2015 2016 #ifdef __FreeBSD__ 2017 static void 2018 offtime_key_init(void) 2019 { 2020 offtime_key_error = _pthread_key_create(&offtime_key, free); 2021 } 2022 #endif /* __FreeBSD__ */ 2023 struct tm * 2024 offtime(time_t const *timep, long offset) 2025 { 2026 # if !SUPPORT_C89 2027 static struct tm tm; 2028 # endif 2029 #ifdef __FreeBSD__ 2030 struct tm *p_tm = &tm; 2031 2032 if (__isthreaded != 0) { 2033 _pthread_once(&offtime_once, offtime_key_init); 2034 if (offtime_key_error != 0) { 2035 errno = offtime_key_error; 2036 return (NULL); 2037 } 2038 if ((p_tm = _pthread_getspecific(offtime_key)) == NULL) { 2039 if ((p_tm = malloc(sizeof(*p_tm))) == NULL) { 2040 return (NULL); 2041 } 2042 if (_pthread_setspecific(offtime_key, p_tm) != 0) { 2043 free(p_tm); 2044 return (NULL); 2045 } 2046 } 2047 } 2048 #endif 2049 return offtime_r(timep, offset, p_tm); 2050 } 2051 2052 # endif 2053 #endif 2054 2055 /* 2056 ** Return the number of leap years through the end of the given year 2057 ** where, to make the math easy, the answer for year zero is defined as zero. 2058 */ 2059 2060 static time_t 2061 leaps_thru_end_of_nonneg(time_t y) 2062 { 2063 return y / 4 - y / 100 + y / 400; 2064 } 2065 2066 static time_t 2067 leaps_thru_end_of(time_t y) 2068 { 2069 return (y < 0 2070 ? -1 - leaps_thru_end_of_nonneg(-1 - y) 2071 : leaps_thru_end_of_nonneg(y)); 2072 } 2073 2074 static struct tm * 2075 timesub(const time_t *timep, int_fast32_t offset, 2076 const struct state *sp, struct tm *tmp) 2077 { 2078 register const struct lsinfo * lp; 2079 register time_t tdays; 2080 register const int * ip; 2081 register int_fast32_t corr; 2082 register int i; 2083 int_fast32_t idays, rem, dayoff, dayrem; 2084 time_t y; 2085 2086 /* If less than SECSPERMIN, the number of seconds since the 2087 most recent positive leap second; otherwise, do not add 1 2088 to localtime tm_sec because of leap seconds. */ 2089 time_t secs_since_posleap = SECSPERMIN; 2090 2091 corr = 0; 2092 i = (sp == NULL) ? 0 : sp->leapcnt; 2093 while (--i >= 0) { 2094 lp = &sp->lsis[i]; 2095 if (*timep >= lp->ls_trans) { 2096 corr = lp->ls_corr; 2097 if ((i == 0 ? 0 : lp[-1].ls_corr) < corr) 2098 secs_since_posleap = *timep - lp->ls_trans; 2099 break; 2100 } 2101 } 2102 2103 /* Calculate the year, avoiding integer overflow even if 2104 time_t is unsigned. */ 2105 tdays = *timep / SECSPERDAY; 2106 rem = *timep % SECSPERDAY; 2107 rem += offset % SECSPERDAY - corr % SECSPERDAY + 3 * SECSPERDAY; 2108 dayoff = offset / SECSPERDAY - corr / SECSPERDAY + rem / SECSPERDAY - 3; 2109 rem %= SECSPERDAY; 2110 /* y = (EPOCH_YEAR 2111 + floor((tdays + dayoff) / DAYSPERREPEAT) * YEARSPERREPEAT), 2112 sans overflow. But calculate against 1570 (EPOCH_YEAR - 2113 YEARSPERREPEAT) instead of against 1970 so that things work 2114 for localtime values before 1970 when time_t is unsigned. */ 2115 dayrem = tdays % DAYSPERREPEAT; 2116 dayrem += dayoff % DAYSPERREPEAT; 2117 y = (EPOCH_YEAR - YEARSPERREPEAT 2118 + ((1 + dayoff / DAYSPERREPEAT + dayrem / DAYSPERREPEAT 2119 - ((dayrem % DAYSPERREPEAT) < 0) 2120 + tdays / DAYSPERREPEAT) 2121 * YEARSPERREPEAT)); 2122 /* idays = (tdays + dayoff) mod DAYSPERREPEAT, sans overflow. */ 2123 idays = tdays % DAYSPERREPEAT; 2124 idays += dayoff % DAYSPERREPEAT + 2 * DAYSPERREPEAT; 2125 idays %= DAYSPERREPEAT; 2126 /* Increase Y and decrease IDAYS until IDAYS is in range for Y. */ 2127 while (year_lengths[isleap(y)] <= idays) { 2128 int tdelta = idays / DAYSPERLYEAR; 2129 int_fast32_t ydelta = tdelta + !tdelta; 2130 time_t newy = y + ydelta; 2131 register int leapdays; 2132 leapdays = leaps_thru_end_of(newy - 1) - 2133 leaps_thru_end_of(y - 1); 2134 idays -= ydelta * DAYSPERNYEAR; 2135 idays -= leapdays; 2136 y = newy; 2137 } 2138 2139 #ifdef ckd_add 2140 if (ckd_add(&tmp->tm_year, y, -TM_YEAR_BASE)) { 2141 errno = EOVERFLOW; 2142 return NULL; 2143 } 2144 #else 2145 if (!TYPE_SIGNED(time_t) && y < TM_YEAR_BASE) { 2146 int signed_y = y; 2147 tmp->tm_year = signed_y - TM_YEAR_BASE; 2148 } else if ((!TYPE_SIGNED(time_t) || INT_MIN + TM_YEAR_BASE <= y) 2149 && y - TM_YEAR_BASE <= INT_MAX) 2150 tmp->tm_year = y - TM_YEAR_BASE; 2151 else { 2152 errno = EOVERFLOW; 2153 return NULL; 2154 } 2155 #endif 2156 tmp->tm_yday = idays; 2157 /* 2158 ** The "extra" mods below avoid overflow problems. 2159 */ 2160 tmp->tm_wday = (TM_WDAY_BASE 2161 + ((tmp->tm_year % DAYSPERWEEK) 2162 * (DAYSPERNYEAR % DAYSPERWEEK)) 2163 + leaps_thru_end_of(y - 1) 2164 - leaps_thru_end_of(TM_YEAR_BASE - 1) 2165 + idays); 2166 tmp->tm_wday %= DAYSPERWEEK; 2167 if (tmp->tm_wday < 0) 2168 tmp->tm_wday += DAYSPERWEEK; 2169 tmp->tm_hour = rem / SECSPERHOUR; 2170 rem %= SECSPERHOUR; 2171 tmp->tm_min = rem / SECSPERMIN; 2172 tmp->tm_sec = rem % SECSPERMIN; 2173 2174 /* Use "... ??:??:60" at the end of the localtime minute containing 2175 the second just before the positive leap second. */ 2176 tmp->tm_sec += secs_since_posleap <= tmp->tm_sec; 2177 2178 ip = mon_lengths[isleap(y)]; 2179 for (tmp->tm_mon = 0; idays >= ip[tmp->tm_mon]; ++(tmp->tm_mon)) 2180 idays -= ip[tmp->tm_mon]; 2181 tmp->tm_mday = idays + 1; 2182 tmp->tm_isdst = 0; 2183 #ifdef TM_GMTOFF 2184 tmp->TM_GMTOFF = offset; 2185 #endif /* defined TM_GMTOFF */ 2186 return tmp; 2187 } 2188 2189 /* 2190 ** Adapted from code provided by Robert Elz, who writes: 2191 ** The "best" way to do mktime I think is based on an idea of Bob 2192 ** Kridle's (so its said...) from a long time ago. 2193 ** It does a binary search of the time_t space. Since time_t's are 2194 ** just 32 bits, its a max of 32 iterations (even at 64 bits it 2195 ** would still be very reasonable). 2196 */ 2197 2198 #ifndef WRONG 2199 # define WRONG (-1) 2200 #endif /* !defined WRONG */ 2201 2202 /* 2203 ** Normalize logic courtesy Paul Eggert. 2204 */ 2205 2206 static bool 2207 increment_overflow(int *ip, int j) 2208 { 2209 #ifdef ckd_add 2210 return ckd_add(ip, *ip, j); 2211 #else 2212 register int const i = *ip; 2213 2214 /* 2215 ** If i >= 0 there can only be overflow if i + j > INT_MAX 2216 ** or if j > INT_MAX - i; given i >= 0, INT_MAX - i cannot overflow. 2217 ** If i < 0 there can only be overflow if i + j < INT_MIN 2218 ** or if j < INT_MIN - i; given i < 0, INT_MIN - i cannot overflow. 2219 */ 2220 if ((i >= 0) ? (j > INT_MAX - i) : (j < INT_MIN - i)) 2221 return true; 2222 *ip += j; 2223 return false; 2224 #endif 2225 } 2226 2227 static bool 2228 increment_overflow_time_iinntt(time_t *tp, iinntt j) 2229 { 2230 #ifdef ckd_add 2231 return ckd_add(tp, *tp, j); 2232 #else 2233 if (j < 0 2234 ? (TYPE_SIGNED(time_t) ? *tp < TIME_T_MIN - j : *tp <= -1 - j) 2235 : TIME_T_MAX - j < *tp) 2236 return true; 2237 *tp += j; 2238 return false; 2239 #endif 2240 } 2241 2242 static bool 2243 increment_overflow_time(time_t *tp, int_fast32_t j) 2244 { 2245 #ifdef ckd_add 2246 return ckd_add(tp, *tp, j); 2247 #else 2248 /* 2249 ** This is like 2250 ** 'if (! (TIME_T_MIN <= *tp + j && *tp + j <= TIME_T_MAX)) ...', 2251 ** except that it does the right thing even if *tp + j would overflow. 2252 */ 2253 if (! (j < 0 2254 ? (TYPE_SIGNED(time_t) ? TIME_T_MIN - j <= *tp : -1 - j < *tp) 2255 : *tp <= TIME_T_MAX - j)) 2256 return true; 2257 *tp += j; 2258 return false; 2259 #endif 2260 } 2261 2262 static int 2263 tmcomp(register const struct tm *const atmp, 2264 register const struct tm *const btmp) 2265 { 2266 register int result; 2267 2268 if (atmp->tm_year != btmp->tm_year) 2269 return atmp->tm_year < btmp->tm_year ? -1 : 1; 2270 if ((result = (atmp->tm_mon - btmp->tm_mon)) == 0 && 2271 (result = (atmp->tm_mday - btmp->tm_mday)) == 0 && 2272 (result = (atmp->tm_hour - btmp->tm_hour)) == 0 && 2273 (result = (atmp->tm_min - btmp->tm_min)) == 0) 2274 result = atmp->tm_sec - btmp->tm_sec; 2275 return result; 2276 } 2277 2278 /* Copy to *DEST from *SRC. Copy only the members needed for mktime, 2279 as other members might not be initialized. */ 2280 static void 2281 mktmcpy(struct tm *dest, struct tm const *src) 2282 { 2283 dest->tm_sec = src->tm_sec; 2284 dest->tm_min = src->tm_min; 2285 dest->tm_hour = src->tm_hour; 2286 dest->tm_mday = src->tm_mday; 2287 dest->tm_mon = src->tm_mon; 2288 dest->tm_year = src->tm_year; 2289 dest->tm_isdst = src->tm_isdst; 2290 #if defined TM_GMTOFF && ! UNINIT_TRAP 2291 dest->TM_GMTOFF = src->TM_GMTOFF; 2292 #endif 2293 } 2294 2295 static time_t 2296 time2sub(struct tm *const tmp, 2297 struct tm *(*funcp)(struct state const *, time_t const *, 2298 int_fast32_t, struct tm *), 2299 struct state const *sp, 2300 const int_fast32_t offset, 2301 bool *okayp, 2302 bool do_norm_secs) 2303 { 2304 register int dir; 2305 register int i, j; 2306 register time_t lo; 2307 register time_t hi; 2308 iinntt y, mday, hour, min, saved_seconds; 2309 time_t newt; 2310 time_t t; 2311 struct tm yourtm, mytm; 2312 2313 *okayp = false; 2314 mktmcpy(&yourtm, tmp); 2315 2316 min = yourtm.tm_min; 2317 if (do_norm_secs) { 2318 min += yourtm.tm_sec / SECSPERMIN; 2319 yourtm.tm_sec %= SECSPERMIN; 2320 if (yourtm.tm_sec < 0) { 2321 yourtm.tm_sec += SECSPERMIN; 2322 min--; 2323 } 2324 } 2325 2326 hour = yourtm.tm_hour; 2327 hour += min / MINSPERHOUR; 2328 yourtm.tm_min = min % MINSPERHOUR; 2329 if (yourtm.tm_min < 0) { 2330 yourtm.tm_min += MINSPERHOUR; 2331 hour--; 2332 } 2333 2334 mday = yourtm.tm_mday; 2335 mday += hour / HOURSPERDAY; 2336 yourtm.tm_hour = hour % HOURSPERDAY; 2337 if (yourtm.tm_hour < 0) { 2338 yourtm.tm_hour += HOURSPERDAY; 2339 mday--; 2340 } 2341 2342 y = yourtm.tm_year; 2343 y += yourtm.tm_mon / MONSPERYEAR; 2344 yourtm.tm_mon %= MONSPERYEAR; 2345 if (yourtm.tm_mon < 0) { 2346 yourtm.tm_mon += MONSPERYEAR; 2347 y--; 2348 } 2349 2350 /* 2351 ** Turn y into an actual year number for now. 2352 ** It is converted back to an offset from TM_YEAR_BASE later. 2353 */ 2354 y += TM_YEAR_BASE; 2355 2356 while (mday <= 0) { 2357 iinntt li = y - (yourtm.tm_mon <= 1); 2358 mday += year_lengths[isleap(li)]; 2359 y--; 2360 } 2361 while (DAYSPERLYEAR < mday) { 2362 iinntt li = y + (1 < yourtm.tm_mon); 2363 mday -= year_lengths[isleap(li)]; 2364 y++; 2365 } 2366 yourtm.tm_mday = mday; 2367 for ( ; ; ) { 2368 i = mon_lengths[isleap(y)][yourtm.tm_mon]; 2369 if (yourtm.tm_mday <= i) 2370 break; 2371 yourtm.tm_mday -= i; 2372 if (++yourtm.tm_mon >= MONSPERYEAR) { 2373 yourtm.tm_mon = 0; 2374 y++; 2375 } 2376 } 2377 #ifdef ckd_add 2378 if (ckd_add(&yourtm.tm_year, y, -TM_YEAR_BASE)) 2379 return WRONG; 2380 #else 2381 y -= TM_YEAR_BASE; 2382 if (! (INT_MIN <= y && y <= INT_MAX)) 2383 return WRONG; 2384 yourtm.tm_year = y; 2385 #endif 2386 if (yourtm.tm_sec >= 0 && yourtm.tm_sec < SECSPERMIN) 2387 saved_seconds = 0; 2388 else if (yourtm.tm_year < EPOCH_YEAR - TM_YEAR_BASE) { 2389 /* 2390 ** We can't set tm_sec to 0, because that might push the 2391 ** time below the minimum representable time. 2392 ** Set tm_sec to 59 instead. 2393 ** This assumes that the minimum representable time is 2394 ** not in the same minute that a leap second was deleted from, 2395 ** which is a safer assumption than using 58 would be. 2396 */ 2397 saved_seconds = yourtm.tm_sec; 2398 saved_seconds -= SECSPERMIN - 1; 2399 yourtm.tm_sec = SECSPERMIN - 1; 2400 } else { 2401 saved_seconds = yourtm.tm_sec; 2402 yourtm.tm_sec = 0; 2403 } 2404 /* 2405 ** Do a binary search (this works whatever time_t's type is). 2406 */ 2407 lo = TIME_T_MIN; 2408 hi = TIME_T_MAX; 2409 for ( ; ; ) { 2410 t = lo / 2 + hi / 2; 2411 if (t < lo) 2412 t = lo; 2413 else if (t > hi) 2414 t = hi; 2415 if (! funcp(sp, &t, offset, &mytm)) { 2416 /* 2417 ** Assume that t is too extreme to be represented in 2418 ** a struct tm; arrange things so that it is less 2419 ** extreme on the next pass. 2420 */ 2421 dir = (t > 0) ? 1 : -1; 2422 } else dir = tmcomp(&mytm, &yourtm); 2423 if (dir != 0) { 2424 if (t == lo) { 2425 if (t == TIME_T_MAX) 2426 return WRONG; 2427 ++t; 2428 ++lo; 2429 } else if (t == hi) { 2430 if (t == TIME_T_MIN) 2431 return WRONG; 2432 --t; 2433 --hi; 2434 } 2435 if (lo > hi) 2436 return WRONG; 2437 if (dir > 0) 2438 hi = t; 2439 else lo = t; 2440 continue; 2441 } 2442 #if defined TM_GMTOFF && ! UNINIT_TRAP 2443 if (mytm.TM_GMTOFF != yourtm.TM_GMTOFF 2444 && (yourtm.TM_GMTOFF < 0 2445 ? (-SECSPERDAY <= yourtm.TM_GMTOFF 2446 && (mytm.TM_GMTOFF <= 2447 (min(INT_FAST32_MAX, LONG_MAX) 2448 + yourtm.TM_GMTOFF))) 2449 : (yourtm.TM_GMTOFF <= SECSPERDAY 2450 && ((max(INT_FAST32_MIN, LONG_MIN) 2451 + yourtm.TM_GMTOFF) 2452 <= mytm.TM_GMTOFF)))) { 2453 /* MYTM matches YOURTM except with the wrong UT offset. 2454 YOURTM.TM_GMTOFF is plausible, so try it instead. 2455 It's OK if YOURTM.TM_GMTOFF contains uninitialized data, 2456 since the guess gets checked. */ 2457 time_t altt = t; 2458 int_fast32_t diff = mytm.TM_GMTOFF - yourtm.TM_GMTOFF; 2459 if (!increment_overflow_time(&altt, diff)) { 2460 struct tm alttm; 2461 if (funcp(sp, &altt, offset, &alttm) 2462 && alttm.tm_isdst == mytm.tm_isdst 2463 && alttm.TM_GMTOFF == yourtm.TM_GMTOFF 2464 && tmcomp(&alttm, &yourtm) == 0) { 2465 t = altt; 2466 mytm = alttm; 2467 } 2468 } 2469 } 2470 #endif 2471 if (yourtm.tm_isdst < 0 || mytm.tm_isdst == yourtm.tm_isdst) 2472 break; 2473 /* 2474 ** Right time, wrong type. 2475 ** Hunt for right time, right type. 2476 ** It's okay to guess wrong since the guess 2477 ** gets checked. 2478 */ 2479 if (sp == NULL) 2480 return WRONG; 2481 for (i = sp->typecnt - 1; i >= 0; --i) { 2482 if (sp->ttis[i].tt_isdst != yourtm.tm_isdst) 2483 continue; 2484 for (j = sp->typecnt - 1; j >= 0; --j) { 2485 if (sp->ttis[j].tt_isdst == yourtm.tm_isdst) 2486 continue; 2487 if (ttunspecified(sp, j)) 2488 continue; 2489 newt = (t + sp->ttis[j].tt_utoff 2490 - sp->ttis[i].tt_utoff); 2491 if (! funcp(sp, &newt, offset, &mytm)) 2492 continue; 2493 if (tmcomp(&mytm, &yourtm) != 0) 2494 continue; 2495 if (mytm.tm_isdst != yourtm.tm_isdst) 2496 continue; 2497 /* 2498 ** We have a match. 2499 */ 2500 t = newt; 2501 goto label; 2502 } 2503 } 2504 return WRONG; 2505 } 2506 label: 2507 if (increment_overflow_time_iinntt(&t, saved_seconds)) 2508 return WRONG; 2509 if (funcp(sp, &t, offset, tmp)) 2510 *okayp = true; 2511 return t; 2512 } 2513 2514 static time_t 2515 time2(struct tm * const tmp, 2516 struct tm *(*funcp)(struct state const *, time_t const *, 2517 int_fast32_t, struct tm *), 2518 struct state const *sp, 2519 const int_fast32_t offset, 2520 bool *okayp) 2521 { 2522 time_t t; 2523 2524 /* 2525 ** First try without normalization of seconds 2526 ** (in case tm_sec contains a value associated with a leap second). 2527 ** If that fails, try with normalization of seconds. 2528 */ 2529 t = time2sub(tmp, funcp, sp, offset, okayp, false); 2530 return *okayp ? t : time2sub(tmp, funcp, sp, offset, okayp, true); 2531 } 2532 2533 static time_t 2534 time1(struct tm *const tmp, 2535 struct tm *(*funcp)(struct state const *, time_t const *, 2536 int_fast32_t, struct tm *), 2537 struct state const *sp, 2538 const int_fast32_t offset) 2539 { 2540 register time_t t; 2541 register int samei, otheri; 2542 register int sameind, otherind; 2543 register int i; 2544 register int nseen; 2545 char seen[TZ_MAX_TYPES]; 2546 unsigned char types[TZ_MAX_TYPES]; 2547 bool okay; 2548 2549 if (tmp == NULL) { 2550 errno = EINVAL; 2551 return WRONG; 2552 } 2553 if (tmp->tm_isdst > 1) 2554 tmp->tm_isdst = 1; 2555 t = time2(tmp, funcp, sp, offset, &okay); 2556 if (okay) 2557 return t; 2558 if (tmp->tm_isdst < 0) 2559 #ifdef PCTS 2560 /* 2561 ** POSIX Conformance Test Suite code courtesy Grant Sullivan. 2562 */ 2563 tmp->tm_isdst = 0; /* reset to std and try again */ 2564 #else 2565 return t; 2566 #endif /* !defined PCTS */ 2567 /* 2568 ** We're supposed to assume that somebody took a time of one type 2569 ** and did some math on it that yielded a "struct tm" that's bad. 2570 ** We try to divine the type they started from and adjust to the 2571 ** type they need. 2572 */ 2573 if (sp == NULL) 2574 return WRONG; 2575 for (i = 0; i < sp->typecnt; ++i) 2576 seen[i] = false; 2577 nseen = 0; 2578 for (i = sp->timecnt - 1; i >= 0; --i) 2579 if (!seen[sp->types[i]] && !ttunspecified(sp, sp->types[i])) { 2580 seen[sp->types[i]] = true; 2581 types[nseen++] = sp->types[i]; 2582 } 2583 for (sameind = 0; sameind < nseen; ++sameind) { 2584 samei = types[sameind]; 2585 if (sp->ttis[samei].tt_isdst != tmp->tm_isdst) 2586 continue; 2587 for (otherind = 0; otherind < nseen; ++otherind) { 2588 otheri = types[otherind]; 2589 if (sp->ttis[otheri].tt_isdst == tmp->tm_isdst) 2590 continue; 2591 tmp->tm_sec += (sp->ttis[otheri].tt_utoff 2592 - sp->ttis[samei].tt_utoff); 2593 tmp->tm_isdst = !tmp->tm_isdst; 2594 t = time2(tmp, funcp, sp, offset, &okay); 2595 if (okay) 2596 return t; 2597 tmp->tm_sec -= (sp->ttis[otheri].tt_utoff 2598 - sp->ttis[samei].tt_utoff); 2599 tmp->tm_isdst = !tmp->tm_isdst; 2600 } 2601 } 2602 return WRONG; 2603 } 2604 2605 #if !defined TM_GMTOFF || !USE_TIMEX_T 2606 2607 static time_t 2608 mktime_tzname(struct state *sp, struct tm *tmp, bool setname) 2609 { 2610 if (sp) 2611 return time1(tmp, localsub, sp, setname); 2612 else { 2613 gmtcheck(); 2614 return time1(tmp, gmtsub, gmtptr, 0); 2615 } 2616 } 2617 2618 # if USE_TIMEX_T 2619 static 2620 # endif 2621 time_t 2622 mktime(struct tm *tmp) 2623 { 2624 time_t t; 2625 int err = lock(); 2626 if (err) { 2627 errno = err; 2628 return -1; 2629 } 2630 tzset_unlocked(); 2631 t = mktime_tzname(lclptr, tmp, true); 2632 unlock(); 2633 return t; 2634 } 2635 2636 #endif 2637 2638 #if NETBSD_INSPIRED && !USE_TIMEX_T 2639 time_t 2640 mktime_z(struct state *restrict sp, struct tm *restrict tmp) 2641 { 2642 return mktime_tzname(sp, tmp, false); 2643 } 2644 #endif 2645 2646 #if STD_INSPIRED && !USE_TIMEX_T 2647 /* This function is obsolescent and may disappear in future releases. 2648 Callers can instead use mktime. */ 2649 time_t 2650 timelocal(struct tm *tmp) 2651 { 2652 if (tmp != NULL) 2653 tmp->tm_isdst = -1; /* in case it wasn't initialized */ 2654 return mktime(tmp); 2655 } 2656 #endif 2657 2658 #if defined TM_GMTOFF || !USE_TIMEX_T 2659 2660 # ifndef EXTERN_TIMEOFF 2661 # ifndef timeoff 2662 # define timeoff my_timeoff /* Don't collide with OpenBSD 7.4 <time.h>. */ 2663 # endif 2664 # define EXTERN_TIMEOFF static 2665 # endif 2666 2667 /* This function is obsolescent and may disappear in future releases. 2668 Callers can instead use mktime_z with a fixed-offset zone. */ 2669 EXTERN_TIMEOFF time_t 2670 timeoff(struct tm *tmp, long offset) 2671 { 2672 if (tmp) 2673 tmp->tm_isdst = 0; 2674 gmtcheck(); 2675 return time1(tmp, gmtsub, gmtptr, offset); 2676 } 2677 #endif 2678 2679 #if !USE_TIMEX_T 2680 time_t 2681 timegm(struct tm *tmp) 2682 { 2683 time_t t; 2684 struct tm tmcpy; 2685 mktmcpy(&tmcpy, tmp); 2686 tmcpy.tm_wday = -1; 2687 t = timeoff(&tmcpy, 0); 2688 if (0 <= tmcpy.tm_wday) 2689 *tmp = tmcpy; 2690 return t; 2691 } 2692 #endif 2693 2694 static int_fast32_t 2695 leapcorr(struct state const *sp, time_t t) 2696 { 2697 register struct lsinfo const * lp; 2698 register int i; 2699 2700 i = sp->leapcnt; 2701 while (--i >= 0) { 2702 lp = &sp->lsis[i]; 2703 if (t >= lp->ls_trans) 2704 return lp->ls_corr; 2705 } 2706 return 0; 2707 } 2708 2709 /* 2710 ** XXX--is the below the right way to conditionalize?? 2711 */ 2712 2713 #if !USE_TIMEX_T 2714 # if STD_INSPIRED 2715 2716 /* NETBSD_INSPIRED_EXTERN functions are exported to callers if 2717 NETBSD_INSPIRED is defined, and are private otherwise. */ 2718 # if NETBSD_INSPIRED 2719 # define NETBSD_INSPIRED_EXTERN 2720 # else 2721 # define NETBSD_INSPIRED_EXTERN static 2722 # endif 2723 2724 /* 2725 ** IEEE Std 1003.1 (POSIX) says that 536457599 2726 ** shall correspond to "Wed Dec 31 23:59:59 UTC 1986", which 2727 ** is not the case if we are accounting for leap seconds. 2728 ** So, we provide the following conversion routines for use 2729 ** when exchanging timestamps with POSIX conforming systems. 2730 */ 2731 2732 NETBSD_INSPIRED_EXTERN time_t 2733 time2posix_z(struct state *sp, time_t t) 2734 { 2735 return t - leapcorr(sp, t); 2736 } 2737 2738 time_t 2739 time2posix(time_t t) 2740 { 2741 int err = lock(); 2742 if (err) { 2743 errno = err; 2744 return -1; 2745 } 2746 #ifndef DETECT_TZ_CHANGES 2747 if (!lcl_is_set) 2748 #endif /* DETECT_TZ_CHANGES */ 2749 tzset_unlocked(); 2750 if (lclptr) 2751 t = time2posix_z(lclptr, t); 2752 unlock(); 2753 return t; 2754 } 2755 2756 NETBSD_INSPIRED_EXTERN time_t 2757 posix2time_z(struct state *sp, time_t t) 2758 { 2759 time_t x; 2760 time_t y; 2761 /* 2762 ** For a positive leap second hit, the result 2763 ** is not unique. For a negative leap second 2764 ** hit, the corresponding time doesn't exist, 2765 ** so we return an adjacent second. 2766 */ 2767 x = t + leapcorr(sp, t); 2768 y = x - leapcorr(sp, x); 2769 if (y < t) { 2770 do { 2771 x++; 2772 y = x - leapcorr(sp, x); 2773 } while (y < t); 2774 x -= y != t; 2775 } else if (y > t) { 2776 do { 2777 --x; 2778 y = x - leapcorr(sp, x); 2779 } while (y > t); 2780 x += y != t; 2781 } 2782 return x; 2783 } 2784 2785 time_t 2786 posix2time(time_t t) 2787 { 2788 int err = lock(); 2789 if (err) { 2790 errno = err; 2791 return -1; 2792 } 2793 #ifndef DETECT_TZ_CHANGES 2794 if (!lcl_is_set) 2795 #endif /* DETECT_TZ_CHANGES */ 2796 tzset_unlocked(); 2797 if (lclptr) 2798 t = posix2time_z(lclptr, t); 2799 unlock(); 2800 return t; 2801 } 2802 2803 # endif /* STD_INSPIRED */ 2804 2805 # if TZ_TIME_T 2806 2807 # if !USG_COMPAT 2808 # define timezone 0 2809 # endif 2810 2811 /* Convert from the underlying system's time_t to the ersatz time_tz, 2812 which is called 'time_t' in this file. Typically, this merely 2813 converts the time's integer width. On some platforms, the system 2814 time is local time not UT, or uses some epoch other than the POSIX 2815 epoch. 2816 2817 Although this code appears to define a function named 'time' that 2818 returns time_t, the macros in private.h cause this code to actually 2819 define a function named 'tz_time' that returns tz_time_t. The call 2820 to sys_time invokes the underlying system's 'time' function. */ 2821 2822 time_t 2823 time(time_t *p) 2824 { 2825 time_t r = sys_time(0); 2826 if (r != (time_t) -1) { 2827 iinntt offset = EPOCH_LOCAL ? timezone : 0; 2828 if (offset < IINNTT_MIN + EPOCH_OFFSET 2829 || increment_overflow_time_iinntt(&r, offset - EPOCH_OFFSET)) { 2830 errno = EOVERFLOW; 2831 r = -1; 2832 } 2833 } 2834 if (p) 2835 *p = r; 2836 return r; 2837 } 2838 2839 # endif 2840 #endif 2841