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