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