Bug Summary

File:src/lib/libc/time/localtime.c
Warning:line 227, column 20
The result of the left shift is undefined because the left operand is negative

Annotated Source Code

Press '?' to see keyboard shortcuts

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