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