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