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