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