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