"Fossies" - the Fresh Open Source Software Archive

Member "localtime.c" (1 Nov 2018, 59587 Bytes) of package /linux/misc/tzcode2018i.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. For more information about "localtime.c" see the Fossies "Dox" file reference documentation and the last Fossies "Diffs" side-by-side code changes report: 2018g_vs_2018h.

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