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
181/*
182** Section 4.12.3 of X3.159-1989 requires that
183**  Except for the strftime function, these functions [asctime,
184**  ctime, gmtime, localtime] return values in one of two static
185**  objects: a broken-down time structure and an array of char.
186** Thanks to Paul Eggert for noting this.
187*/
188
189static struct tm	tm;
190
191#if !HAVE_POSIX_DECLS
192char *			tzname[2] = {
193	(char *) wildabbr,
194	(char *) wildabbr
195};
196#ifdef USG_COMPAT
197long			timezone;
198int			daylight;
199# endif
200#endif
201
202#ifdef ALTZONE
203long			altzone;
204#endif /* defined ALTZONE */
205
206/* Initialize *S to a value based on GMTOFF, ISDST, and ABBRIND.  */
207static void
208init_ttinfo(struct ttinfo *s, int_fast32_t gmtoff, bool isdst, int abbrind)
209{
210  s->tt_gmtoff = gmtoff;
211  s->tt_isdst = isdst;
212  s->tt_abbrind = abbrind;
213  s->tt_ttisstd = false;
214  s->tt_ttisgmt = false;
215}
216
217static int_fast32_t
218detzcode(const char *const codep)
219{
220	register int_fast32_t	result;
221	register int		i;
222	int_fast32_t one = 1;
223	int_fast32_t halfmaxval = one << (32 - 2);
224	int_fast32_t maxval = halfmaxval - 1 + halfmaxval;
225	int_fast32_t minval = -1 - maxval;
226
227	result = codep[0] & 0x7f;
228	for (i = 1; i < 4; ++i)
229		result = (result << 8) | (codep[i] & 0xff);
230
231	if (codep[0] & 0x80) {
232	  /* Do two's-complement negation even on non-two's-complement machines.
233	     If the result would be minval - 1, return minval.  */
234	  result -= !TWOS_COMPLEMENT(int_fast32_t) && result != 0;
235	  result += minval;
236	}
237	return result;
238}
239
240static int_fast64_t
241detzcode64(const char *const codep)
242{
243	register uint_fast64_t result;
244	register int	i;
245	int_fast64_t one = 1;
246	int_fast64_t halfmaxval = one << (64 - 2);
247	int_fast64_t maxval = halfmaxval - 1 + halfmaxval;
248	int_fast64_t minval = -TWOS_COMPLEMENT(int_fast64_t) - maxval;
249
250	result = codep[0] & 0x7f;
251	for (i = 1; i < 8; ++i)
252		result = (result << 8) | (codep[i] & 0xff);
253
254	if (codep[0] & 0x80) {
255	  /* Do two's-complement negation even on non-two's-complement machines.
256	     If the result would be minval - 1, return minval.  */
257	  result -= !TWOS_COMPLEMENT(int_fast64_t) && result != 0;
258	  result += minval;
259	}
260	return result;
261}
262
263static void
264update_tzname_etc(struct state const *sp, struct ttinfo const *ttisp)
265{
266  tzname[ttisp->tt_isdst] = (char *) &sp->chars[ttisp->tt_abbrind];
267#ifdef USG_COMPAT
268  if (!ttisp->tt_isdst)
269    timezone = - ttisp->tt_gmtoff;
270#endif
271#ifdef ALTZONE
272  if (ttisp->tt_isdst)
273    altzone = - ttisp->tt_gmtoff;
274#endif
275}
276
277static void
278settzname(void)
279{
280	register struct state * const	sp = lclptr;
281	register int			i;
282
283	tzname[0] = tzname[1] = (char *) wildabbr;
284#ifdef USG_COMPAT
285	daylight = 0;
286	timezone = 0;
287#endif /* defined USG_COMPAT */
288#ifdef ALTZONE
289	altzone = 0;
290#endif /* defined ALTZONE */
291	if (sp == NULL) {
292		tzname[0] = tzname[1] = (char *) gmt;
293		return;
294	}
295	/*
296	** And to get the latest zone names into tzname. . .
297	*/
298	for (i = 0; i < sp->typecnt; ++i) {
299		register const struct ttinfo * const	ttisp = &sp->ttis[i];
300		update_tzname_etc(sp, ttisp);
301	}
302	for (i = 0; i < sp->timecnt; ++i) {
303		register const struct ttinfo * const	ttisp =
304							&sp->ttis[
305								sp->types[i]];
306		update_tzname_etc(sp, ttisp);
307#ifdef USG_COMPAT
308		if (ttisp->tt_isdst)
309			daylight = 1;
310#endif /* defined USG_COMPAT */
311	}
312}
313
314static void
315scrub_abbrs(struct state *sp)
316{
317	int i;
318	/*
319	** First, replace bogus characters.
320	*/
321	for (i = 0; i < sp->charcnt; ++i)
322		if (strchr(TZ_ABBR_CHAR_SET, sp->chars[i]) == NULL)
323			sp->chars[i] = TZ_ABBR_ERR_CHAR;
324	/*
325	** Second, truncate long abbreviations.
326	*/
327	for (i = 0; i < sp->typecnt; ++i) {
328		register const struct ttinfo * const	ttisp = &sp->ttis[i];
329		register char *				cp = &sp->chars[ttisp->tt_abbrind];
330
331		if (strlen(cp) > TZ_ABBR_MAX_LEN &&
332			strcmp(cp, GRANDPARENTED) != 0)
333				*(cp + TZ_ABBR_MAX_LEN) = '\0';
334	}
335}
336
337static bool
338differ_by_repeat(const time_t t1, const time_t t0)
339{
340    if (TYPE_BIT(time_t) - TYPE_SIGNED(time_t) < SECSPERREPEAT_BITS)
341        return 0;
342#if defined(__LP64__) // 32-bit Android/glibc has a signed 32-bit time_t; 64-bit doesn't.
343    return t1 - t0 == SECSPERREPEAT;
344#endif
345}
346
347/* Input buffer for data read from a compiled tz file.  */
348union input_buffer {
349  /* The first part of the buffer, interpreted as a header.  */
350  struct tzhead tzhead;
351
352  /* The entire buffer.  */
353  char buf[2 * sizeof(struct tzhead) + 2 * sizeof (struct state)
354	   + 4 * TZ_MAX_TIMES];
355};
356
357/* Local storage needed for 'tzloadbody'.  */
358union local_storage {
359  /* The file name to be opened.  */
360  char fullname[FILENAME_MAX + 1];
361
362  /* The results of analyzing the file's contents after it is opened.  */
363  struct {
364    /* The input buffer.  */
365    union input_buffer u;
366
367    /* A temporary state used for parsing a TZ string in the file.  */
368    struct state st;
369  } u;
370};
371
372/* Load tz data from the file named NAME into *SP.  Read extended
373   format if DOEXTEND.  Use *LSP for temporary storage.  Return 0 on
374   success, an errno value on failure.  */
375static int
376tzloadbody(char const *name, struct state *sp, bool doextend,
377	   union local_storage *lsp)
378{
379	register int			i;
380	register int			fid;
381	register int			stored;
382	register ssize_t		nread;
383#if !defined(__BIONIC__)
384	register bool doaccess;
385	register char *fullname = lsp->fullname;
386#endif
387	register union input_buffer *up = &lsp->u.u;
388	register int tzheadsize = sizeof (struct tzhead);
389
390	sp->goback = sp->goahead = false;
391
392	if (! name) {
393		name = TZDEFAULT;
394		if (! name)
395		  return EINVAL;
396	}
397
398#if defined(__BIONIC__)
399	extern int __bionic_open_tzdata(const char*, int32_t*);
400	int32_t entry_length;
401	fid = __bionic_open_tzdata(name, &entry_length);
402#else
403	if (name[0] == ':')
404		++name;
405	doaccess = name[0] == '/';
406	if (!doaccess) {
407		char const *p = TZDIR;
408		if (! p)
409		  return EINVAL;
410		if (sizeof lsp->fullname - 1 <= strlen(p) + strlen(name))
411		  return ENAMETOOLONG;
412		strcpy(fullname, p);
413		strcat(fullname, "/");
414		strcat(fullname, name);
415		/* Set doaccess if '.' (as in "../") shows up in name.  */
416		if (strchr(name, '.'))
417			doaccess = true;
418		name = fullname;
419	}
420	if (doaccess && access(name, R_OK) != 0)
421	  return errno;
422	fid = open(name, OPEN_MODE);
423#endif
424	if (fid < 0)
425	  return errno;
426
427#if defined(__BIONIC__)
428	nread = TEMP_FAILURE_RETRY(read(fid, up->buf, entry_length));
429#else
430	nread = read(fid, up->buf, sizeof up->buf);
431#endif
432	if (nread < tzheadsize) {
433	  int err = nread < 0 ? errno : EINVAL;
434	  close(fid);
435	  return err;
436	}
437	if (close(fid) < 0)
438	  return errno;
439	for (stored = 4; stored <= 8; stored *= 2) {
440		int_fast32_t ttisstdcnt = detzcode(up->tzhead.tzh_ttisstdcnt);
441		int_fast32_t ttisgmtcnt = detzcode(up->tzhead.tzh_ttisgmtcnt);
442		int_fast32_t leapcnt = detzcode(up->tzhead.tzh_leapcnt);
443		int_fast32_t timecnt = detzcode(up->tzhead.tzh_timecnt);
444		int_fast32_t typecnt = detzcode(up->tzhead.tzh_typecnt);
445		int_fast32_t charcnt = detzcode(up->tzhead.tzh_charcnt);
446		char const *p = up->buf + tzheadsize;
447		if (! (0 <= leapcnt && leapcnt < TZ_MAX_LEAPS
448		       && 0 < typecnt && typecnt < TZ_MAX_TYPES
449		       && 0 <= timecnt && timecnt < TZ_MAX_TIMES
450		       && 0 <= charcnt && charcnt < TZ_MAX_CHARS
451		       && (ttisstdcnt == typecnt || ttisstdcnt == 0)
452		       && (ttisgmtcnt == typecnt || ttisgmtcnt == 0)))
453		  return EINVAL;
454		if (nread
455		    < (tzheadsize		/* struct tzhead */
456		       + timecnt * stored	/* ats */
457		       + timecnt		/* types */
458		       + typecnt * 6		/* ttinfos */
459		       + charcnt		/* chars */
460		       + leapcnt * (stored + 4)	/* lsinfos */
461		       + ttisstdcnt		/* ttisstds */
462		       + ttisgmtcnt))		/* ttisgmts */
463		  return EINVAL;
464		sp->leapcnt = leapcnt;
465		sp->timecnt = timecnt;
466		sp->typecnt = typecnt;
467		sp->charcnt = charcnt;
468
469		/* Read transitions, discarding those out of time_t range.
470		   But pretend the last transition before time_t_min
471		   occurred at time_t_min.  */
472		timecnt = 0;
473		for (i = 0; i < sp->timecnt; ++i) {
474			int_fast64_t at
475			  = stored == 4 ? detzcode(p) : detzcode64(p);
476			sp->types[i] = at <= time_t_max;
477			if (sp->types[i]) {
478			  time_t attime
479			    = ((TYPE_SIGNED(time_t) ? at < time_t_min : at < 0)
480			       ? time_t_min : at);
481			  if (timecnt && attime <= sp->ats[timecnt - 1]) {
482			    if (attime < sp->ats[timecnt - 1])
483			      return EINVAL;
484			    sp->types[i - 1] = 0;
485			    timecnt--;
486			  }
487			  sp->ats[timecnt++] = attime;
488			}
489			p += stored;
490		}
491
492		timecnt = 0;
493		for (i = 0; i < sp->timecnt; ++i) {
494			unsigned char typ = *p++;
495			if (sp->typecnt <= typ)
496			  return EINVAL;
497			if (sp->types[i])
498				sp->types[timecnt++] = typ;
499		}
500		sp->timecnt = timecnt;
501		for (i = 0; i < sp->typecnt; ++i) {
502			register struct ttinfo *	ttisp;
503			unsigned char isdst, abbrind;
504
505			ttisp = &sp->ttis[i];
506			ttisp->tt_gmtoff = detzcode(p);
507			p += 4;
508			isdst = *p++;
509			if (! (isdst < 2))
510			  return EINVAL;
511			ttisp->tt_isdst = isdst;
512			abbrind = *p++;
513			if (! (abbrind < sp->charcnt))
514			  return EINVAL;
515			ttisp->tt_abbrind = abbrind;
516		}
517		for (i = 0; i < sp->charcnt; ++i)
518			sp->chars[i] = *p++;
519		sp->chars[i] = '\0';	/* ensure '\0' at end */
520
521		/* Read leap seconds, discarding those out of time_t range.  */
522		leapcnt = 0;
523		for (i = 0; i < sp->leapcnt; ++i) {
524		  int_fast64_t tr = stored == 4 ? detzcode(p) : detzcode64(p);
525		  int_fast32_t corr = detzcode(p + stored);
526		  p += stored + 4;
527		  if (tr <= time_t_max) {
528		    time_t trans
529		      = ((TYPE_SIGNED(time_t) ? tr < time_t_min : tr < 0)
530			 ? time_t_min : tr);
531		    if (leapcnt && trans <= sp->lsis[leapcnt - 1].ls_trans) {
532		      if (trans < sp->lsis[leapcnt - 1].ls_trans)
533			return EINVAL;
534		      leapcnt--;
535		    }
536		    sp->lsis[leapcnt].ls_trans = trans;
537		    sp->lsis[leapcnt].ls_corr = corr;
538		    leapcnt++;
539		  }
540		}
541		sp->leapcnt = leapcnt;
542
543		for (i = 0; i < sp->typecnt; ++i) {
544			register struct ttinfo *	ttisp;
545
546			ttisp = &sp->ttis[i];
547			if (ttisstdcnt == 0)
548				ttisp->tt_ttisstd = false;
549			else {
550				if (*p != true && *p != false)
551				  return EINVAL;
552				ttisp->tt_ttisstd = *p++;
553			}
554		}
555		for (i = 0; i < sp->typecnt; ++i) {
556			register struct ttinfo *	ttisp;
557
558			ttisp = &sp->ttis[i];
559			if (ttisgmtcnt == 0)
560				ttisp->tt_ttisgmt = false;
561			else {
562				if (*p != true && *p != false)
563						return EINVAL;
564				ttisp->tt_ttisgmt = *p++;
565			}
566		}
567		/*
568		** If this is an old file, we're done.
569		*/
570		if (up->tzhead.tzh_version[0] == '\0')
571			break;
572		nread -= p - up->buf;
573		memmove(up->buf, p, nread);
574	}
575	if (doextend && nread > 2 &&
576		up->buf[0] == '\n' && up->buf[nread - 1] == '\n' &&
577		sp->typecnt + 2 <= TZ_MAX_TYPES) {
578			struct state	*ts = &lsp->u.st;
579
580			up->buf[nread - 1] = '\0';
581			if (tzparse(&up->buf[1], ts, false)
582			    && ts->typecnt == 2) {
583
584			  /* Attempt to reuse existing abbreviations.
585			     Without this, America/Anchorage would stop
586			     working after 2037 when TZ_MAX_CHARS is 50, as
587			     sp->charcnt equals 42 (for LMT CAT CAWT CAPT AHST
588			     AHDT YST AKDT AKST) and ts->charcnt equals 10
589			     (for AKST AKDT).  Reusing means sp->charcnt can
590			     stay 42 in this example.  */
591			  int gotabbr = 0;
592			  int charcnt = sp->charcnt;
593			  for (i = 0; i < 2; i++) {
594			    char *tsabbr = ts->chars + ts->ttis[i].tt_abbrind;
595			    int j;
596			    for (j = 0; j < charcnt; j++)
597			      if (strcmp(sp->chars + j, tsabbr) == 0) {
598				ts->ttis[i].tt_abbrind = j;
599				gotabbr++;
600				break;
601			      }
602			    if (! (j < charcnt)) {
603			      int tsabbrlen = strlen(tsabbr);
604			      if (j + tsabbrlen < TZ_MAX_CHARS) {
605				strcpy(sp->chars + j, tsabbr);
606				charcnt = j + tsabbrlen + 1;
607				ts->ttis[i].tt_abbrind = j;
608				gotabbr++;
609			      }
610			    }
611			  }
612			  if (gotabbr == 2) {
613			    sp->charcnt = charcnt;
614			    for (i = 0; i < ts->timecnt; i++)
615			      if (sp->ats[sp->timecnt - 1] < ts->ats[i])
616				break;
617			    while (i < ts->timecnt
618				   && sp->timecnt < TZ_MAX_TIMES) {
619			      sp->ats[sp->timecnt] = ts->ats[i];
620			      sp->types[sp->timecnt] = (sp->typecnt
621							+ ts->types[i]);
622			      sp->timecnt++;
623			      i++;
624			    }
625			    sp->ttis[sp->typecnt++] = ts->ttis[0];
626			    sp->ttis[sp->typecnt++] = ts->ttis[1];
627			  }
628			}
629	}
630	if (sp->timecnt > 1) {
631		for (i = 1; i < sp->timecnt; ++i)
632			if (typesequiv(sp, sp->types[i], sp->types[0]) &&
633				differ_by_repeat(sp->ats[i], sp->ats[0])) {
634					sp->goback = true;
635					break;
636				}
637		for (i = sp->timecnt - 2; i >= 0; --i)
638			if (typesequiv(sp, sp->types[sp->timecnt - 1],
639				sp->types[i]) &&
640				differ_by_repeat(sp->ats[sp->timecnt - 1],
641				sp->ats[i])) {
642					sp->goahead = true;
643					break;
644		}
645	}
646	/*
647	** If type 0 is is unused in transitions,
648	** it's the type to use for early times.
649	*/
650	for (i = 0; i < sp->timecnt; ++i)
651		if (sp->types[i] == 0)
652			break;
653	i = i < sp->timecnt ? -1 : 0;
654	/*
655	** Absent the above,
656	** if there are transition times
657	** and the first transition is to a daylight time
658	** find the standard type less than and closest to
659	** the type of the first transition.
660	*/
661	if (i < 0 && sp->timecnt > 0 && sp->ttis[sp->types[0]].tt_isdst) {
662		i = sp->types[0];
663		while (--i >= 0)
664			if (!sp->ttis[i].tt_isdst)
665				break;
666	}
667	/*
668	** If no result yet, find the first standard type.
669	** If there is none, punt to type zero.
670	*/
671	if (i < 0) {
672		i = 0;
673		while (sp->ttis[i].tt_isdst)
674			if (++i >= sp->typecnt) {
675				i = 0;
676				break;
677			}
678	}
679	sp->defaulttype = i;
680	return 0;
681}
682
683/* Load tz data from the file named NAME into *SP.  Read extended
684   format if DOEXTEND.  Return 0 on success, an errno value on failure.  */
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
1281void
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(__BIONIC__)
1316extern void tzset_unlocked(void);
1317#else
1318static void
1319tzset_unlocked(void)
1320{
1321  tzsetlcl(getenv("TZ"));
1322}
1323#endif
1324
1325void
1326tzset(void)
1327{
1328  if (lock() != 0)
1329    return;
1330  tzset_unlocked();
1331  unlock();
1332}
1333
1334static void
1335gmtcheck(void)
1336{
1337  static bool gmt_is_set;
1338  if (lock() != 0)
1339    return;
1340  if (! gmt_is_set) {
1341#ifdef ALL_STATE
1342    gmtptr = malloc(sizeof *gmtptr);
1343#endif
1344    if (gmtptr)
1345      gmtload(gmtptr);
1346    gmt_is_set = true;
1347  }
1348  unlock();
1349}
1350
1351#if NETBSD_INSPIRED
1352
1353timezone_t
1354tzalloc(char const *name)
1355{
1356  timezone_t sp = malloc(sizeof *sp);
1357  if (sp) {
1358    int err = zoneinit(sp, name);
1359    if (err != 0) {
1360      free(sp);
1361      errno = err;
1362      return NULL;
1363    }
1364  }
1365  return sp;
1366}
1367
1368void
1369tzfree(timezone_t sp)
1370{
1371  free(sp);
1372}
1373
1374/*
1375** NetBSD 6.1.4 has ctime_rz, but omit it because POSIX says ctime and
1376** ctime_r are obsolescent and have potential security problems that
1377** ctime_rz would share.  Callers can instead use localtime_rz + strftime.
1378**
1379** NetBSD 6.1.4 has tzgetname, but omit it because it doesn't work
1380** in zones with three or more time zone abbreviations.
1381** Callers can instead use localtime_rz + strftime.
1382*/
1383
1384#endif
1385
1386/*
1387** The easy way to behave "as if no library function calls" localtime
1388** is to not call it, so we drop its guts into "localsub", which can be
1389** freely called. (And no, the PANS doesn't require the above behavior,
1390** but it *is* desirable.)
1391**
1392** If successful and SETNAME is nonzero,
1393** set the applicable parts of tzname, timezone and altzone;
1394** however, it's OK to omit this step if the time zone is POSIX-compatible,
1395** since in that case tzset should have already done this step correctly.
1396** SETNAME's type is intfast32_t for compatibility with gmtsub,
1397** but it is actually a boolean and its value should be 0 or 1.
1398*/
1399
1400/*ARGSUSED*/
1401static struct tm *
1402localsub(struct state const *sp, time_t const *timep, int_fast32_t setname,
1403	 struct tm *const tmp)
1404{
1405	register const struct ttinfo *	ttisp;
1406	register int			i;
1407	register struct tm *		result;
1408	const time_t			t = *timep;
1409
1410	if (sp == NULL) {
1411	  /* Don't bother to set tzname etc.; tzset has already done it.  */
1412	  return gmtsub(gmtptr, timep, 0, tmp);
1413	}
1414	if ((sp->goback && t < sp->ats[0]) ||
1415		(sp->goahead && t > sp->ats[sp->timecnt - 1])) {
1416			time_t			newt = t;
1417			register time_t		seconds;
1418			register time_t		years;
1419
1420			if (t < sp->ats[0])
1421				seconds = sp->ats[0] - t;
1422			else	seconds = t - sp->ats[sp->timecnt - 1];
1423			--seconds;
1424			years = (seconds / SECSPERREPEAT + 1) * YEARSPERREPEAT;
1425			seconds = years * AVGSECSPERYEAR;
1426			if (t < sp->ats[0])
1427				newt += seconds;
1428			else	newt -= seconds;
1429			if (newt < sp->ats[0] ||
1430				newt > sp->ats[sp->timecnt - 1])
1431					return NULL;	/* "cannot happen" */
1432			result = localsub(sp, &newt, setname, tmp);
1433			if (result) {
1434				register int_fast64_t newy;
1435
1436				newy = result->tm_year;
1437				if (t < sp->ats[0])
1438					newy -= years;
1439				else	newy += years;
1440				if (! (INT_MIN <= newy && newy <= INT_MAX))
1441					return NULL;
1442				result->tm_year = newy;
1443			}
1444			return result;
1445	}
1446	if (sp->timecnt == 0 || t < sp->ats[0]) {
1447		i = sp->defaulttype;
1448	} else {
1449		register int	lo = 1;
1450		register int	hi = sp->timecnt;
1451
1452		while (lo < hi) {
1453			register int	mid = (lo + hi) >> 1;
1454
1455			if (t < sp->ats[mid])
1456				hi = mid;
1457			else	lo = mid + 1;
1458		}
1459		i = (int) sp->types[lo - 1];
1460	}
1461	ttisp = &sp->ttis[i];
1462	/*
1463	** To get (wrong) behavior that's compatible with System V Release 2.0
1464	** you'd replace the statement below with
1465	**	t += ttisp->tt_gmtoff;
1466	**	timesub(&t, 0L, sp, tmp);
1467	*/
1468	result = timesub(&t, ttisp->tt_gmtoff, sp, tmp);
1469	if (result) {
1470	  result->tm_isdst = ttisp->tt_isdst;
1471#ifdef TM_ZONE
1472	  result->TM_ZONE = (char *) &sp->chars[ttisp->tt_abbrind];
1473#endif /* defined TM_ZONE */
1474	  if (setname)
1475	    update_tzname_etc(sp, ttisp);
1476	}
1477	return result;
1478}
1479
1480#if NETBSD_INSPIRED
1481
1482struct tm *
1483localtime_rz(struct state *sp, time_t const *timep, struct tm *tmp)
1484{
1485  return localsub(sp, timep, 0, tmp);
1486}
1487
1488#endif
1489
1490static struct tm *
1491localtime_tzset(time_t const *timep, struct tm *tmp)
1492{
1493  int err = lock();
1494  if (err) {
1495    errno = err;
1496    return NULL;
1497  }
1498
1499  // http://b/31339449: POSIX says localtime(3) acts as if it called tzset(3), but upstream
1500  // and glibc both think it's okay for localtime_r(3) to not do so (presumably because of
1501  // the "not required to set tzname" clause). It's unclear that POSIX actually intended this,
1502  // the BSDs disagree with glibc, and it's confusing to developers to have localtime_r(3)
1503  // behave differently than other time zone-sensitive functions in <time.h>.
1504  tzset_unlocked();
1505
1506  tmp = localsub(lclptr, timep, true, tmp);
1507  unlock();
1508  return tmp;
1509}
1510
1511struct tm *
1512localtime(const time_t *timep)
1513{
1514  return localtime_tzset(timep, &tm);
1515}
1516
1517struct tm *
1518localtime_r(const time_t *timep, struct tm *tmp)
1519{
1520  return localtime_tzset(timep, tmp);
1521}
1522
1523/*
1524** gmtsub is to gmtime as localsub is to localtime.
1525*/
1526
1527static struct tm *
1528gmtsub(struct state const *sp, time_t const *timep, int_fast32_t offset,
1529       struct tm *tmp)
1530{
1531	register struct tm *	result;
1532
1533	result = timesub(timep, offset, gmtptr, tmp);
1534#ifdef TM_ZONE
1535	/*
1536	** Could get fancy here and deliver something such as
1537	** "UT+xxxx" or "UT-xxxx" if offset is non-zero,
1538	** but this is no time for a treasure hunt.
1539	*/
1540	tmp->TM_ZONE = ((char *)
1541			(offset ? wildabbr : gmtptr ? gmtptr->chars : gmt));
1542#endif /* defined TM_ZONE */
1543	return result;
1544}
1545
1546/*
1547* Re-entrant version of gmtime.
1548*/
1549
1550struct tm *
1551gmtime_r(const time_t *timep, struct tm *tmp)
1552{
1553  gmtcheck();
1554  return gmtsub(gmtptr, timep, 0, tmp);
1555}
1556
1557struct tm *
1558gmtime(const time_t *timep)
1559{
1560  return gmtime_r(timep, &tm);
1561}
1562
1563#ifdef STD_INSPIRED
1564
1565struct tm *
1566offtime(const time_t *timep, long offset)
1567{
1568  gmtcheck();
1569  return gmtsub(gmtptr, timep, offset, &tm);
1570}
1571
1572#endif /* defined STD_INSPIRED */
1573
1574/*
1575** Return the number of leap years through the end of the given year
1576** where, to make the math easy, the answer for year zero is defined as zero.
1577*/
1578
1579static int ATTRIBUTE_PURE
1580leaps_thru_end_of(register const int y)
1581{
1582	return (y >= 0) ? (y / 4 - y / 100 + y / 400) :
1583		-(leaps_thru_end_of(-(y + 1)) + 1);
1584}
1585
1586static struct tm *
1587timesub(const time_t *timep, int_fast32_t offset,
1588	const struct state *sp, struct tm *tmp)
1589{
1590	register const struct lsinfo *	lp;
1591	register time_t			tdays;
1592	register int			idays;	/* unsigned would be so 2003 */
1593	register int_fast64_t		rem;
1594	int				y;
1595	register const int *		ip;
1596	register int_fast64_t		corr;
1597	register bool			hit;
1598	register int			i;
1599
1600	corr = 0;
1601	hit = false;
1602	i = (sp == NULL) ? 0 : sp->leapcnt;
1603	while (--i >= 0) {
1604		lp = &sp->lsis[i];
1605		if (*timep >= lp->ls_trans) {
1606			if (*timep == lp->ls_trans) {
1607				hit = ((i == 0 && lp->ls_corr > 0) ||
1608					lp->ls_corr > sp->lsis[i - 1].ls_corr);
1609				if (hit)
1610					while (i > 0 &&
1611						sp->lsis[i].ls_trans ==
1612						sp->lsis[i - 1].ls_trans + 1 &&
1613						sp->lsis[i].ls_corr ==
1614						sp->lsis[i - 1].ls_corr + 1) {
1615							++hit;
1616							--i;
1617					}
1618			}
1619			corr = lp->ls_corr;
1620			break;
1621		}
1622	}
1623	y = EPOCH_YEAR;
1624	tdays = *timep / SECSPERDAY;
1625	rem = *timep % SECSPERDAY;
1626	while (tdays < 0 || tdays >= year_lengths[isleap(y)]) {
1627		int		newy;
1628		register time_t	tdelta;
1629		register int	idelta;
1630		register int	leapdays;
1631
1632		tdelta = tdays / DAYSPERLYEAR;
1633		if (! ((! TYPE_SIGNED(time_t) || INT_MIN <= tdelta)
1634		       && tdelta <= INT_MAX))
1635		  goto out_of_range;
1636		idelta = tdelta;
1637		if (idelta == 0)
1638			idelta = (tdays < 0) ? -1 : 1;
1639		newy = y;
1640		if (increment_overflow(&newy, idelta))
1641		  goto out_of_range;
1642		leapdays = leaps_thru_end_of(newy - 1) -
1643			leaps_thru_end_of(y - 1);
1644		tdays -= ((time_t) newy - y) * DAYSPERNYEAR;
1645		tdays -= leapdays;
1646		y = newy;
1647	}
1648	/*
1649	** Given the range, we can now fearlessly cast...
1650	*/
1651	idays = tdays;
1652	rem += offset - corr;
1653	while (rem < 0) {
1654		rem += SECSPERDAY;
1655		--idays;
1656	}
1657	while (rem >= SECSPERDAY) {
1658		rem -= SECSPERDAY;
1659		++idays;
1660	}
1661	while (idays < 0) {
1662		if (increment_overflow(&y, -1))
1663		  goto out_of_range;
1664		idays += year_lengths[isleap(y)];
1665	}
1666	while (idays >= year_lengths[isleap(y)]) {
1667		idays -= year_lengths[isleap(y)];
1668		if (increment_overflow(&y, 1))
1669		  goto out_of_range;
1670	}
1671	tmp->tm_year = y;
1672	if (increment_overflow(&tmp->tm_year, -TM_YEAR_BASE))
1673	  goto out_of_range;
1674	tmp->tm_yday = idays;
1675	/*
1676	** The "extra" mods below avoid overflow problems.
1677	*/
1678	tmp->tm_wday = EPOCH_WDAY +
1679		((y - EPOCH_YEAR) % DAYSPERWEEK) *
1680		(DAYSPERNYEAR % DAYSPERWEEK) +
1681		leaps_thru_end_of(y - 1) -
1682		leaps_thru_end_of(EPOCH_YEAR - 1) +
1683		idays;
1684	tmp->tm_wday %= DAYSPERWEEK;
1685	if (tmp->tm_wday < 0)
1686		tmp->tm_wday += DAYSPERWEEK;
1687	tmp->tm_hour = (int) (rem / SECSPERHOUR);
1688	rem %= SECSPERHOUR;
1689	tmp->tm_min = (int) (rem / SECSPERMIN);
1690	/*
1691	** A positive leap second requires a special
1692	** representation. This uses "... ??:59:60" et seq.
1693	*/
1694	tmp->tm_sec = (int) (rem % SECSPERMIN) + hit;
1695	ip = mon_lengths[isleap(y)];
1696	for (tmp->tm_mon = 0; idays >= ip[tmp->tm_mon]; ++(tmp->tm_mon))
1697		idays -= ip[tmp->tm_mon];
1698	tmp->tm_mday = (int) (idays + 1);
1699	tmp->tm_isdst = 0;
1700#ifdef TM_GMTOFF
1701	tmp->TM_GMTOFF = offset;
1702#endif /* defined TM_GMTOFF */
1703	return tmp;
1704
1705 out_of_range:
1706	errno = EOVERFLOW;
1707	return NULL;
1708}
1709
1710char *
1711ctime(const time_t *timep)
1712{
1713/*
1714** Section 4.12.3.2 of X3.159-1989 requires that
1715**	The ctime function converts the calendar time pointed to by timer
1716**	to local time in the form of a string. It is equivalent to
1717**		asctime(localtime(timer))
1718*/
1719  struct tm *tmp = localtime(timep);
1720  return tmp ? asctime(tmp) : NULL;
1721}
1722
1723char *
1724ctime_r(const time_t *timep, char *buf)
1725{
1726  struct tm mytm;
1727  struct tm *tmp = localtime_r(timep, &mytm);
1728  return tmp ? asctime_r(tmp, buf) : NULL;
1729}
1730
1731/*
1732** Adapted from code provided by Robert Elz, who writes:
1733**	The "best" way to do mktime I think is based on an idea of Bob
1734**	Kridle's (so its said...) from a long time ago.
1735**	It does a binary search of the time_t space. Since time_t's are
1736**	just 32 bits, its a max of 32 iterations (even at 64 bits it
1737**	would still be very reasonable).
1738*/
1739
1740#ifndef WRONG
1741#define WRONG	(-1)
1742#endif /* !defined WRONG */
1743
1744/*
1745** Normalize logic courtesy Paul Eggert.
1746*/
1747
1748static bool
1749increment_overflow(int *ip, int j)
1750{
1751	register int const	i = *ip;
1752
1753	/*
1754	** If i >= 0 there can only be overflow if i + j > INT_MAX
1755	** or if j > INT_MAX - i; given i >= 0, INT_MAX - i cannot overflow.
1756	** If i < 0 there can only be overflow if i + j < INT_MIN
1757	** or if j < INT_MIN - i; given i < 0, INT_MIN - i cannot overflow.
1758	*/
1759	if ((i >= 0) ? (j > INT_MAX - i) : (j < INT_MIN - i))
1760		return true;
1761	*ip += j;
1762	return false;
1763}
1764
1765static bool
1766increment_overflow32(int_fast32_t *const lp, int const m)
1767{
1768	register int_fast32_t const	l = *lp;
1769
1770	if ((l >= 0) ? (m > INT_FAST32_MAX - l) : (m < INT_FAST32_MIN - l))
1771		return true;
1772	*lp += m;
1773	return false;
1774}
1775
1776static bool
1777increment_overflow_time(time_t *tp, int_fast32_t j)
1778{
1779	/*
1780	** This is like
1781	** 'if (! (time_t_min <= *tp + j && *tp + j <= time_t_max)) ...',
1782	** except that it does the right thing even if *tp + j would overflow.
1783	*/
1784	if (! (j < 0
1785	       ? (TYPE_SIGNED(time_t) ? time_t_min - j <= *tp : -1 - j < *tp)
1786	       : *tp <= time_t_max - j))
1787		return true;
1788	*tp += j;
1789	return false;
1790}
1791
1792static bool
1793normalize_overflow(int *const tensptr, int *const unitsptr, const int base)
1794{
1795	register int	tensdelta;
1796
1797	tensdelta = (*unitsptr >= 0) ?
1798		(*unitsptr / base) :
1799		(-1 - (-1 - *unitsptr) / base);
1800	*unitsptr -= tensdelta * base;
1801	return increment_overflow(tensptr, tensdelta);
1802}
1803
1804static bool
1805normalize_overflow32(int_fast32_t *tensptr, int *unitsptr, int base)
1806{
1807	register int	tensdelta;
1808
1809	tensdelta = (*unitsptr >= 0) ?
1810		(*unitsptr / base) :
1811		(-1 - (-1 - *unitsptr) / base);
1812	*unitsptr -= tensdelta * base;
1813	return increment_overflow32(tensptr, tensdelta);
1814}
1815
1816static int
1817tmcomp(register const struct tm *const atmp,
1818       register const struct tm *const btmp)
1819{
1820	register int	result;
1821
1822	if (atmp->tm_year != btmp->tm_year)
1823		return atmp->tm_year < btmp->tm_year ? -1 : 1;
1824	if ((result = (atmp->tm_mon - btmp->tm_mon)) == 0 &&
1825		(result = (atmp->tm_mday - btmp->tm_mday)) == 0 &&
1826		(result = (atmp->tm_hour - btmp->tm_hour)) == 0 &&
1827		(result = (atmp->tm_min - btmp->tm_min)) == 0)
1828			result = atmp->tm_sec - btmp->tm_sec;
1829	return result;
1830}
1831
1832static time_t
1833time2sub(struct tm *const tmp,
1834	 struct tm *(*funcp)(struct state const *, time_t const *,
1835			     int_fast32_t, struct tm *),
1836	 struct state const *sp,
1837	 const int_fast32_t offset,
1838	 bool *okayp,
1839	 bool do_norm_secs)
1840{
1841	register int			dir;
1842	register int			i, j;
1843	register int			saved_seconds;
1844	register int_fast32_t		li;
1845	register time_t			lo;
1846	register time_t			hi;
1847	int_fast32_t			y;
1848	time_t				newt;
1849	time_t				t;
1850	struct tm			yourtm, mytm;
1851
1852	*okayp = false;
1853	yourtm = *tmp;
1854	if (do_norm_secs) {
1855		if (normalize_overflow(&yourtm.tm_min, &yourtm.tm_sec,
1856			SECSPERMIN))
1857				return WRONG;
1858	}
1859	if (normalize_overflow(&yourtm.tm_hour, &yourtm.tm_min, MINSPERHOUR))
1860		return WRONG;
1861	if (normalize_overflow(&yourtm.tm_mday, &yourtm.tm_hour, HOURSPERDAY))
1862		return WRONG;
1863	y = yourtm.tm_year;
1864	if (normalize_overflow32(&y, &yourtm.tm_mon, MONSPERYEAR))
1865		return WRONG;
1866	/*
1867	** Turn y into an actual year number for now.
1868	** It is converted back to an offset from TM_YEAR_BASE later.
1869	*/
1870	if (increment_overflow32(&y, TM_YEAR_BASE))
1871		return WRONG;
1872	while (yourtm.tm_mday <= 0) {
1873		if (increment_overflow32(&y, -1))
1874			return WRONG;
1875		li = y + (1 < yourtm.tm_mon);
1876		yourtm.tm_mday += year_lengths[isleap(li)];
1877	}
1878	while (yourtm.tm_mday > DAYSPERLYEAR) {
1879		li = y + (1 < yourtm.tm_mon);
1880		yourtm.tm_mday -= year_lengths[isleap(li)];
1881		if (increment_overflow32(&y, 1))
1882			return WRONG;
1883	}
1884	for ( ; ; ) {
1885		i = mon_lengths[isleap(y)][yourtm.tm_mon];
1886		if (yourtm.tm_mday <= i)
1887			break;
1888		yourtm.tm_mday -= i;
1889		if (++yourtm.tm_mon >= MONSPERYEAR) {
1890			yourtm.tm_mon = 0;
1891			if (increment_overflow32(&y, 1))
1892				return WRONG;
1893		}
1894	}
1895	if (increment_overflow32(&y, -TM_YEAR_BASE))
1896		return WRONG;
1897	if (! (INT_MIN <= y && y <= INT_MAX))
1898		return WRONG;
1899	yourtm.tm_year = y;
1900	if (yourtm.tm_sec >= 0 && yourtm.tm_sec < SECSPERMIN)
1901		saved_seconds = 0;
1902	else if (y + TM_YEAR_BASE < EPOCH_YEAR) {
1903		/*
1904		** We can't set tm_sec to 0, because that might push the
1905		** time below the minimum representable time.
1906		** Set tm_sec to 59 instead.
1907		** This assumes that the minimum representable time is
1908		** not in the same minute that a leap second was deleted from,
1909		** which is a safer assumption than using 58 would be.
1910		*/
1911		if (increment_overflow(&yourtm.tm_sec, 1 - SECSPERMIN))
1912			return WRONG;
1913		saved_seconds = yourtm.tm_sec;
1914		yourtm.tm_sec = SECSPERMIN - 1;
1915	} else {
1916		saved_seconds = yourtm.tm_sec;
1917		yourtm.tm_sec = 0;
1918	}
1919	/*
1920	** Do a binary search (this works whatever time_t's type is).
1921	*/
1922	lo = time_t_min;
1923	hi = time_t_max;
1924	for ( ; ; ) {
1925		t = lo / 2 + hi / 2;
1926		if (t < lo)
1927			t = lo;
1928		else if (t > hi)
1929			t = hi;
1930		if (! funcp(sp, &t, offset, &mytm)) {
1931			/*
1932			** Assume that t is too extreme to be represented in
1933			** a struct tm; arrange things so that it is less
1934			** extreme on the next pass.
1935			*/
1936			dir = (t > 0) ? 1 : -1;
1937		} else	dir = tmcomp(&mytm, &yourtm);
1938		if (dir != 0) {
1939			if (t == lo) {
1940				if (t == time_t_max)
1941					return WRONG;
1942				++t;
1943				++lo;
1944			} else if (t == hi) {
1945				if (t == time_t_min)
1946					return WRONG;
1947				--t;
1948				--hi;
1949			}
1950			if (lo > hi)
1951				return WRONG;
1952			if (dir > 0)
1953				hi = t;
1954			else	lo = t;
1955			continue;
1956		}
1957#if defined TM_GMTOFF && ! UNINIT_TRAP
1958		if (mytm.TM_GMTOFF != yourtm.TM_GMTOFF
1959		    && (yourtm.TM_GMTOFF < 0
1960			? (-SECSPERDAY <= yourtm.TM_GMTOFF
1961			   && (mytm.TM_GMTOFF <=
1962			       (SMALLEST (INT_FAST32_MAX, LONG_MAX)
1963				+ yourtm.TM_GMTOFF)))
1964			: (yourtm.TM_GMTOFF <= SECSPERDAY
1965			   && ((BIGGEST (INT_FAST32_MIN, LONG_MIN)
1966				+ yourtm.TM_GMTOFF)
1967			       <= mytm.TM_GMTOFF)))) {
1968		  /* MYTM matches YOURTM except with the wrong UTC offset.
1969		     YOURTM.TM_GMTOFF is plausible, so try it instead.
1970		     It's OK if YOURTM.TM_GMTOFF contains uninitialized data,
1971		     since the guess gets checked.  */
1972		  time_t altt = t;
1973		  int_fast32_t diff = mytm.TM_GMTOFF - yourtm.TM_GMTOFF;
1974		  if (!increment_overflow_time(&altt, diff)) {
1975		    struct tm alttm;
1976		    if (funcp(sp, &altt, offset, &alttm)
1977			&& alttm.tm_isdst == mytm.tm_isdst
1978			&& alttm.TM_GMTOFF == yourtm.TM_GMTOFF
1979			&& tmcomp(&alttm, &yourtm) == 0) {
1980		      t = altt;
1981		      mytm = alttm;
1982		    }
1983		  }
1984		}
1985#endif
1986		if (yourtm.tm_isdst < 0 || mytm.tm_isdst == yourtm.tm_isdst)
1987			break;
1988		/*
1989		** Right time, wrong type.
1990		** Hunt for right time, right type.
1991		** It's okay to guess wrong since the guess
1992		** gets checked.
1993		*/
1994		if (sp == NULL)
1995			return WRONG;
1996		for (i = sp->typecnt - 1; i >= 0; --i) {
1997			if (sp->ttis[i].tt_isdst != yourtm.tm_isdst)
1998				continue;
1999			for (j = sp->typecnt - 1; j >= 0; --j) {
2000				if (sp->ttis[j].tt_isdst == yourtm.tm_isdst)
2001					continue;
2002				newt = t + sp->ttis[j].tt_gmtoff -
2003					sp->ttis[i].tt_gmtoff;
2004				if (! funcp(sp, &newt, offset, &mytm))
2005					continue;
2006				if (tmcomp(&mytm, &yourtm) != 0)
2007					continue;
2008				if (mytm.tm_isdst != yourtm.tm_isdst)
2009					continue;
2010				/*
2011				** We have a match.
2012				*/
2013				t = newt;
2014				goto label;
2015			}
2016		}
2017		return WRONG;
2018	}
2019label:
2020	newt = t + saved_seconds;
2021	if ((newt < t) != (saved_seconds < 0))
2022		return WRONG;
2023	t = newt;
2024	if (funcp(sp, &t, offset, tmp))
2025		*okayp = true;
2026	return t;
2027}
2028
2029static time_t
2030time2(struct tm * const	tmp,
2031      struct tm *(*funcp)(struct state const *, time_t const *,
2032			  int_fast32_t, struct tm *),
2033      struct state const *sp,
2034      const int_fast32_t offset,
2035      bool *okayp)
2036{
2037	time_t	t;
2038
2039	/*
2040	** First try without normalization of seconds
2041	** (in case tm_sec contains a value associated with a leap second).
2042	** If that fails, try with normalization of seconds.
2043	*/
2044	t = time2sub(tmp, funcp, sp, offset, okayp, false);
2045	return *okayp ? t : time2sub(tmp, funcp, sp, offset, okayp, true);
2046}
2047
2048static time_t
2049time1(struct tm *const tmp,
2050      struct tm *(*funcp) (struct state const *, time_t const *,
2051			   int_fast32_t, struct tm *),
2052      struct state const *sp,
2053      const int_fast32_t offset)
2054{
2055	register time_t			t;
2056	register int			samei, otheri;
2057	register int			sameind, otherind;
2058	register int			i;
2059	register int			nseen;
2060	char				seen[TZ_MAX_TYPES];
2061	unsigned char			types[TZ_MAX_TYPES];
2062	bool				okay;
2063
2064	if (tmp == NULL) {
2065		errno = EINVAL;
2066		return WRONG;
2067	}
2068	if (tmp->tm_isdst > 1)
2069		tmp->tm_isdst = 1;
2070	t = time2(tmp, funcp, sp, offset, &okay);
2071	if (okay)
2072		return t;
2073	if (tmp->tm_isdst < 0)
2074#ifdef PCTS
2075		/*
2076		** POSIX Conformance Test Suite code courtesy Grant Sullivan.
2077		*/
2078		tmp->tm_isdst = 0;	/* reset to std and try again */
2079#else
2080		return t;
2081#endif /* !defined PCTS */
2082	/*
2083	** We're supposed to assume that somebody took a time of one type
2084	** and did some math on it that yielded a "struct tm" that's bad.
2085	** We try to divine the type they started from and adjust to the
2086	** type they need.
2087	*/
2088	if (sp == NULL)
2089		return WRONG;
2090	for (i = 0; i < sp->typecnt; ++i)
2091		seen[i] = false;
2092	nseen = 0;
2093	for (i = sp->timecnt - 1; i >= 0; --i)
2094		if (!seen[sp->types[i]]) {
2095			seen[sp->types[i]] = true;
2096			types[nseen++] = sp->types[i];
2097		}
2098	for (sameind = 0; sameind < nseen; ++sameind) {
2099		samei = types[sameind];
2100		if (sp->ttis[samei].tt_isdst != tmp->tm_isdst)
2101			continue;
2102		for (otherind = 0; otherind < nseen; ++otherind) {
2103			otheri = types[otherind];
2104			if (sp->ttis[otheri].tt_isdst == tmp->tm_isdst)
2105				continue;
2106			tmp->tm_sec += sp->ttis[otheri].tt_gmtoff -
2107					sp->ttis[samei].tt_gmtoff;
2108			tmp->tm_isdst = !tmp->tm_isdst;
2109			t = time2(tmp, funcp, sp, offset, &okay);
2110			if (okay)
2111				return t;
2112			tmp->tm_sec -= sp->ttis[otheri].tt_gmtoff -
2113					sp->ttis[samei].tt_gmtoff;
2114			tmp->tm_isdst = !tmp->tm_isdst;
2115		}
2116	}
2117	return WRONG;
2118}
2119
2120static time_t
2121mktime_tzname(struct state *sp, struct tm *tmp, bool setname)
2122{
2123  if (sp)
2124    return time1(tmp, localsub, sp, setname);
2125  else {
2126    gmtcheck();
2127    return time1(tmp, gmtsub, gmtptr, 0);
2128  }
2129}
2130
2131#if NETBSD_INSPIRED
2132
2133time_t
2134mktime_z(struct state *sp, struct tm *tmp)
2135{
2136  return mktime_tzname(sp, tmp, false);
2137}
2138
2139#endif
2140
2141time_t
2142mktime(struct tm *tmp)
2143{
2144#if defined(__BIONIC__)
2145  int saved_errno = errno;
2146#endif
2147
2148  time_t t;
2149  int err = lock();
2150  if (err) {
2151    errno = err;
2152    return -1;
2153  }
2154  tzset_unlocked();
2155  t = mktime_tzname(lclptr, tmp, true);
2156  unlock();
2157
2158#if defined(__BIONIC__)
2159  errno = (t == -1) ? EOVERFLOW : saved_errno;
2160#endif
2161  return t;
2162}
2163
2164#ifdef STD_INSPIRED
2165
2166time_t
2167timelocal(struct tm *tmp)
2168{
2169	if (tmp != NULL)
2170		tmp->tm_isdst = -1;	/* in case it wasn't initialized */
2171	return mktime(tmp);
2172}
2173
2174time_t
2175timegm(struct tm *tmp)
2176{
2177  return timeoff(tmp, 0);
2178}
2179
2180time_t
2181timeoff(struct tm *tmp, long offset)
2182{
2183  if (tmp)
2184    tmp->tm_isdst = 0;
2185  gmtcheck();
2186  return time1(tmp, gmtsub, gmtptr, offset);
2187}
2188
2189#endif /* defined STD_INSPIRED */
2190
2191/*
2192** XXX--is the below the right way to conditionalize??
2193*/
2194
2195#ifdef STD_INSPIRED
2196
2197/*
2198** IEEE Std 1003.1-1988 (POSIX) legislates that 536457599
2199** shall correspond to "Wed Dec 31 23:59:59 UTC 1986", which
2200** is not the case if we are accounting for leap seconds.
2201** So, we provide the following conversion routines for use
2202** when exchanging timestamps with POSIX conforming systems.
2203*/
2204
2205static int_fast64_t
2206leapcorr(struct state const *sp, time_t t)
2207{
2208	register struct lsinfo const *	lp;
2209	register int			i;
2210
2211	i = sp->leapcnt;
2212	while (--i >= 0) {
2213		lp = &sp->lsis[i];
2214		if (t >= lp->ls_trans)
2215			return lp->ls_corr;
2216	}
2217	return 0;
2218}
2219
2220NETBSD_INSPIRED_EXTERN time_t ATTRIBUTE_PURE
2221time2posix_z(struct state *sp, time_t t)
2222{
2223  return t - leapcorr(sp, t);
2224}
2225
2226time_t
2227time2posix(time_t t)
2228{
2229  int err = lock();
2230  if (err) {
2231    errno = err;
2232    return -1;
2233  }
2234  if (!lcl_is_set)
2235    tzset_unlocked();
2236  if (lclptr)
2237    t = time2posix_z(lclptr, t);
2238  unlock();
2239  return t;
2240}
2241
2242NETBSD_INSPIRED_EXTERN time_t ATTRIBUTE_PURE
2243posix2time_z(struct state *sp, time_t t)
2244{
2245	time_t	x;
2246	time_t	y;
2247	/*
2248	** For a positive leap second hit, the result
2249	** is not unique. For a negative leap second
2250	** hit, the corresponding time doesn't exist,
2251	** so we return an adjacent second.
2252	*/
2253	x = t + leapcorr(sp, t);
2254	y = x - leapcorr(sp, x);
2255	if (y < t) {
2256		do {
2257			x++;
2258			y = x - leapcorr(sp, x);
2259		} while (y < t);
2260		x -= y != t;
2261	} else if (y > t) {
2262		do {
2263			--x;
2264			y = x - leapcorr(sp, x);
2265		} while (y > t);
2266		x += y != t;
2267	}
2268	return x;
2269}
2270
2271time_t
2272posix2time(time_t t)
2273{
2274  int err = lock();
2275  if (err) {
2276    errno = err;
2277    return -1;
2278  }
2279  if (!lcl_is_set)
2280    tzset_unlocked();
2281  if (lclptr)
2282    t = posix2time_z(lclptr, t);
2283  unlock();
2284  return t;
2285}
2286
2287#endif /* defined STD_INSPIRED */
2288
2289#ifdef time_tz
2290
2291/* Convert from the underlying system's time_t to the ersatz time_tz,
2292   which is called 'time_t' in this file.  */
2293
2294time_t
2295time(time_t *p)
2296{
2297  time_t r = sys_time(0);
2298  if (p)
2299    *p = r;
2300  return r;
2301}
2302
2303#endif
2304