Home | History | Annotate | Download | only in tzcode
      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;
     51 static inline void _tzLock(void) { pthread_mutex_lock(&_tzMutex); }
     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
    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
    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
    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
    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
    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
    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 *
    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 *
    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 *
    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 *
    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 *
    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 *
    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
    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
    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
   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
   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
   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
   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 *
   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 *
   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 *
   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 *
   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 *
   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 *
   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
   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 *
   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 *
   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 *
   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
   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
   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
   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
   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
   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
   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
   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
   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
   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
   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
   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
   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
   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
   2066 time2posix(time_t t)
   2067 {
   2068     tzset();
   2069     return t - leapcorr(&t);
   2070 }
   2071 
   2072 time_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 
   2113 static int to_int(unsigned char* s) {
   2114   return (s[0] << 24) | (s[1] << 16) | (s[2] << 8) | s[3];
   2115 }
   2116 
   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 
   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).
   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.
   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.
   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