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