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>
21static pthread_mutex_t locallock = PTHREAD_MUTEX_INITIALIZER;
22static int lock(void) { return pthread_mutex_lock(&locallock); }
23static void unlock(void) { pthread_mutex_unlock(&locallock); }
24#else
25static int lock(void) { return 0; }
26static 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
84static const char       wildabbr[] = WILDABBR;
85
86static 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
99struct 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
107struct 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
122struct 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
138enum 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
144struct 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
152static struct tm *gmtsub(struct state const *, time_t const *, int_fast32_t,
153			 struct tm *);
154static bool increment_overflow(int *, int);
155static bool increment_overflow_time(time_t *, int_fast32_t);
156static bool normalize_overflow32(int_fast32_t *, int *, int);
157static struct tm *timesub(time_t const *, int_fast32_t, struct state const *,
158			  struct tm *);
159static bool typesequiv(struct state const *, int, int);
160static bool tzparse(char const *, struct state *, bool);
161
162#ifdef ALL_STATE
163static struct state * lclptr;
164static struct state * gmtptr;
165#endif /* defined ALL_STATE */
166
167#ifndef ALL_STATE
168static struct state lclmem;
169static 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
178static char lcl_TZname[TZ_STRLEN_MAX + 1];
179static int  lcl_is_set;
180
181char * 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
194static struct tm	tm;
195
196#ifdef USG_COMPAT
197long			timezone;
198int			daylight;
199#endif /* defined USG_COMPAT */
200
201#ifdef ALTZONE
202long			altzone;
203#endif /* defined ALTZONE */
204
205/* Initialize *S to a value based on GMTOFF, ISDST, and ABBRIND.  */
206static void
207init_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
216static int_fast32_t
217detzcode(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
239static int_fast64_t
240detzcode64(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
262static void
263update_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
276static void
277settzname(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
313static void
314scrub_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
336static bool
337differ_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.  */
347union 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'.  */
357union 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
371static int __bionic_open_tzdata(const char*, int32_t*);
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.  */
376static int
377tzloadbody(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(__BIONIC__)
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 = 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.  */
685static int
686tzload(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
703static bool
704typesequiv(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
725static 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
730static 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
740static const char * ATTRIBUTE_PURE
741getzname(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
760static const char * ATTRIBUTE_PURE
761getqzname(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
777static const char *
778getnum(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
806static const char *
807getsecs(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
846static const char *
847getoffset(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
871static const char *
872getrule(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
922static int_fast32_t ATTRIBUTE_PURE
923transtime(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
1013static bool
1014tzparse(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
1246static void
1247gmtload(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.  */
1255static int
1256zoneinit(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
1281static void
1282tzsetlcl(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
1305void
1306tzsetwall(void)
1307{
1308  if (lock() != 0)
1309    return;
1310  tzsetlcl(NULL);
1311  unlock();
1312}
1313#endif
1314
1315#if defined(__ANDROID__)
1316#define _REALLY_INCLUDE_SYS__SYSTEM_PROPERTIES_H_
1317#include <sys/_system_properties.h> // For __system_property_serial.
1318#endif
1319
1320static void
1321tzset_unlocked(void)
1322{
1323#if defined(__ANDROID__)
1324  // The TZ environment variable is meant to override the system-wide setting.
1325  const char * name = getenv("TZ");
1326
1327  // If that's not set, look at the "persist.sys.timezone" system property.
1328  if (name == NULL) {
1329    static const prop_info *pi;
1330
1331    if (!pi) {
1332      pi = __system_property_find("persist.sys.timezone");
1333    }
1334    if (pi) {
1335      static char buf[PROP_VALUE_MAX];
1336      static uint32_t s = -1;
1337      static bool ok = false;
1338      uint32_t serial = __system_property_serial(pi);
1339      if (serial != s) {
1340        ok = __system_property_read(pi, 0, buf) > 0;
1341        s = serial;
1342      }
1343      if (ok) {
1344        name = buf;
1345      }
1346    }
1347  }
1348
1349  // If that's not available (because you're running AOSP on a WiFi-only
1350  // device, say), fall back to GMT.
1351  if (name == NULL) name = gmt;
1352
1353  tzsetlcl(name);
1354#else
1355  tzsetlcl(getenv("TZ"));
1356#endif
1357}
1358
1359void
1360tzset(void)
1361{
1362  if (lock() != 0)
1363    return;
1364  tzset_unlocked();
1365  unlock();
1366}
1367
1368static void
1369gmtcheck(void)
1370{
1371  static bool gmt_is_set;
1372  if (lock() != 0)
1373    return;
1374  if (! gmt_is_set) {
1375#ifdef ALL_STATE
1376    gmtptr = malloc(sizeof *gmtptr);
1377#endif
1378    if (gmtptr)
1379      gmtload(gmtptr);
1380    gmt_is_set = true;
1381  }
1382  unlock();
1383}
1384
1385#if NETBSD_INSPIRED
1386
1387timezone_t
1388tzalloc(char const *name)
1389{
1390  timezone_t sp = malloc(sizeof *sp);
1391  if (sp) {
1392    int err = zoneinit(sp, name);
1393    if (err != 0) {
1394      free(sp);
1395      errno = err;
1396      return NULL;
1397    }
1398  }
1399  return sp;
1400}
1401
1402void
1403tzfree(timezone_t sp)
1404{
1405  free(sp);
1406}
1407
1408/*
1409** NetBSD 6.1.4 has ctime_rz, but omit it because POSIX says ctime and
1410** ctime_r are obsolescent and have potential security problems that
1411** ctime_rz would share.  Callers can instead use localtime_rz + strftime.
1412**
1413** NetBSD 6.1.4 has tzgetname, but omit it because it doesn't work
1414** in zones with three or more time zone abbreviations.
1415** Callers can instead use localtime_rz + strftime.
1416*/
1417
1418#endif
1419
1420/*
1421** The easy way to behave "as if no library function calls" localtime
1422** is to not call it, so we drop its guts into "localsub", which can be
1423** freely called. (And no, the PANS doesn't require the above behavior,
1424** but it *is* desirable.)
1425**
1426** If successful and SETNAME is nonzero,
1427** set the applicable parts of tzname, timezone and altzone;
1428** however, it's OK to omit this step if the time zone is POSIX-compatible,
1429** since in that case tzset should have already done this step correctly.
1430** SETNAME's type is intfast32_t for compatibility with gmtsub,
1431** but it is actually a boolean and its value should be 0 or 1.
1432*/
1433
1434/*ARGSUSED*/
1435static struct tm *
1436localsub(struct state const *sp, time_t const *timep, int_fast32_t setname,
1437	 struct tm *const tmp)
1438{
1439	register const struct ttinfo *	ttisp;
1440	register int			i;
1441	register struct tm *		result;
1442	const time_t			t = *timep;
1443
1444	if (sp == NULL) {
1445	  /* Don't bother to set tzname etc.; tzset has already done it.  */
1446	  return gmtsub(gmtptr, timep, 0, tmp);
1447	}
1448	if ((sp->goback && t < sp->ats[0]) ||
1449		(sp->goahead && t > sp->ats[sp->timecnt - 1])) {
1450			time_t			newt = t;
1451			register time_t		seconds;
1452			register time_t		years;
1453
1454			if (t < sp->ats[0])
1455				seconds = sp->ats[0] - t;
1456			else	seconds = t - sp->ats[sp->timecnt - 1];
1457			--seconds;
1458			years = (seconds / SECSPERREPEAT + 1) * YEARSPERREPEAT;
1459			seconds = years * AVGSECSPERYEAR;
1460			if (t < sp->ats[0])
1461				newt += seconds;
1462			else	newt -= seconds;
1463			if (newt < sp->ats[0] ||
1464				newt > sp->ats[sp->timecnt - 1])
1465					return NULL;	/* "cannot happen" */
1466			result = localsub(sp, &newt, setname, tmp);
1467			if (result) {
1468				register int_fast64_t newy;
1469
1470				newy = result->tm_year;
1471				if (t < sp->ats[0])
1472					newy -= years;
1473				else	newy += years;
1474				if (! (INT_MIN <= newy && newy <= INT_MAX))
1475					return NULL;
1476				result->tm_year = newy;
1477			}
1478			return result;
1479	}
1480	if (sp->timecnt == 0 || t < sp->ats[0]) {
1481		i = sp->defaulttype;
1482	} else {
1483		register int	lo = 1;
1484		register int	hi = sp->timecnt;
1485
1486		while (lo < hi) {
1487			register int	mid = (lo + hi) >> 1;
1488
1489			if (t < sp->ats[mid])
1490				hi = mid;
1491			else	lo = mid + 1;
1492		}
1493		i = (int) sp->types[lo - 1];
1494	}
1495	ttisp = &sp->ttis[i];
1496	/*
1497	** To get (wrong) behavior that's compatible with System V Release 2.0
1498	** you'd replace the statement below with
1499	**	t += ttisp->tt_gmtoff;
1500	**	timesub(&t, 0L, sp, tmp);
1501	*/
1502	result = timesub(&t, ttisp->tt_gmtoff, sp, tmp);
1503	if (result) {
1504	  result->tm_isdst = ttisp->tt_isdst;
1505#ifdef TM_ZONE
1506	  result->TM_ZONE = (char *) &sp->chars[ttisp->tt_abbrind];
1507#endif /* defined TM_ZONE */
1508	  if (setname)
1509	    update_tzname_etc(sp, ttisp);
1510	}
1511	return result;
1512}
1513
1514#if NETBSD_INSPIRED
1515
1516struct tm *
1517localtime_rz(struct state *sp, time_t const *timep, struct tm *tmp)
1518{
1519  return localsub(sp, timep, 0, tmp);
1520}
1521
1522#endif
1523
1524static struct tm *
1525localtime_tzset(time_t const *timep, struct tm *tmp, bool setname)
1526{
1527  int err = lock();
1528  if (err) {
1529    errno = err;
1530    return NULL;
1531  }
1532  if (setname || !lcl_is_set)
1533    tzset_unlocked();
1534  tmp = localsub(lclptr, timep, setname, tmp);
1535  unlock();
1536  return tmp;
1537}
1538
1539struct tm *
1540localtime(const time_t *timep)
1541{
1542  return localtime_tzset(timep, &tm, true);
1543}
1544
1545struct tm *
1546localtime_r(const time_t *timep, struct tm *tmp)
1547{
1548  return localtime_tzset(timep, tmp, false);
1549}
1550
1551/*
1552** gmtsub is to gmtime as localsub is to localtime.
1553*/
1554
1555static struct tm *
1556gmtsub(struct state const *sp, time_t const *timep, int_fast32_t offset,
1557       struct tm *tmp)
1558{
1559	register struct tm *	result;
1560
1561	result = timesub(timep, offset, gmtptr, tmp);
1562#ifdef TM_ZONE
1563	/*
1564	** Could get fancy here and deliver something such as
1565	** "UT+xxxx" or "UT-xxxx" if offset is non-zero,
1566	** but this is no time for a treasure hunt.
1567	*/
1568	tmp->TM_ZONE = ((char *)
1569			(offset ? wildabbr : gmtptr ? gmtptr->chars : gmt));
1570#endif /* defined TM_ZONE */
1571	return result;
1572}
1573
1574/*
1575* Re-entrant version of gmtime.
1576*/
1577
1578struct tm *
1579gmtime_r(const time_t *timep, struct tm *tmp)
1580{
1581  gmtcheck();
1582  return gmtsub(gmtptr, timep, 0, tmp);
1583}
1584
1585struct tm *
1586gmtime(const time_t *timep)
1587{
1588  return gmtime_r(timep, &tm);
1589}
1590
1591#ifdef STD_INSPIRED
1592
1593struct tm *
1594offtime(const time_t *timep, long offset)
1595{
1596  gmtcheck();
1597  return gmtsub(gmtptr, timep, offset, &tm);
1598}
1599
1600#endif /* defined STD_INSPIRED */
1601
1602/*
1603** Return the number of leap years through the end of the given year
1604** where, to make the math easy, the answer for year zero is defined as zero.
1605*/
1606
1607static int ATTRIBUTE_PURE
1608leaps_thru_end_of(register const int y)
1609{
1610	return (y >= 0) ? (y / 4 - y / 100 + y / 400) :
1611		-(leaps_thru_end_of(-(y + 1)) + 1);
1612}
1613
1614static struct tm *
1615timesub(const time_t *timep, int_fast32_t offset,
1616	const struct state *sp, struct tm *tmp)
1617{
1618	register const struct lsinfo *	lp;
1619	register time_t			tdays;
1620	register int			idays;	/* unsigned would be so 2003 */
1621	register int_fast64_t		rem;
1622	int				y;
1623	register const int *		ip;
1624	register int_fast64_t		corr;
1625	register bool			hit;
1626	register int			i;
1627
1628	corr = 0;
1629	hit = false;
1630	i = (sp == NULL) ? 0 : sp->leapcnt;
1631	while (--i >= 0) {
1632		lp = &sp->lsis[i];
1633		if (*timep >= lp->ls_trans) {
1634			if (*timep == lp->ls_trans) {
1635				hit = ((i == 0 && lp->ls_corr > 0) ||
1636					lp->ls_corr > sp->lsis[i - 1].ls_corr);
1637				if (hit)
1638					while (i > 0 &&
1639						sp->lsis[i].ls_trans ==
1640						sp->lsis[i - 1].ls_trans + 1 &&
1641						sp->lsis[i].ls_corr ==
1642						sp->lsis[i - 1].ls_corr + 1) {
1643							++hit;
1644							--i;
1645					}
1646			}
1647			corr = lp->ls_corr;
1648			break;
1649		}
1650	}
1651	y = EPOCH_YEAR;
1652	tdays = *timep / SECSPERDAY;
1653	rem = *timep % SECSPERDAY;
1654	while (tdays < 0 || tdays >= year_lengths[isleap(y)]) {
1655		int		newy;
1656		register time_t	tdelta;
1657		register int	idelta;
1658		register int	leapdays;
1659
1660		tdelta = tdays / DAYSPERLYEAR;
1661		if (! ((! TYPE_SIGNED(time_t) || INT_MIN <= tdelta)
1662		       && tdelta <= INT_MAX))
1663		  goto out_of_range;
1664		idelta = tdelta;
1665		if (idelta == 0)
1666			idelta = (tdays < 0) ? -1 : 1;
1667		newy = y;
1668		if (increment_overflow(&newy, idelta))
1669		  goto out_of_range;
1670		leapdays = leaps_thru_end_of(newy - 1) -
1671			leaps_thru_end_of(y - 1);
1672		tdays -= ((time_t) newy - y) * DAYSPERNYEAR;
1673		tdays -= leapdays;
1674		y = newy;
1675	}
1676	/*
1677	** Given the range, we can now fearlessly cast...
1678	*/
1679	idays = tdays;
1680	rem += offset - corr;
1681	while (rem < 0) {
1682		rem += SECSPERDAY;
1683		--idays;
1684	}
1685	while (rem >= SECSPERDAY) {
1686		rem -= SECSPERDAY;
1687		++idays;
1688	}
1689	while (idays < 0) {
1690		if (increment_overflow(&y, -1))
1691		  goto out_of_range;
1692		idays += year_lengths[isleap(y)];
1693	}
1694	while (idays >= year_lengths[isleap(y)]) {
1695		idays -= year_lengths[isleap(y)];
1696		if (increment_overflow(&y, 1))
1697		  goto out_of_range;
1698	}
1699	tmp->tm_year = y;
1700	if (increment_overflow(&tmp->tm_year, -TM_YEAR_BASE))
1701	  goto out_of_range;
1702	tmp->tm_yday = idays;
1703	/*
1704	** The "extra" mods below avoid overflow problems.
1705	*/
1706	tmp->tm_wday = EPOCH_WDAY +
1707		((y - EPOCH_YEAR) % DAYSPERWEEK) *
1708		(DAYSPERNYEAR % DAYSPERWEEK) +
1709		leaps_thru_end_of(y - 1) -
1710		leaps_thru_end_of(EPOCH_YEAR - 1) +
1711		idays;
1712	tmp->tm_wday %= DAYSPERWEEK;
1713	if (tmp->tm_wday < 0)
1714		tmp->tm_wday += DAYSPERWEEK;
1715	tmp->tm_hour = (int) (rem / SECSPERHOUR);
1716	rem %= SECSPERHOUR;
1717	tmp->tm_min = (int) (rem / SECSPERMIN);
1718	/*
1719	** A positive leap second requires a special
1720	** representation. This uses "... ??:59:60" et seq.
1721	*/
1722	tmp->tm_sec = (int) (rem % SECSPERMIN) + hit;
1723	ip = mon_lengths[isleap(y)];
1724	for (tmp->tm_mon = 0; idays >= ip[tmp->tm_mon]; ++(tmp->tm_mon))
1725		idays -= ip[tmp->tm_mon];
1726	tmp->tm_mday = (int) (idays + 1);
1727	tmp->tm_isdst = 0;
1728#ifdef TM_GMTOFF
1729	tmp->TM_GMTOFF = offset;
1730#endif /* defined TM_GMTOFF */
1731	return tmp;
1732
1733 out_of_range:
1734	errno = EOVERFLOW;
1735	return NULL;
1736}
1737
1738char *
1739ctime(const time_t *timep)
1740{
1741/*
1742** Section 4.12.3.2 of X3.159-1989 requires that
1743**	The ctime function converts the calendar time pointed to by timer
1744**	to local time in the form of a string. It is equivalent to
1745**		asctime(localtime(timer))
1746*/
1747  struct tm *tmp = localtime(timep);
1748  return tmp ? asctime(tmp) : NULL;
1749}
1750
1751char *
1752ctime_r(const time_t *timep, char *buf)
1753{
1754  struct tm mytm;
1755  struct tm *tmp = localtime_r(timep, &mytm);
1756  return tmp ? asctime_r(tmp, buf) : NULL;
1757}
1758
1759/*
1760** Adapted from code provided by Robert Elz, who writes:
1761**	The "best" way to do mktime I think is based on an idea of Bob
1762**	Kridle's (so its said...) from a long time ago.
1763**	It does a binary search of the time_t space. Since time_t's are
1764**	just 32 bits, its a max of 32 iterations (even at 64 bits it
1765**	would still be very reasonable).
1766*/
1767
1768#ifndef WRONG
1769#define WRONG	(-1)
1770#endif /* !defined WRONG */
1771
1772/*
1773** Normalize logic courtesy Paul Eggert.
1774*/
1775
1776static bool
1777increment_overflow(int *ip, int j)
1778{
1779	register int const	i = *ip;
1780
1781	/*
1782	** If i >= 0 there can only be overflow if i + j > INT_MAX
1783	** or if j > INT_MAX - i; given i >= 0, INT_MAX - i cannot overflow.
1784	** If i < 0 there can only be overflow if i + j < INT_MIN
1785	** or if j < INT_MIN - i; given i < 0, INT_MIN - i cannot overflow.
1786	*/
1787	if ((i >= 0) ? (j > INT_MAX - i) : (j < INT_MIN - i))
1788		return true;
1789	*ip += j;
1790	return false;
1791}
1792
1793static bool
1794increment_overflow32(int_fast32_t *const lp, int const m)
1795{
1796	register int_fast32_t const	l = *lp;
1797
1798	if ((l >= 0) ? (m > INT_FAST32_MAX - l) : (m < INT_FAST32_MIN - l))
1799		return true;
1800	*lp += m;
1801	return false;
1802}
1803
1804static bool
1805increment_overflow_time(time_t *tp, int_fast32_t j)
1806{
1807	/*
1808	** This is like
1809	** 'if (! (time_t_min <= *tp + j && *tp + j <= time_t_max)) ...',
1810	** except that it does the right thing even if *tp + j would overflow.
1811	*/
1812	if (! (j < 0
1813	       ? (TYPE_SIGNED(time_t) ? time_t_min - j <= *tp : -1 - j < *tp)
1814	       : *tp <= time_t_max - j))
1815		return true;
1816	*tp += j;
1817	return false;
1818}
1819
1820static bool
1821normalize_overflow(int *const tensptr, int *const unitsptr, const int base)
1822{
1823	register int	tensdelta;
1824
1825	tensdelta = (*unitsptr >= 0) ?
1826		(*unitsptr / base) :
1827		(-1 - (-1 - *unitsptr) / base);
1828	*unitsptr -= tensdelta * base;
1829	return increment_overflow(tensptr, tensdelta);
1830}
1831
1832static bool
1833normalize_overflow32(int_fast32_t *tensptr, int *unitsptr, int base)
1834{
1835	register int	tensdelta;
1836
1837	tensdelta = (*unitsptr >= 0) ?
1838		(*unitsptr / base) :
1839		(-1 - (-1 - *unitsptr) / base);
1840	*unitsptr -= tensdelta * base;
1841	return increment_overflow32(tensptr, tensdelta);
1842}
1843
1844static int
1845tmcomp(register const struct tm *const atmp,
1846       register const struct tm *const btmp)
1847{
1848	register int	result;
1849
1850	if (atmp->tm_year != btmp->tm_year)
1851		return atmp->tm_year < btmp->tm_year ? -1 : 1;
1852	if ((result = (atmp->tm_mon - btmp->tm_mon)) == 0 &&
1853		(result = (atmp->tm_mday - btmp->tm_mday)) == 0 &&
1854		(result = (atmp->tm_hour - btmp->tm_hour)) == 0 &&
1855		(result = (atmp->tm_min - btmp->tm_min)) == 0)
1856			result = atmp->tm_sec - btmp->tm_sec;
1857	return result;
1858}
1859
1860static time_t
1861time2sub(struct tm *const tmp,
1862	 struct tm *(*funcp)(struct state const *, time_t const *,
1863			     int_fast32_t, struct tm *),
1864	 struct state const *sp,
1865	 const int_fast32_t offset,
1866	 bool *okayp,
1867	 bool do_norm_secs)
1868{
1869	register int			dir;
1870	register int			i, j;
1871	register int			saved_seconds;
1872	register int_fast32_t		li;
1873	register time_t			lo;
1874	register time_t			hi;
1875	int_fast32_t			y;
1876	time_t				newt;
1877	time_t				t;
1878	struct tm			yourtm, mytm;
1879
1880	*okayp = false;
1881	yourtm = *tmp;
1882	if (do_norm_secs) {
1883		if (normalize_overflow(&yourtm.tm_min, &yourtm.tm_sec,
1884			SECSPERMIN))
1885				return WRONG;
1886	}
1887	if (normalize_overflow(&yourtm.tm_hour, &yourtm.tm_min, MINSPERHOUR))
1888		return WRONG;
1889	if (normalize_overflow(&yourtm.tm_mday, &yourtm.tm_hour, HOURSPERDAY))
1890		return WRONG;
1891	y = yourtm.tm_year;
1892	if (normalize_overflow32(&y, &yourtm.tm_mon, MONSPERYEAR))
1893		return WRONG;
1894	/*
1895	** Turn y into an actual year number for now.
1896	** It is converted back to an offset from TM_YEAR_BASE later.
1897	*/
1898	if (increment_overflow32(&y, TM_YEAR_BASE))
1899		return WRONG;
1900	while (yourtm.tm_mday <= 0) {
1901		if (increment_overflow32(&y, -1))
1902			return WRONG;
1903		li = y + (1 < yourtm.tm_mon);
1904		yourtm.tm_mday += year_lengths[isleap(li)];
1905	}
1906	while (yourtm.tm_mday > DAYSPERLYEAR) {
1907		li = y + (1 < yourtm.tm_mon);
1908		yourtm.tm_mday -= year_lengths[isleap(li)];
1909		if (increment_overflow32(&y, 1))
1910			return WRONG;
1911	}
1912	for ( ; ; ) {
1913		i = mon_lengths[isleap(y)][yourtm.tm_mon];
1914		if (yourtm.tm_mday <= i)
1915			break;
1916		yourtm.tm_mday -= i;
1917		if (++yourtm.tm_mon >= MONSPERYEAR) {
1918			yourtm.tm_mon = 0;
1919			if (increment_overflow32(&y, 1))
1920				return WRONG;
1921		}
1922	}
1923	if (increment_overflow32(&y, -TM_YEAR_BASE))
1924		return WRONG;
1925	if (! (INT_MIN <= y && y <= INT_MAX))
1926		return WRONG;
1927	yourtm.tm_year = y;
1928	if (yourtm.tm_sec >= 0 && yourtm.tm_sec < SECSPERMIN)
1929		saved_seconds = 0;
1930	else if (y + TM_YEAR_BASE < EPOCH_YEAR) {
1931		/*
1932		** We can't set tm_sec to 0, because that might push the
1933		** time below the minimum representable time.
1934		** Set tm_sec to 59 instead.
1935		** This assumes that the minimum representable time is
1936		** not in the same minute that a leap second was deleted from,
1937		** which is a safer assumption than using 58 would be.
1938		*/
1939		if (increment_overflow(&yourtm.tm_sec, 1 - SECSPERMIN))
1940			return WRONG;
1941		saved_seconds = yourtm.tm_sec;
1942		yourtm.tm_sec = SECSPERMIN - 1;
1943	} else {
1944		saved_seconds = yourtm.tm_sec;
1945		yourtm.tm_sec = 0;
1946	}
1947	/*
1948	** Do a binary search (this works whatever time_t's type is).
1949	*/
1950	lo = time_t_min;
1951	hi = time_t_max;
1952	for ( ; ; ) {
1953		t = lo / 2 + hi / 2;
1954		if (t < lo)
1955			t = lo;
1956		else if (t > hi)
1957			t = hi;
1958		if (! funcp(sp, &t, offset, &mytm)) {
1959			/*
1960			** Assume that t is too extreme to be represented in
1961			** a struct tm; arrange things so that it is less
1962			** extreme on the next pass.
1963			*/
1964			dir = (t > 0) ? 1 : -1;
1965		} else	dir = tmcomp(&mytm, &yourtm);
1966		if (dir != 0) {
1967			if (t == lo) {
1968				if (t == time_t_max)
1969					return WRONG;
1970				++t;
1971				++lo;
1972			} else if (t == hi) {
1973				if (t == time_t_min)
1974					return WRONG;
1975				--t;
1976				--hi;
1977			}
1978			if (lo > hi)
1979				return WRONG;
1980			if (dir > 0)
1981				hi = t;
1982			else	lo = t;
1983			continue;
1984		}
1985#if defined TM_GMTOFF && ! UNINIT_TRAP
1986		if (mytm.TM_GMTOFF != yourtm.TM_GMTOFF
1987		    && (yourtm.TM_GMTOFF < 0
1988			? (-SECSPERDAY <= yourtm.TM_GMTOFF
1989			   && (mytm.TM_GMTOFF <=
1990			       (SMALLEST (INT_FAST32_MAX, LONG_MAX)
1991				+ yourtm.TM_GMTOFF)))
1992			: (yourtm.TM_GMTOFF <= SECSPERDAY
1993			   && ((BIGGEST (INT_FAST32_MIN, LONG_MIN)
1994				+ yourtm.TM_GMTOFF)
1995			       <= mytm.TM_GMTOFF)))) {
1996		  /* MYTM matches YOURTM except with the wrong UTC offset.
1997		     YOURTM.TM_GMTOFF is plausible, so try it instead.
1998		     It's OK if YOURTM.TM_GMTOFF contains uninitialized data,
1999		     since the guess gets checked.  */
2000		  time_t altt = t;
2001		  int_fast32_t diff = mytm.TM_GMTOFF - yourtm.TM_GMTOFF;
2002		  if (!increment_overflow_time(&altt, diff)) {
2003		    struct tm alttm;
2004		    if (funcp(sp, &altt, offset, &alttm)
2005			&& alttm.tm_isdst == mytm.tm_isdst
2006			&& alttm.TM_GMTOFF == yourtm.TM_GMTOFF
2007			&& tmcomp(&alttm, &yourtm) == 0) {
2008		      t = altt;
2009		      mytm = alttm;
2010		    }
2011		  }
2012		}
2013#endif
2014		if (yourtm.tm_isdst < 0 || mytm.tm_isdst == yourtm.tm_isdst)
2015			break;
2016		/*
2017		** Right time, wrong type.
2018		** Hunt for right time, right type.
2019		** It's okay to guess wrong since the guess
2020		** gets checked.
2021		*/
2022		if (sp == NULL)
2023			return WRONG;
2024		for (i = sp->typecnt - 1; i >= 0; --i) {
2025			if (sp->ttis[i].tt_isdst != yourtm.tm_isdst)
2026				continue;
2027			for (j = sp->typecnt - 1; j >= 0; --j) {
2028				if (sp->ttis[j].tt_isdst == yourtm.tm_isdst)
2029					continue;
2030				newt = t + sp->ttis[j].tt_gmtoff -
2031					sp->ttis[i].tt_gmtoff;
2032				if (! funcp(sp, &newt, offset, &mytm))
2033					continue;
2034				if (tmcomp(&mytm, &yourtm) != 0)
2035					continue;
2036				if (mytm.tm_isdst != yourtm.tm_isdst)
2037					continue;
2038				/*
2039				** We have a match.
2040				*/
2041				t = newt;
2042				goto label;
2043			}
2044		}
2045		return WRONG;
2046	}
2047label:
2048	newt = t + saved_seconds;
2049	if ((newt < t) != (saved_seconds < 0))
2050		return WRONG;
2051	t = newt;
2052	if (funcp(sp, &t, offset, tmp))
2053		*okayp = true;
2054	return t;
2055}
2056
2057static time_t
2058time2(struct tm * const	tmp,
2059      struct tm *(*funcp)(struct state const *, time_t const *,
2060			  int_fast32_t, struct tm *),
2061      struct state const *sp,
2062      const int_fast32_t offset,
2063      bool *okayp)
2064{
2065	time_t	t;
2066
2067	/*
2068	** First try without normalization of seconds
2069	** (in case tm_sec contains a value associated with a leap second).
2070	** If that fails, try with normalization of seconds.
2071	*/
2072	t = time2sub(tmp, funcp, sp, offset, okayp, false);
2073	return *okayp ? t : time2sub(tmp, funcp, sp, offset, okayp, true);
2074}
2075
2076static time_t
2077time1(struct tm *const tmp,
2078      struct tm *(*funcp) (struct state const *, time_t const *,
2079			   int_fast32_t, struct tm *),
2080      struct state const *sp,
2081      const int_fast32_t offset)
2082{
2083	register time_t			t;
2084	register int			samei, otheri;
2085	register int			sameind, otherind;
2086	register int			i;
2087	register int			nseen;
2088	char				seen[TZ_MAX_TYPES];
2089	unsigned char			types[TZ_MAX_TYPES];
2090	bool				okay;
2091
2092	if (tmp == NULL) {
2093		errno = EINVAL;
2094		return WRONG;
2095	}
2096	if (tmp->tm_isdst > 1)
2097		tmp->tm_isdst = 1;
2098	t = time2(tmp, funcp, sp, offset, &okay);
2099	if (okay)
2100		return t;
2101	if (tmp->tm_isdst < 0)
2102#ifdef PCTS
2103		/*
2104		** POSIX Conformance Test Suite code courtesy Grant Sullivan.
2105		*/
2106		tmp->tm_isdst = 0;	/* reset to std and try again */
2107#else
2108		return t;
2109#endif /* !defined PCTS */
2110	/*
2111	** We're supposed to assume that somebody took a time of one type
2112	** and did some math on it that yielded a "struct tm" that's bad.
2113	** We try to divine the type they started from and adjust to the
2114	** type they need.
2115	*/
2116	if (sp == NULL)
2117		return WRONG;
2118	for (i = 0; i < sp->typecnt; ++i)
2119		seen[i] = false;
2120	nseen = 0;
2121	for (i = sp->timecnt - 1; i >= 0; --i)
2122		if (!seen[sp->types[i]]) {
2123			seen[sp->types[i]] = true;
2124			types[nseen++] = sp->types[i];
2125		}
2126	for (sameind = 0; sameind < nseen; ++sameind) {
2127		samei = types[sameind];
2128		if (sp->ttis[samei].tt_isdst != tmp->tm_isdst)
2129			continue;
2130		for (otherind = 0; otherind < nseen; ++otherind) {
2131			otheri = types[otherind];
2132			if (sp->ttis[otheri].tt_isdst == tmp->tm_isdst)
2133				continue;
2134			tmp->tm_sec += sp->ttis[otheri].tt_gmtoff -
2135					sp->ttis[samei].tt_gmtoff;
2136			tmp->tm_isdst = !tmp->tm_isdst;
2137			t = time2(tmp, funcp, sp, offset, &okay);
2138			if (okay)
2139				return t;
2140			tmp->tm_sec -= sp->ttis[otheri].tt_gmtoff -
2141					sp->ttis[samei].tt_gmtoff;
2142			tmp->tm_isdst = !tmp->tm_isdst;
2143		}
2144	}
2145	return WRONG;
2146}
2147
2148static time_t
2149mktime_tzname(struct state *sp, struct tm *tmp, bool setname)
2150{
2151  if (sp)
2152    return time1(tmp, localsub, sp, setname);
2153  else {
2154    gmtcheck();
2155    return time1(tmp, gmtsub, gmtptr, 0);
2156  }
2157}
2158
2159#if NETBSD_INSPIRED
2160
2161time_t
2162mktime_z(struct state *sp, struct tm *tmp)
2163{
2164  return mktime_tzname(sp, tmp, false);
2165}
2166
2167#endif
2168
2169time_t
2170mktime(struct tm *tmp)
2171{
2172  time_t t;
2173  int err = lock();
2174  if (err) {
2175    errno = err;
2176    return -1;
2177  }
2178  tzset_unlocked();
2179  t = mktime_tzname(lclptr, tmp, true);
2180  unlock();
2181  return t;
2182}
2183
2184#ifdef STD_INSPIRED
2185
2186time_t
2187timelocal(struct tm *tmp)
2188{
2189	if (tmp != NULL)
2190		tmp->tm_isdst = -1;	/* in case it wasn't initialized */
2191	return mktime(tmp);
2192}
2193
2194time_t
2195timegm(struct tm *tmp)
2196{
2197  return timeoff(tmp, 0);
2198}
2199
2200time_t
2201timeoff(struct tm *tmp, long offset)
2202{
2203  if (tmp)
2204    tmp->tm_isdst = 0;
2205  gmtcheck();
2206  return time1(tmp, gmtsub, gmtptr, offset);
2207}
2208
2209#endif /* defined STD_INSPIRED */
2210
2211/*
2212** XXX--is the below the right way to conditionalize??
2213*/
2214
2215#ifdef STD_INSPIRED
2216
2217/*
2218** IEEE Std 1003.1-1988 (POSIX) legislates that 536457599
2219** shall correspond to "Wed Dec 31 23:59:59 UTC 1986", which
2220** is not the case if we are accounting for leap seconds.
2221** So, we provide the following conversion routines for use
2222** when exchanging timestamps with POSIX conforming systems.
2223*/
2224
2225static int_fast64_t
2226leapcorr(struct state const *sp, time_t t)
2227{
2228	register struct lsinfo const *	lp;
2229	register int			i;
2230
2231	i = sp->leapcnt;
2232	while (--i >= 0) {
2233		lp = &sp->lsis[i];
2234		if (t >= lp->ls_trans)
2235			return lp->ls_corr;
2236	}
2237	return 0;
2238}
2239
2240NETBSD_INSPIRED_EXTERN time_t ATTRIBUTE_PURE
2241time2posix_z(struct state *sp, time_t t)
2242{
2243  return t - leapcorr(sp, t);
2244}
2245
2246time_t
2247time2posix(time_t t)
2248{
2249  int err = lock();
2250  if (err) {
2251    errno = err;
2252    return -1;
2253  }
2254  if (!lcl_is_set)
2255    tzset_unlocked();
2256  if (lclptr)
2257    t = time2posix_z(lclptr, t);
2258  unlock();
2259  return t;
2260}
2261
2262NETBSD_INSPIRED_EXTERN time_t ATTRIBUTE_PURE
2263posix2time_z(struct state *sp, time_t t)
2264{
2265	time_t	x;
2266	time_t	y;
2267	/*
2268	** For a positive leap second hit, the result
2269	** is not unique. For a negative leap second
2270	** hit, the corresponding time doesn't exist,
2271	** so we return an adjacent second.
2272	*/
2273	x = t + leapcorr(sp, t);
2274	y = x - leapcorr(sp, x);
2275	if (y < t) {
2276		do {
2277			x++;
2278			y = x - leapcorr(sp, x);
2279		} while (y < t);
2280		x -= y != t;
2281	} else if (y > t) {
2282		do {
2283			--x;
2284			y = x - leapcorr(sp, x);
2285		} while (y > t);
2286		x += y != t;
2287	}
2288	return x;
2289}
2290
2291time_t
2292posix2time(time_t t)
2293{
2294  int err = lock();
2295  if (err) {
2296    errno = err;
2297    return -1;
2298  }
2299  if (!lcl_is_set)
2300    tzset_unlocked();
2301  if (lclptr)
2302    t = posix2time_z(lclptr, t);
2303  unlock();
2304  return t;
2305}
2306
2307#endif /* defined STD_INSPIRED */
2308
2309#ifdef time_tz
2310
2311/* Convert from the underlying system's time_t to the ersatz time_tz,
2312   which is called 'time_t' in this file.  */
2313
2314time_t
2315time(time_t *p)
2316{
2317  time_t r = sys_time(0);
2318  if (p)
2319    *p = r;
2320  return r;
2321}
2322
2323#endif
2324
2325// BEGIN android-added
2326
2327#include <assert.h>
2328#include <stdint.h>
2329#include <arpa/inet.h> // For ntohl(3).
2330
2331static int __bionic_open_tzdata_path(const char* path_prefix_variable, const char* path_suffix,
2332                                     const char* olson_id,
2333                                     int32_t* entry_length) {
2334  const char* path_prefix = getenv(path_prefix_variable);
2335  if (path_prefix == NULL) {
2336    fprintf(stderr, "%s: %s not set!\n", __FUNCTION__, path_prefix_variable);
2337    return -1;
2338  }
2339  size_t path_length = strlen(path_prefix) + 1 + strlen(path_suffix) + 1;
2340  char* path = malloc(path_length);
2341  if (path == NULL) {
2342    fprintf(stderr, "%s: couldn't allocate %zu-byte path\n", __FUNCTION__, path_length);
2343    return -1;
2344  }
2345  snprintf(path, path_length, "%s/%s", path_prefix, path_suffix);
2346  int fd = TEMP_FAILURE_RETRY(open(path, OPEN_MODE));
2347  if (fd == -1) {
2348    free(path);
2349    return -2; // Distinguish failure to find any data from failure to find a specific id.
2350  }
2351
2352  // byte[12] tzdata_version  -- "tzdata2012f\0"
2353  // int index_offset
2354  // int data_offset
2355  // int zonetab_offset
2356  struct bionic_tzdata_header {
2357    char tzdata_version[12];
2358    int32_t index_offset;
2359    int32_t data_offset;
2360    int32_t zonetab_offset;
2361  } header;
2362  memset(&header, 0, sizeof(header));
2363  ssize_t bytes_read = TEMP_FAILURE_RETRY(read(fd, &header, sizeof(header)));
2364  if (bytes_read != sizeof(header)) {
2365    fprintf(stderr, "%s: could not read header of \"%s\": %s\n",
2366            __FUNCTION__, path, (bytes_read == -1) ? strerror(errno) : "short read");
2367    free(path);
2368    close(fd);
2369    return -1;
2370  }
2371
2372  if (strncmp(header.tzdata_version, "tzdata", 6) != 0 || header.tzdata_version[11] != 0) {
2373    fprintf(stderr, "%s: bad magic in \"%s\": \"%.6s\"\n",
2374            __FUNCTION__, path, header.tzdata_version);
2375    free(path);
2376    close(fd);
2377    return -1;
2378  }
2379
2380#if 0
2381  fprintf(stderr, "version: %s\n", header.tzdata_version);
2382  fprintf(stderr, "index_offset = %d\n", ntohl(header.index_offset));
2383  fprintf(stderr, "data_offset = %d\n", ntohl(header.data_offset));
2384  fprintf(stderr, "zonetab_offset = %d\n", ntohl(header.zonetab_offset));
2385#endif
2386
2387  if (TEMP_FAILURE_RETRY(lseek(fd, ntohl(header.index_offset), SEEK_SET)) == -1) {
2388    fprintf(stderr, "%s: couldn't seek to index in \"%s\": %s\n",
2389            __FUNCTION__, path, strerror(errno));
2390    free(path);
2391    close(fd);
2392    return -1;
2393  }
2394
2395  off_t specific_zone_offset = -1;
2396  ssize_t index_size = ntohl(header.data_offset) - ntohl(header.index_offset);
2397  char* index = malloc(index_size);
2398  if (index == NULL) {
2399    fprintf(stderr, "%s: couldn't allocate %zd-byte index for \"%s\"\n",
2400            __FUNCTION__, index_size, path);
2401    free(path);
2402    close(fd);
2403    return -1;
2404  }
2405  if (TEMP_FAILURE_RETRY(read(fd, index, index_size)) != index_size) {
2406    fprintf(stderr, "%s: could not read index of \"%s\": %s\n",
2407            __FUNCTION__, path, (bytes_read == -1) ? strerror(errno) : "short read");
2408    free(path);
2409    free(index);
2410    close(fd);
2411    return -1;
2412  }
2413
2414  static const size_t NAME_LENGTH = 40;
2415  struct index_entry_t {
2416    char buf[NAME_LENGTH];
2417    int32_t start;
2418    int32_t length;
2419    int32_t unused; // Was raw GMT offset; always 0 since tzdata2014f (L).
2420  };
2421
2422  size_t id_count = (ntohl(header.data_offset) - ntohl(header.index_offset)) / sizeof(struct index_entry_t);
2423  struct index_entry_t* entry = (struct index_entry_t*) index;
2424  for (size_t i = 0; i < id_count; ++i) {
2425    char this_id[NAME_LENGTH + 1];
2426    memcpy(this_id, entry->buf, NAME_LENGTH);
2427    this_id[NAME_LENGTH] = '\0';
2428
2429    if (strcmp(this_id, olson_id) == 0) {
2430      specific_zone_offset = ntohl(entry->start) + ntohl(header.data_offset);
2431      *entry_length = ntohl(entry->length);
2432      break;
2433    }
2434
2435    ++entry;
2436  }
2437  free(index);
2438
2439  if (specific_zone_offset == -1) {
2440    free(path);
2441    close(fd);
2442    return -1;
2443  }
2444
2445  if (TEMP_FAILURE_RETRY(lseek(fd, specific_zone_offset, SEEK_SET)) == -1) {
2446    fprintf(stderr, "%s: could not seek to %ld in \"%s\": %s\n",
2447            __FUNCTION__, specific_zone_offset, path, strerror(errno));
2448    free(path);
2449    close(fd);
2450    return -1;
2451  }
2452
2453  // TODO: check that there's TZ_MAGIC at this offset, so we can fall back to the other file if not.
2454
2455  free(path);
2456  return fd;
2457}
2458
2459static int __bionic_open_tzdata(const char* olson_id, int32_t* entry_length) {
2460  int fd = __bionic_open_tzdata_path("ANDROID_DATA", "/misc/zoneinfo/current/tzdata",
2461                                     olson_id, entry_length);
2462  if (fd < 0) {
2463    fd = __bionic_open_tzdata_path("ANDROID_ROOT", "/usr/share/zoneinfo/tzdata",
2464                                   olson_id, entry_length);
2465    if (fd == -2) {
2466      // The first thing that 'recovery' does is try to format the current time. It doesn't have
2467      // any tzdata available, so we must not abort here --- doing so breaks the recovery image!
2468      fprintf(stderr, "%s: couldn't find any tzdata when looking for %s!\n", __FUNCTION__, olson_id);
2469    }
2470  }
2471  return fd;
2472}
2473
2474// END android-added
2475