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