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