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