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