Bug Summary

File:src/lib/libc/time/localtime.c
Warning:line 1486, column 30
The right operand of '>=' is a garbage value

Annotated Source Code

Press '?' to see keyboard shortcuts

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