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