"Fossies" - the Fresh Open Source Software Archive

Member "localtime.c" (21 Nov 2022, 64813 Bytes) of package /linux/misc/tzcode2022g.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. See also the latest Fossies "Diffs" side-by-side code changes report for "localtime.c": 2022f_vs_2022g.

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