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