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