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