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