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