tztime.c revision dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0
1dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project/*
2dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project** This file is in the public domain, so clarified as of
3dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project** 1996-06-05 by Arthur David Olson.
4dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project*/
5dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
6dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <stdio.h>
7dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
8dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#ifndef lint
9dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#ifndef NOID
10dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic char	elsieid[] = "@(#)localtime.c	8.3";
11dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#endif /* !defined NOID */
12dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#endif /* !defined lint */
13dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
14dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project/*
15dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project** Leap second handling from Bradley White.
16dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project** POSIX-style TZ environment variable handling from Guy Harris.
17dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project*/
18dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
19dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project/*LINTLIBRARY*/
20dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
21dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include "private.h"
22dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include "tzfile.h"
23dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include "fcntl.h"
24dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include "float.h"	/* for FLT_MAX and DBL_MAX */
25dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
26dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#ifndef TZ_ABBR_MAX_LEN
27dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#define TZ_ABBR_MAX_LEN	16
28dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#endif /* !defined TZ_ABBR_MAX_LEN */
29dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
30dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#ifndef TZ_ABBR_CHAR_SET
31dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#define TZ_ABBR_CHAR_SET \
32dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789 :+-._"
33dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#endif /* !defined TZ_ABBR_CHAR_SET */
34dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
35dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#ifndef TZ_ABBR_ERR_CHAR
36dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#define TZ_ABBR_ERR_CHAR	'_'
37dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#endif /* !defined TZ_ABBR_ERR_CHAR */
38dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
39dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#define INDEXFILE "/system/usr/share/zoneinfo/zoneinfo.idx"
40dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#define DATAFILE "/system/usr/share/zoneinfo/zoneinfo.dat"
41dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#define NAMELEN 40
42dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#define INTLEN 4
43dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#define READLEN (NAMELEN + 3 * INTLEN)
44dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
45dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project/*
46dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project** SunOS 4.1.1 headers lack O_BINARY.
47dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project*/
48dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
49dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#ifdef O_BINARY
50dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#define OPEN_MODE	(O_RDONLY | O_BINARY)
51dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#endif /* defined O_BINARY */
52dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#ifndef O_BINARY
53dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#define OPEN_MODE	O_RDONLY
54dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#endif /* !defined O_BINARY */
55dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
56dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#ifndef WILDABBR
57dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project/*
58dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project** Someone might make incorrect use of a time zone abbreviation:
59dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project**	1.	They might reference tzname[0] before calling tzset (explicitly
60dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project**		or implicitly).
61dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project**	2.	They might reference tzname[1] before calling tzset (explicitly
62dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project**		or implicitly).
63dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project**	3.	They might reference tzname[1] after setting to a time zone
64dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project**		in which Daylight Saving Time is never observed.
65dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project**	4.	They might reference tzname[0] after setting to a time zone
66dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project**		in which Standard Time is never observed.
67dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project**	5.	They might reference tm.TM_ZONE after calling offtime.
68dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project** What's best to do in the above cases is open to debate;
69dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project** for now, we just set things up so that in any of the five cases
70dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project** WILDABBR is used. Another possibility: initialize tzname[0] to the
71dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project** string "tzname[0] used before set", and similarly for the other cases.
72dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project** And another: initialize tzname[0] to "ERA", with an explanation in the
73dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project** manual page of what this "time zone abbreviation" means (doing this so
74dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project** that tzname[0] has the "normal" length of three characters).
75dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project*/
76dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#define WILDABBR	"   "
77dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#endif /* !defined WILDABBR */
78dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
79dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic char		wildabbr[] = WILDABBR;
80dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
81dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic const char	gmt[] = "GMT";
82dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
83dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project/*
84dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project** The DST rules to use if TZ has no rules and we can't load TZDEFRULES.
85dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project** We default to US rules as of 1999-08-17.
86dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project** POSIX 1003.1 section 8.1.1 says that the default DST rules are
87dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project** implementation dependent; for historical reasons, US rules are a
88dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project** common default.
89dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project*/
90dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#ifndef TZDEFRULESTRING
91dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#define TZDEFRULESTRING ",M4.1.0,M10.5.0"
92dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#endif /* !defined TZDEFDST */
93dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
94dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstruct ttinfo {				/* time type information */
95dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	long		tt_gmtoff;	/* UTC offset in seconds */
96dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	int		tt_isdst;	/* used to set tm_isdst */
97dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	int		tt_abbrind;	/* abbreviation list index */
98dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	int		tt_ttisstd;	/* TRUE if transition is std time */
99dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	int		tt_ttisgmt;	/* TRUE if transition is UTC */
100dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project};
101dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
102dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstruct lsinfo {				/* leap second information */
103dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	time_t		ls_trans;	/* transition time */
104dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	long		ls_corr;	/* correction to apply */
105dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project};
106dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
107dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#define BIGGEST(a, b)	(((a) > (b)) ? (a) : (b))
108dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
109dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#ifdef TZNAME_MAX
110dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#define MY_TZNAME_MAX	TZNAME_MAX
111dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#endif /* defined TZNAME_MAX */
112dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#ifndef TZNAME_MAX
113dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#define MY_TZNAME_MAX	255
114dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#endif /* !defined TZNAME_MAX */
115dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
116dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstruct state {
117dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	int		leapcnt;
118dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	int		timecnt;
119dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	int		typecnt;
120dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	int		charcnt;
121dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	int		goback;
122dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	int		goahead;
123dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	time_t		ats[TZ_MAX_TIMES];
124dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	unsigned char	types[TZ_MAX_TIMES];
125dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	struct ttinfo	ttis[TZ_MAX_TYPES];
126dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	char		chars[BIGGEST(BIGGEST(TZ_MAX_CHARS + 1, sizeof gmt),
127dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project				(2 * (MY_TZNAME_MAX + 1)))];
128dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	struct lsinfo	lsis[TZ_MAX_LEAPS];
129dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project};
130dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
131dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstruct rule {
132dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	int		r_type;		/* type of rule--see below */
133dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	int		r_day;		/* day number of rule */
134dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	int		r_week;		/* week number of rule */
135dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	int		r_mon;		/* month number of rule */
136dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	long		r_time;		/* transition time of rule */
137dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project};
138dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
139dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#define JULIAN_DAY		0	/* Jn - Julian day */
140dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#define DAY_OF_YEAR		1	/* n - day of year */
141dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#define MONTH_NTH_DAY_OF_WEEK	2	/* Mm.n.d - month, week, day of week */
142dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
143dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project/*
144dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project** Prototypes for static functions.
145dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project*/
146dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
147dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic long		detzcode P((const char * codep));
148dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic time_t		detzcode64 P((const char * codep));
149dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic int		differ_by_repeat P((time_t t1, time_t t0));
150dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic const char *	getzname P((const char * strp));
151dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic const char *	getqzname P((const char * strp, const int delim));
152dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic const char *	getnum P((const char * strp, int * nump, int min,
153dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project				int max));
154dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic const char *	getsecs P((const char * strp, long * secsp));
155dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic const char *	getoffset P((const char * strp, long * offsetp));
156dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic const char *	getrule P((const char * strp, struct rule * rulep));
157dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic void		gmtload P((struct state * sp));
158dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic struct tm *	gmtsub P((const time_t * timep, long offset,
159dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project				struct tm * tmp));
160dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic struct tm *	localsub P((const time_t * timep, long offset,
161dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project				struct tm * tmp, struct state *sp));
162dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic int		increment_overflow P((int * number, int delta));
163dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic int		leaps_thru_end_of P((int y));
164dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic int		long_increment_overflow P((long * number, int delta));
165dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic int		long_normalize_overflow P((long * tensptr,
166dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project				int * unitsptr, int base));
167dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic int		normalize_overflow P((int * tensptr, int * unitsptr,
168dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project				int base));
169dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic void		settzname P((void));
170dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic time_t		time1 P((struct tm * tmp,
171dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project				struct tm * (*funcp) P((const time_t *,
172dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project				long, struct tm *, const struct state* sp)),
173dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project				long offset, const struct state *	sp));
174dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic time_t		time2 P((struct tm *tmp,
175dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project				struct tm * (*funcp) P((const time_t *,
176dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project				long, struct tm*, const struct state* sp)),
177dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project				long offset, int * okayp, const struct state *	sp));
178dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic time_t		time2sub P((struct tm *tmp,
179dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project				struct tm * (*funcp) P((const time_t*, long, struct tm*,const struct state *sp)),
180dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project				long offset, int * okayp, int do_norm_secs,
181dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                const struct state *sp));
182dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic struct tm *	timesub P((const time_t * timep, long offset,
183dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project				const struct state * sp, struct tm * tmp));
184dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic int		tmcomp P((const struct tm * atmp,
185dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project				const struct tm * btmp));
186dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic time_t		transtime P((time_t janfirst, int year,
187dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project				const struct rule * rulep, long offset));
188dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic int		tzload P((const char * name, struct state * sp,
189dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project				int doextend));
190dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic int		tzload_uncached P((const char * name, struct state * sp,
191dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project				int doextend));
192dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic int		tzparse P((const char * name, struct state * sp,
193dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project				int lastditch));
194dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
195dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#ifdef ALL_STATE
196dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic struct state *	gmtptr;
197dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#endif /* defined ALL_STATE */
198dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
199dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#ifndef ALL_STATE
200dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic struct state	gmtmem;
201dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#define gmtptr		(&gmtmem)
202dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#endif /* State Farm */
203dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
204dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#define CACHE_COUNT 4
205dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic char * g_cacheNames[CACHE_COUNT] = {0,0};
206dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic struct state	g_cacheStates[CACHE_COUNT];
207dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic int g_lastCache = 0;
208dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic struct state g_utc;
209dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectunsigned char g_utcSet = 0;
210dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
211dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
212dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#ifndef TZ_STRLEN_MAX
213dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#define TZ_STRLEN_MAX 255
214dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#endif /* !defined TZ_STRLEN_MAX */
215dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
216dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic char		lcl_TZname[TZ_STRLEN_MAX + 1];
217dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic int		lcl_is_set;
218dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic int		gmt_is_set;
219dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
220dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectchar *			tzname[2] = {
221dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	wildabbr,
222dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	wildabbr
223dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project};
224dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
225dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project/*
226dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project** Section 4.12.3 of X3.159-1989 requires that
227dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project**	Except for the strftime function, these functions [asctime,
228dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project**	ctime, gmtime, localtime] return values in one of two static
229dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project**	objects: a broken-down time structure and an array of char.
230dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project** Thanks to Paul Eggert for noting this.
231dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project*/
232dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
233dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic struct tm	tm;
234dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
235dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#ifdef USG_COMPAT
236dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projecttime_t			timezone = 0;
237dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectint			daylight = 0;
238dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#endif /* defined USG_COMPAT */
239dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
240dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#ifdef ALTZONE
241dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projecttime_t			altzone = 0;
242dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#endif /* defined ALTZONE */
243dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
244dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic long
245dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectdetzcode(codep)
246dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectconst char * const	codep;
247dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
248dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	register long	result;
249dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	register int	i;
250dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
251dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	result = (codep[0] & 0x80) ? ~0L : 0;
252dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	for (i = 0; i < 4; ++i)
253dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		result = (result << 8) | (codep[i] & 0xff);
254dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	return result;
255dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
256dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
257dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic time_t
258dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectdetzcode64(codep)
259dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectconst char * const	codep;
260dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
261dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	register time_t	result;
262dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	register int	i;
263dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
264dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	result = (codep[0] & 0x80) ?  (~(int_fast64_t) 0) : 0;
265dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	for (i = 0; i < 8; ++i)
266dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		result = result * 256 + (codep[i] & 0xff);
267dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	return result;
268dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
269dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
270dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic int
271dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectdiffer_by_repeat(t1, t0)
272dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectconst time_t	t1;
273dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectconst time_t	t0;
274dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
275dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	if (TYPE_INTEGRAL(time_t) &&
276dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		TYPE_BIT(time_t) - TYPE_SIGNED(time_t) < SECSPERREPEAT_BITS)
277dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			return 0;
278dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	return t1 - t0 == SECSPERREPEAT;
279dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
280dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
281dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic int toint(unsigned char *s) {
282dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    return (s[0] << 24) | (s[1] << 16) | (s[2] << 8) | s[3];
283dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
284dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
285dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic int
286dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projecttzload(const char *name, struct state * const sp, const int doextend)
287dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
288dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if (name) {
289dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        int i, err;
290dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        if (0 == strcmp(name, "UTC")) {
291dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            if (!g_utcSet) {
292dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                tzload_uncached(name, &g_utc, 1);
293dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                g_utcSet = 1;
294dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            }
295dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            //printf("tzload: utc\n");
296dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            *sp = g_utc;
297dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            return 0;
298dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        }
299dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        for (i=0; i<CACHE_COUNT; i++) {
300dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            if (g_cacheNames[i] && 0 == strcmp(name, g_cacheNames[i])) {
301dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                *sp = g_cacheStates[i];
302dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                //printf("tzload: hit: %s\n", name);
303dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                return 0;
304dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            }
305dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        }
306dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        //printf("tzload: miss: %s\n", name);
307dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        g_lastCache++;
308dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        if (g_lastCache >= CACHE_COUNT) {
309dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            g_lastCache = 0;
310dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        }
311dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        i = g_lastCache;
312dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        if (g_cacheNames[i]) {
313dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            free(g_cacheNames[i]);
314dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        }
315dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        err = tzload_uncached(name, &(g_cacheStates[i]), 1);
316dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        if (err == 0) {
317dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            g_cacheNames[i] = strdup(name);
318dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            *sp = g_cacheStates[i];
319dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            return 0;
320dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        } else {
321dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            g_cacheNames[i] = NULL;
322dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            return err;
323dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        }
324dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
325dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    return tzload_uncached(name, sp, doextend);
326dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
327dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
328dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic int
329dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projecttzload_uncached(name, sp, doextend)
330dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectregister const char *		name;
331dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectregister struct state * const	sp;
332dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectregister const int		doextend;
333dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
334dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	register const char *		p;
335dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	register int			i;
336dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	register int			fid;
337dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	register int			stored;
338dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	register int			nread;
339dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	union {
340dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		struct tzhead	tzhead;
341dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		char		buf[2 * sizeof(struct tzhead) +
342dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project					2 * sizeof *sp +
343dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project					4 * TZ_MAX_TIMES];
344dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	} u;
345dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    int                     toread = sizeof u.buf;
346dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
347dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	if (name == NULL && (name = TZDEFAULT) == NULL)
348dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		return -1;
349dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	{
350dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		register int	doaccess;
351dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		/*
352dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		** Section 4.9.1 of the C standard says that
353dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		** "FILENAME_MAX expands to an integral constant expression
354dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		** that is the size needed for an array of char large enough
355dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		** to hold the longest file name string that the implementation
356dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		** guarantees can be opened."
357dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		*/
358dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		char		fullname[FILENAME_MAX + 1];
359dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		const char	*origname = name;
360dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
361dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		if (name[0] == ':')
362dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			++name;
363dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		doaccess = name[0] == '/';
364dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		if (!doaccess) {
365dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			if ((p = TZDIR) == NULL)
366dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project				return -1;
367dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			if ((strlen(p) + strlen(name) + 1) >= sizeof fullname)
368dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project				return -1;
369dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			(void) strcpy(fullname, p);
370dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			(void) strcat(fullname, "/");
371dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			(void) strcat(fullname, name);
372dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			/*
373dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			** Set doaccess if '.' (as in "../") shows up in name.
374dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			*/
375dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			if (strchr(name, '.') != NULL)
376dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project				doaccess = TRUE;
377dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			name = fullname;
378dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		}
379dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		if (doaccess && access(name, R_OK) != 0)
380dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			return -1;
381dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		if ((fid = open(name, OPEN_MODE)) == -1) {
382dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            char buf[READLEN];
383dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            char name[NAMELEN + 1];
384dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            int fidix = open(INDEXFILE, OPEN_MODE);
385dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            int off = -1;
386dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
387dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            if (fidix < 0) {
388dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                return -1;
389dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            }
390dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
391dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            while (read(fidix, buf, sizeof(buf)) == sizeof(buf)) {
392dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                memcpy(name, buf, NAMELEN);
393dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                name[NAMELEN] = '\0';
394dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
395dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                if (strcmp(name, origname) == 0) {
396dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                    off = toint((unsigned char *) buf + NAMELEN);
397dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                    toread = toint((unsigned char *) buf + NAMELEN + INTLEN);
398dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                    break;
399dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                }
400dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            }
401dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
402dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            close(fidix);
403dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
404dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            if (off < 0)
405dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                return -1;
406dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
407dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            fid = open(DATAFILE, OPEN_MODE);
408dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
409dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            if (fid < 0) {
410dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                return -1;
411dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            }
412dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
413dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            if (lseek(fid, off, SEEK_SET) < 0) {
414dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                return -1;
415dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            }
416dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        }
417dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	}
418dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	nread = read(fid, u.buf, toread);
419dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	if (close(fid) < 0 || nread <= 0)
420dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		return -1;
421dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	for (stored = 4; stored <= 8; stored *= 2) {
422dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		int		ttisstdcnt;
423dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		int		ttisgmtcnt;
424dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
425dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		ttisstdcnt = (int) detzcode(u.tzhead.tzh_ttisstdcnt);
426dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		ttisgmtcnt = (int) detzcode(u.tzhead.tzh_ttisgmtcnt);
427dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		sp->leapcnt = (int) detzcode(u.tzhead.tzh_leapcnt);
428dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		sp->timecnt = (int) detzcode(u.tzhead.tzh_timecnt);
429dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		sp->typecnt = (int) detzcode(u.tzhead.tzh_typecnt);
430dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		sp->charcnt = (int) detzcode(u.tzhead.tzh_charcnt);
431dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		p = u.tzhead.tzh_charcnt + sizeof u.tzhead.tzh_charcnt;
432dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		if (sp->leapcnt < 0 || sp->leapcnt > TZ_MAX_LEAPS ||
433dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			sp->typecnt <= 0 || sp->typecnt > TZ_MAX_TYPES ||
434dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			sp->timecnt < 0 || sp->timecnt > TZ_MAX_TIMES ||
435dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			sp->charcnt < 0 || sp->charcnt > TZ_MAX_CHARS ||
436dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			(ttisstdcnt != sp->typecnt && ttisstdcnt != 0) ||
437dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			(ttisgmtcnt != sp->typecnt && ttisgmtcnt != 0))
438dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project				return -1;
439dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		if (nread - (p - u.buf) <
440dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			sp->timecnt * stored +		/* ats */
441dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			sp->timecnt +			/* types */
442dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			sp->typecnt * 6 +		/* ttinfos */
443dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			sp->charcnt +			/* chars */
444dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			sp->leapcnt * (stored + 4) +	/* lsinfos */
445dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			ttisstdcnt +			/* ttisstds */
446dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			ttisgmtcnt)			/* ttisgmts */
447dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project				return -1;
448dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		for (i = 0; i < sp->timecnt; ++i) {
449dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			sp->ats[i] = (stored == 4) ?
450dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project				detzcode(p) : detzcode64(p);
451dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			p += stored;
452dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		}
453dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		for (i = 0; i < sp->timecnt; ++i) {
454dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			sp->types[i] = (unsigned char) *p++;
455dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			if (sp->types[i] >= sp->typecnt)
456dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project				return -1;
457dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		}
458dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		for (i = 0; i < sp->typecnt; ++i) {
459dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			register struct ttinfo *	ttisp;
460dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
461dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			ttisp = &sp->ttis[i];
462dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			ttisp->tt_gmtoff = detzcode(p);
463dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			p += 4;
464dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			ttisp->tt_isdst = (unsigned char) *p++;
465dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			if (ttisp->tt_isdst != 0 && ttisp->tt_isdst != 1)
466dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project				return -1;
467dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			ttisp->tt_abbrind = (unsigned char) *p++;
468dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			if (ttisp->tt_abbrind < 0 ||
469dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project				ttisp->tt_abbrind > sp->charcnt)
470dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project					return -1;
471dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		}
472dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		for (i = 0; i < sp->charcnt; ++i)
473dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			sp->chars[i] = *p++;
474dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		sp->chars[i] = '\0';	/* ensure '\0' at end */
475dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		for (i = 0; i < sp->leapcnt; ++i) {
476dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			register struct lsinfo *	lsisp;
477dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
478dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			lsisp = &sp->lsis[i];
479dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			lsisp->ls_trans = (stored == 4) ?
480dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project				detzcode(p) : detzcode64(p);
481dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			p += stored;
482dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			lsisp->ls_corr = detzcode(p);
483dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			p += 4;
484dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		}
485dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		for (i = 0; i < sp->typecnt; ++i) {
486dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			register struct ttinfo *	ttisp;
487dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
488dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			ttisp = &sp->ttis[i];
489dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			if (ttisstdcnt == 0)
490dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project				ttisp->tt_ttisstd = FALSE;
491dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			else {
492dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project				ttisp->tt_ttisstd = *p++;
493dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project				if (ttisp->tt_ttisstd != TRUE &&
494dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project					ttisp->tt_ttisstd != FALSE)
495dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project						return -1;
496dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			}
497dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		}
498dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		for (i = 0; i < sp->typecnt; ++i) {
499dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			register struct ttinfo *	ttisp;
500dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
501dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			ttisp = &sp->ttis[i];
502dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			if (ttisgmtcnt == 0)
503dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project				ttisp->tt_ttisgmt = FALSE;
504dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			else {
505dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project				ttisp->tt_ttisgmt = *p++;
506dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project				if (ttisp->tt_ttisgmt != TRUE &&
507dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project					ttisp->tt_ttisgmt != FALSE)
508dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project						return -1;
509dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			}
510dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		}
511dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		/*
512dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		** Out-of-sort ats should mean we're running on a
513dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		** signed time_t system but using a data file with
514dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		** unsigned values (or vice versa).
515dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		*/
516dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		for (i = 0; i < sp->timecnt - 2; ++i)
517dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			if (sp->ats[i] > sp->ats[i + 1]) {
518dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project				++i;
519dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project				if (TYPE_SIGNED(time_t)) {
520dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project					/*
521dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project					** Ignore the end (easy).
522dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project					*/
523dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project					sp->timecnt = i;
524dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project				} else {
525dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project					/*
526dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project					** Ignore the beginning (harder).
527dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project					*/
528dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project					register int	j;
529dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
530dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project					for (j = 0; j + i < sp->timecnt; ++j) {
531dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project						sp->ats[j] = sp->ats[j + i];
532dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project						sp->types[j] = sp->types[j + i];
533dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project					}
534dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project					sp->timecnt = j;
535dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project				}
536dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project				break;
537dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			}
538dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		/*
539dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		** If this is an old file, we're done.
540dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		*/
541dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		if (u.tzhead.tzh_version[0] == '\0')
542dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			break;
543dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		nread -= p - u.buf;
544dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		for (i = 0; i < nread; ++i)
545dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			u.buf[i] = p[i];
546dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		/*
547dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		** If this is a narrow integer time_t system, we're done.
548dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		*/
549dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		if (stored >= (int) sizeof(time_t) && TYPE_INTEGRAL(time_t))
550dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			break;
551dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	}
552dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	if (doextend && nread > 2 &&
553dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		u.buf[0] == '\n' && u.buf[nread - 1] == '\n' &&
554dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		sp->typecnt + 2 <= TZ_MAX_TYPES) {
555dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			struct state	ts;
556dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			register int	result;
557dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
558dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			u.buf[nread - 1] = '\0';
559dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			result = tzparse(&u.buf[1], &ts, FALSE);
560dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			if (result == 0 && ts.typecnt == 2 &&
561dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project				sp->charcnt + ts.charcnt <= TZ_MAX_CHARS) {
562dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project					for (i = 0; i < 2; ++i)
563dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project						ts.ttis[i].tt_abbrind +=
564dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project							sp->charcnt;
565dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project					for (i = 0; i < ts.charcnt; ++i)
566dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project						sp->chars[sp->charcnt++] =
567dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project							ts.chars[i];
568dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project					i = 0;
569dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project					while (i < ts.timecnt &&
570dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project						ts.ats[i] <=
571dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project						sp->ats[sp->timecnt - 1])
572dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project							++i;
573dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project					while (i < ts.timecnt &&
574dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project					    sp->timecnt < TZ_MAX_TIMES) {
575dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project						sp->ats[sp->timecnt] =
576dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project							ts.ats[i];
577dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project						sp->types[sp->timecnt] =
578dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project							sp->typecnt +
579dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project							ts.types[i];
580dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project						++sp->timecnt;
581dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project						++i;
582dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project					}
583dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project					sp->ttis[sp->typecnt++] = ts.ttis[0];
584dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project					sp->ttis[sp->typecnt++] = ts.ttis[1];
585dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			}
586dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	}
587dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	i = 2 * YEARSPERREPEAT;
588dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	sp->goback = sp->goahead = sp->timecnt > i;
589dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	sp->goback &= sp->types[i] == sp->types[0] &&
590dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		differ_by_repeat(sp->ats[i], sp->ats[0]);
591dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	sp->goahead &=
592dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		sp->types[sp->timecnt - 1] == sp->types[sp->timecnt - 1 - i] &&
593dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		differ_by_repeat(sp->ats[sp->timecnt - 1],
594dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			 sp->ats[sp->timecnt - 1 - i]);
595dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	return 0;
596dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
597dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
598dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic const int	mon_lengths[2][MONSPERYEAR] = {
599dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	{ 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 },
600dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	{ 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }
601dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project};
602dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
603dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic const int	year_lengths[2] = {
604dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	DAYSPERNYEAR, DAYSPERLYEAR
605dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project};
606dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
607dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project/*
608dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project** Given a pointer into a time zone string, scan until a character that is not
609dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project** a valid character in a zone name is found. Return a pointer to that
610dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project** character.
611dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project*/
612dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
613dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic const char *
614dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectgetzname(strp)
615dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectregister const char *	strp;
616dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
617dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	register char	c;
618dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
619dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	while ((c = *strp) != '\0' && !is_digit(c) && c != ',' && c != '-' &&
620dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		c != '+')
621dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			++strp;
622dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	return strp;
623dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
624dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
625dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project/*
626dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project** Given a pointer into an extended time zone string, scan until the ending
627dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project** delimiter of the zone name is located. Return a pointer to the delimiter.
628dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project**
629dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project** As with getzname above, the legal character set is actually quite
630dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project** restricted, with other characters producing undefined results.
631dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project** We don't do any checking here; checking is done later in common-case code.
632dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project*/
633dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
634dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic const char *
635dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectgetqzname(register const char *strp, const int delim)
636dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
637dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	register int	c;
638dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
639dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	while ((c = *strp) != '\0' && c != delim)
640dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		++strp;
641dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	return strp;
642dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
643dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
644dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project/*
645dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project** Given a pointer into a time zone string, extract a number from that string.
646dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project** Check that the number is within a specified range; if it is not, return
647dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project** NULL.
648dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project** Otherwise, return a pointer to the first character not part of the number.
649dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project*/
650dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
651dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic const char *
652dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectgetnum(strp, nump, min, max)
653dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectregister const char *	strp;
654dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectint * const		nump;
655dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectconst int		min;
656dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectconst int		max;
657dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
658dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	register char	c;
659dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	register int	num;
660dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
661dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	if (strp == NULL || !is_digit(c = *strp))
662dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		return NULL;
663dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	num = 0;
664dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	do {
665dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		num = num * 10 + (c - '0');
666dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		if (num > max)
667dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			return NULL;	/* illegal value */
668dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		c = *++strp;
669dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	} while (is_digit(c));
670dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	if (num < min)
671dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		return NULL;		/* illegal value */
672dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	*nump = num;
673dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	return strp;
674dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
675dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
676dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project/*
677dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project** Given a pointer into a time zone string, extract a number of seconds,
678dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project** in hh[:mm[:ss]] form, from the string.
679dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project** If any error occurs, return NULL.
680dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project** Otherwise, return a pointer to the first character not part of the number
681dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project** of seconds.
682dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project*/
683dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
684dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic const char *
685dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectgetsecs(strp, secsp)
686dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectregister const char *	strp;
687dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectlong * const		secsp;
688dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
689dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	int	num;
690dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
691dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	/*
692dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	** `HOURSPERDAY * DAYSPERWEEK - 1' allows quasi-Posix rules like
693dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	** "M10.4.6/26", which does not conform to Posix,
694dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	** but which specifies the equivalent of
695dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	** ``02:00 on the first Sunday on or after 23 Oct''.
696dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	*/
697dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	strp = getnum(strp, &num, 0, HOURSPERDAY * DAYSPERWEEK - 1);
698dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	if (strp == NULL)
699dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		return NULL;
700dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	*secsp = num * (long) SECSPERHOUR;
701dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	if (*strp == ':') {
702dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		++strp;
703dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		strp = getnum(strp, &num, 0, MINSPERHOUR - 1);
704dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		if (strp == NULL)
705dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			return NULL;
706dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		*secsp += num * SECSPERMIN;
707dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		if (*strp == ':') {
708dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			++strp;
709dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			/* `SECSPERMIN' allows for leap seconds. */
710dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			strp = getnum(strp, &num, 0, SECSPERMIN);
711dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			if (strp == NULL)
712dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project				return NULL;
713dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			*secsp += num;
714dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		}
715dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	}
716dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	return strp;
717dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
718dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
719dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project/*
720dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project** Given a pointer into a time zone string, extract an offset, in
721dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project** [+-]hh[:mm[:ss]] form, from the string.
722dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project** If any error occurs, return NULL.
723dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project** Otherwise, return a pointer to the first character not part of the time.
724dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project*/
725dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
726dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic const char *
727dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectgetoffset(strp, offsetp)
728dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectregister const char *	strp;
729dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectlong * const		offsetp;
730dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
731dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	register int	neg = 0;
732dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
733dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	if (*strp == '-') {
734dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		neg = 1;
735dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		++strp;
736dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	} else if (*strp == '+')
737dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		++strp;
738dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	strp = getsecs(strp, offsetp);
739dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	if (strp == NULL)
740dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		return NULL;		/* illegal time */
741dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	if (neg)
742dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		*offsetp = -*offsetp;
743dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	return strp;
744dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
745dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
746dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project/*
747dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project** Given a pointer into a time zone string, extract a rule in the form
748dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project** date[/time]. See POSIX section 8 for the format of "date" and "time".
749dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project** If a valid rule is not found, return NULL.
750dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project** Otherwise, return a pointer to the first character not part of the rule.
751dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project*/
752dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
753dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic const char *
754dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectgetrule(strp, rulep)
755dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectconst char *			strp;
756dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectregister struct rule * const	rulep;
757dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
758dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	if (*strp == 'J') {
759dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		/*
760dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		** Julian day.
761dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		*/
762dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		rulep->r_type = JULIAN_DAY;
763dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		++strp;
764dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		strp = getnum(strp, &rulep->r_day, 1, DAYSPERNYEAR);
765dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	} else if (*strp == 'M') {
766dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		/*
767dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		** Month, week, day.
768dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		*/
769dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		rulep->r_type = MONTH_NTH_DAY_OF_WEEK;
770dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		++strp;
771dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		strp = getnum(strp, &rulep->r_mon, 1, MONSPERYEAR);
772dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		if (strp == NULL)
773dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			return NULL;
774dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		if (*strp++ != '.')
775dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			return NULL;
776dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		strp = getnum(strp, &rulep->r_week, 1, 5);
777dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		if (strp == NULL)
778dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			return NULL;
779dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		if (*strp++ != '.')
780dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			return NULL;
781dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		strp = getnum(strp, &rulep->r_day, 0, DAYSPERWEEK - 1);
782dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	} else if (is_digit(*strp)) {
783dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		/*
784dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		** Day of year.
785dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		*/
786dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		rulep->r_type = DAY_OF_YEAR;
787dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		strp = getnum(strp, &rulep->r_day, 0, DAYSPERLYEAR - 1);
788dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	} else	return NULL;		/* invalid format */
789dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	if (strp == NULL)
790dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		return NULL;
791dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	if (*strp == '/') {
792dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		/*
793dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		** Time specified.
794dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		*/
795dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		++strp;
796dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		strp = getsecs(strp, &rulep->r_time);
797dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	} else	rulep->r_time = 2 * SECSPERHOUR;	/* default = 2:00:00 */
798dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	return strp;
799dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
800dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
801dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project/*
802dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project** Given the Epoch-relative time of January 1, 00:00:00 UTC, in a year, the
803dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project** year, a rule, and the offset from UTC at the time that rule takes effect,
804dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project** calculate the Epoch-relative time that rule takes effect.
805dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project*/
806dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
807dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic time_t
808dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projecttranstime(janfirst, year, rulep, offset)
809dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectconst time_t				janfirst;
810dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectconst int				year;
811dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectregister const struct rule * const	rulep;
812dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectconst long				offset;
813dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
814dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	register int	leapyear;
815dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	register time_t	value;
816dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	register int	i;
817dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	int		d, m1, yy0, yy1, yy2, dow;
818dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
819dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	INITIALIZE(value);
820dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	leapyear = isleap(year);
821dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	switch (rulep->r_type) {
822dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
823dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	case JULIAN_DAY:
824dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		/*
825dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		** Jn - Julian day, 1 == January 1, 60 == March 1 even in leap
826dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		** years.
827dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		** In non-leap years, or if the day number is 59 or less, just
828dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		** add SECSPERDAY times the day number-1 to the time of
829dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		** January 1, midnight, to get the day.
830dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		*/
831dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		value = janfirst + (rulep->r_day - 1) * SECSPERDAY;
832dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		if (leapyear && rulep->r_day >= 60)
833dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			value += SECSPERDAY;
834dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		break;
835dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
836dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	case DAY_OF_YEAR:
837dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		/*
838dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		** n - day of year.
839dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		** Just add SECSPERDAY times the day number to the time of
840dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		** January 1, midnight, to get the day.
841dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		*/
842dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		value = janfirst + rulep->r_day * SECSPERDAY;
843dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		break;
844dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
845dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	case MONTH_NTH_DAY_OF_WEEK:
846dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		/*
847dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		** Mm.n.d - nth "dth day" of month m.
848dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		*/
849dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		value = janfirst;
850dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		for (i = 0; i < rulep->r_mon - 1; ++i)
851dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			value += mon_lengths[leapyear][i] * SECSPERDAY;
852dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
853dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		/*
854dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		** Use Zeller's Congruence to get day-of-week of first day of
855dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		** month.
856dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		*/
857dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		m1 = (rulep->r_mon + 9) % 12 + 1;
858dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		yy0 = (rulep->r_mon <= 2) ? (year - 1) : year;
859dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		yy1 = yy0 / 100;
860dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		yy2 = yy0 % 100;
861dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		dow = ((26 * m1 - 2) / 10 +
862dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			1 + yy2 + yy2 / 4 + yy1 / 4 - 2 * yy1) % 7;
863dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		if (dow < 0)
864dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			dow += DAYSPERWEEK;
865dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
866dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		/*
867dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		** "dow" is the day-of-week of the first day of the month. Get
868dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		** the day-of-month (zero-origin) of the first "dow" day of the
869dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		** month.
870dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		*/
871dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		d = rulep->r_day - dow;
872dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		if (d < 0)
873dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			d += DAYSPERWEEK;
874dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		for (i = 1; i < rulep->r_week; ++i) {
875dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			if (d + DAYSPERWEEK >=
876dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project				mon_lengths[leapyear][rulep->r_mon - 1])
877dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project					break;
878dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			d += DAYSPERWEEK;
879dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		}
880dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
881dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		/*
882dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		** "d" is the day-of-month (zero-origin) of the day we want.
883dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		*/
884dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		value += d * SECSPERDAY;
885dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		break;
886dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	}
887dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
888dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	/*
889dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	** "value" is the Epoch-relative time of 00:00:00 UTC on the day in
890dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	** question. To get the Epoch-relative time of the specified local
891dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	** time on that day, add the transition time and the current offset
892dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	** from UTC.
893dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	*/
894dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	return value + rulep->r_time + offset;
895dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
896dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
897dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project/*
898dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project** Given a POSIX section 8-style TZ string, fill in the rule tables as
899dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project** appropriate.
900dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project*/
901dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
902dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic int
903dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projecttzparse(name, sp, lastditch)
904dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectconst char *			name;
905dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectregister struct state * const	sp;
906dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectconst int			lastditch;
907dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
908dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	const char *			stdname;
909dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	const char *			dstname;
910dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	size_t				stdlen;
911dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	size_t				dstlen;
912dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	long				stdoffset;
913dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	long				dstoffset;
914dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	register time_t *		atp;
915dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	register unsigned char *	typep;
916dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	register char *			cp;
917dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	register int			load_result;
918dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
919dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	INITIALIZE(dstname);
920dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	stdname = name;
921dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	if (lastditch) {
922dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		stdlen = strlen(name);	/* length of standard zone name */
923dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		name += stdlen;
924dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		if (stdlen >= sizeof sp->chars)
925dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			stdlen = (sizeof sp->chars) - 1;
926dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		stdoffset = 0;
927dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	} else {
928dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		if (*name == '<') {
929dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			name++;
930dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			stdname = name;
931dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			name = getqzname(name, '>');
932dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			if (*name != '>')
933dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project				return (-1);
934dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			stdlen = name - stdname;
935dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			name++;
936dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		} else {
937dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			name = getzname(name);
938dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			stdlen = name - stdname;
939dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		}
940dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		if (*name == '\0')
941dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			return -1;
942dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		name = getoffset(name, &stdoffset);
943dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		if (name == NULL)
944dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			return -1;
945dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	}
946dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	load_result = tzload(TZDEFRULES, sp, FALSE);
947dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	if (load_result != 0)
948dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		sp->leapcnt = 0;		/* so, we're off a little */
949dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	sp->timecnt = 0;
950dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	if (*name != '\0') {
951dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		if (*name == '<') {
952dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			dstname = ++name;
953dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			name = getqzname(name, '>');
954dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			if (*name != '>')
955dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project				return -1;
956dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			dstlen = name - dstname;
957dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			name++;
958dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		} else {
959dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			dstname = name;
960dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			name = getzname(name);
961dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			dstlen = name - dstname; /* length of DST zone name */
962dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		}
963dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		if (*name != '\0' && *name != ',' && *name != ';') {
964dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			name = getoffset(name, &dstoffset);
965dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			if (name == NULL)
966dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project				return -1;
967dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		} else	dstoffset = stdoffset - SECSPERHOUR;
968dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		if (*name == '\0' && load_result != 0)
969dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			name = TZDEFRULESTRING;
970dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		if (*name == ',' || *name == ';') {
971dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			struct rule	start;
972dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			struct rule	end;
973dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			register int	year;
974dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			register time_t	janfirst;
975dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			time_t		starttime;
976dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			time_t		endtime;
977dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
978dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			++name;
979dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			if ((name = getrule(name, &start)) == NULL)
980dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project				return -1;
981dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			if (*name++ != ',')
982dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project				return -1;
983dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			if ((name = getrule(name, &end)) == NULL)
984dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project				return -1;
985dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			if (*name != '\0')
986dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project				return -1;
987dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			sp->typecnt = 2;	/* standard time and DST */
988dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			/*
989dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			** Two transitions per year, from EPOCH_YEAR forward.
990dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			*/
991dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			sp->ttis[0].tt_gmtoff = -dstoffset;
992dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			sp->ttis[0].tt_isdst = 1;
993dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			sp->ttis[0].tt_abbrind = stdlen + 1;
994dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			sp->ttis[1].tt_gmtoff = -stdoffset;
995dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			sp->ttis[1].tt_isdst = 0;
996dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			sp->ttis[1].tt_abbrind = 0;
997dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			atp = sp->ats;
998dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			typep = sp->types;
999dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			janfirst = 0;
1000dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			for (year = EPOCH_YEAR;
1001dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			    sp->timecnt + 2 <= TZ_MAX_TIMES;
1002dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			    ++year) {
1003dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			    	time_t	newfirst;
1004dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
1005dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project				starttime = transtime(janfirst, year, &start,
1006dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project					stdoffset);
1007dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project				endtime = transtime(janfirst, year, &end,
1008dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project					dstoffset);
1009dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project				if (starttime > endtime) {
1010dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project					*atp++ = endtime;
1011dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project					*typep++ = 1;	/* DST ends */
1012dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project					*atp++ = starttime;
1013dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project					*typep++ = 0;	/* DST begins */
1014dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project				} else {
1015dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project					*atp++ = starttime;
1016dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project					*typep++ = 0;	/* DST begins */
1017dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project					*atp++ = endtime;
1018dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project					*typep++ = 1;	/* DST ends */
1019dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project				}
1020dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project				sp->timecnt += 2;
1021dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project				newfirst = janfirst;
1022dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project				newfirst += year_lengths[isleap(year)] *
1023dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project					SECSPERDAY;
1024dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project				if (newfirst <= janfirst)
1025dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project					break;
1026dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project				janfirst = newfirst;
1027dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			}
1028dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		} else {
1029dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			register long	theirstdoffset;
1030dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			register long	theirdstoffset;
1031dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			register long	theiroffset;
1032dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			register int	isdst;
1033dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			register int	i;
1034dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			register int	j;
1035dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
1036dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			if (*name != '\0')
1037dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project				return -1;
1038dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			/*
1039dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			** Initial values of theirstdoffset and theirdstoffset.
1040dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			*/
1041dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			theirstdoffset = 0;
1042dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			for (i = 0; i < sp->timecnt; ++i) {
1043dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project				j = sp->types[i];
1044dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project				if (!sp->ttis[j].tt_isdst) {
1045dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project					theirstdoffset =
1046dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project						-sp->ttis[j].tt_gmtoff;
1047dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project					break;
1048dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project				}
1049dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			}
1050dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			theirdstoffset = 0;
1051dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			for (i = 0; i < sp->timecnt; ++i) {
1052dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project				j = sp->types[i];
1053dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project				if (sp->ttis[j].tt_isdst) {
1054dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project					theirdstoffset =
1055dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project						-sp->ttis[j].tt_gmtoff;
1056dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project					break;
1057dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project				}
1058dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			}
1059dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			/*
1060dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			** Initially we're assumed to be in standard time.
1061dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			*/
1062dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			isdst = FALSE;
1063dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			theiroffset = theirstdoffset;
1064dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			/*
1065dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			** Now juggle transition times and types
1066dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			** tracking offsets as you do.
1067dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			*/
1068dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			for (i = 0; i < sp->timecnt; ++i) {
1069dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project				j = sp->types[i];
1070dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project				sp->types[i] = sp->ttis[j].tt_isdst;
1071dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project				if (sp->ttis[j].tt_ttisgmt) {
1072dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project					/* No adjustment to transition time */
1073dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project				} else {
1074dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project					/*
1075dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project					** If summer time is in effect, and the
1076dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project					** transition time was not specified as
1077dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project					** standard time, add the summer time
1078dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project					** offset to the transition time;
1079dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project					** otherwise, add the standard time
1080dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project					** offset to the transition time.
1081dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project					*/
1082dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project					/*
1083dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project					** Transitions from DST to DDST
1084dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project					** will effectively disappear since
1085dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project					** POSIX provides for only one DST
1086dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project					** offset.
1087dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project					*/
1088dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project					if (isdst && !sp->ttis[j].tt_ttisstd) {
1089dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project						sp->ats[i] += dstoffset -
1090dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project							theirdstoffset;
1091dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project					} else {
1092dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project						sp->ats[i] += stdoffset -
1093dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project							theirstdoffset;
1094dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project					}
1095dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project				}
1096dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project				theiroffset = -sp->ttis[j].tt_gmtoff;
1097dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project				if (sp->ttis[j].tt_isdst)
1098dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project					theirdstoffset = theiroffset;
1099dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project				else	theirstdoffset = theiroffset;
1100dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			}
1101dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			/*
1102dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			** Finally, fill in ttis.
1103dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			** ttisstd and ttisgmt need not be handled.
1104dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			*/
1105dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			sp->ttis[0].tt_gmtoff = -stdoffset;
1106dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			sp->ttis[0].tt_isdst = FALSE;
1107dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			sp->ttis[0].tt_abbrind = 0;
1108dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			sp->ttis[1].tt_gmtoff = -dstoffset;
1109dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			sp->ttis[1].tt_isdst = TRUE;
1110dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			sp->ttis[1].tt_abbrind = stdlen + 1;
1111dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			sp->typecnt = 2;
1112dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		}
1113dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	} else {
1114dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		dstlen = 0;
1115dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		sp->typecnt = 1;		/* only standard time */
1116dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		sp->timecnt = 0;
1117dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		sp->ttis[0].tt_gmtoff = -stdoffset;
1118dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		sp->ttis[0].tt_isdst = 0;
1119dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		sp->ttis[0].tt_abbrind = 0;
1120dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	}
1121dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	sp->charcnt = stdlen + 1;
1122dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	if (dstlen != 0)
1123dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		sp->charcnt += dstlen + 1;
1124dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	if ((size_t) sp->charcnt > sizeof sp->chars)
1125dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		return -1;
1126dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	cp = sp->chars;
1127dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	(void) strncpy(cp, stdname, stdlen);
1128dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	cp += stdlen;
1129dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	*cp++ = '\0';
1130dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	if (dstlen != 0) {
1131dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		(void) strncpy(cp, dstname, dstlen);
1132dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		*(cp + dstlen) = '\0';
1133dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	}
1134dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	return 0;
1135dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
1136dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
1137dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic void
1138dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectgmtload(sp)
1139dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstruct state * const	sp;
1140dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
1141dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	if (tzload(gmt, sp, TRUE) != 0)
1142dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		(void) tzparse(gmt, sp, TRUE);
1143dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
1144dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
1145dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project/*
1146dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project** The easy way to behave "as if no library function calls" localtime
1147dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project** is to not call it--so we drop its guts into "localsub", which can be
1148dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project** freely called. (And no, the PANS doesn't require the above behavior--
1149dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project** but it *is* desirable.)
1150dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project**
1151dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project** The unused offset argument is for the benefit of mktime variants.
1152dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project*/
1153dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
1154dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project/*ARGSUSED*/
1155dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic struct tm *
1156dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectlocalsub(timep, offset, tmp, sp)
1157dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectconst time_t * const	timep;
1158dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectconst long		offset;
1159dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstruct tm * const	tmp;
1160dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstruct state *		sp;
1161dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
1162dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	register const struct ttinfo *	ttisp;
1163dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	register int			i;
1164dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	register struct tm *		result;
1165dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	const time_t			t = *timep;
1166dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
1167dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#ifdef ALL_STATE
1168dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	if (sp == NULL)
1169dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		return gmtsub(timep, offset, tmp);
1170dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#endif /* defined ALL_STATE */
1171dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	if ((sp->goback && t < sp->ats[0]) ||
1172dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		(sp->goahead && t > sp->ats[sp->timecnt - 1])) {
1173dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			time_t			newt = t;
1174dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			register time_t		seconds;
1175dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			register time_t		tcycles;
1176dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			register int_fast64_t	icycles;
1177dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
1178dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			if (t < sp->ats[0])
1179dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project				seconds = sp->ats[0] - t;
1180dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			else	seconds = t - sp->ats[sp->timecnt - 1];
1181dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			--seconds;
1182dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			tcycles = seconds / YEARSPERREPEAT / AVGSECSPERYEAR;
1183dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			++tcycles;
1184dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			icycles = tcycles;
1185dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			if (tcycles - icycles >= 1 || icycles - tcycles >= 1)
1186dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project				return NULL;
1187dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			seconds = icycles;
1188dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			seconds *= YEARSPERREPEAT;
1189dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			seconds *= AVGSECSPERYEAR;
1190dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			if (t < sp->ats[0])
1191dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project				newt += seconds;
1192dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			else	newt -= seconds;
1193dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			if (newt < sp->ats[0] ||
1194dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project				newt > sp->ats[sp->timecnt - 1])
1195dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project					return NULL;	/* "cannot happen" */
1196dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			result = localsub(&newt, offset, tmp, sp);
1197dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			if (result == tmp) {
1198dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project				register time_t	newy;
1199dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
1200dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project				newy = tmp->tm_year;
1201dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project				if (t < sp->ats[0])
1202dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project					newy -= icycles * YEARSPERREPEAT;
1203dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project				else	newy += icycles * YEARSPERREPEAT;
1204dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project				tmp->tm_year = newy;
1205dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project				if (tmp->tm_year != newy)
1206dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project					return NULL;
1207dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			}
1208dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			return result;
1209dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	}
1210dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	if (sp->timecnt == 0 || t < sp->ats[0]) {
1211dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		i = 0;
1212dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		while (sp->ttis[i].tt_isdst)
1213dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			if (++i >= sp->typecnt) {
1214dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project				i = 0;
1215dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project				break;
1216dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			}
1217dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	} else {
1218dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		register int	lo = 1;
1219dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		register int	hi = sp->timecnt;
1220dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
1221dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		while (lo < hi) {
1222dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			register int	mid = (lo + hi) >> 1;
1223dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
1224dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			if (t < sp->ats[mid])
1225dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project				hi = mid;
1226dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			else	lo = mid + 1;
1227dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		}
1228dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		i = (int) sp->types[lo - 1];
1229dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	}
1230dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	ttisp = &sp->ttis[i];
1231dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	/*
1232dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	** To get (wrong) behavior that's compatible with System V Release 2.0
1233dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	** you'd replace the statement below with
1234dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	**	t += ttisp->tt_gmtoff;
1235dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	**	timesub(&t, 0L, sp, tmp);
1236dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	*/
1237dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	result = timesub(&t, ttisp->tt_gmtoff, sp, tmp);
1238dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	tmp->tm_isdst = ttisp->tt_isdst;
1239dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#ifdef HAVE_TM_GMTOFF
1240dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	tmp->tm_gmtoff = ttisp->tt_gmtoff;
1241dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#endif
1242dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	tzname[tmp->tm_isdst] = &sp->chars[ttisp->tt_abbrind];
1243dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#ifdef TM_ZONE
1244dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	tmp->TM_ZONE = &sp->chars[ttisp->tt_abbrind];
1245dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#endif /* defined TM_ZONE */
1246dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	return result;
1247dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
1248dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
1249dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
1250dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project// ============================================================================
1251dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#if 0
1252dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstruct tm *
1253dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectlocaltime(timep)
1254dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectconst time_t * const	timep;
1255dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
1256dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	tzset();
1257dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	return localsub(timep, 0L, &tm);
1258dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
1259dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#endif
1260dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
1261dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project/*
1262dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project** Re-entrant version of localtime.
1263dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project*/
1264dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
1265dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project// ============================================================================
1266dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectvoid
1267dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectlocaltime_tz(const time_t * const timep, struct tm * tmp, const char* tz)
1268dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
1269dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    struct state st;
1270dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if (tzload(tz, &st, TRUE) != 0) {
1271dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        // not sure what's best here, but for now, we fall back to gmt
1272dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        gmtload(&st);
1273dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
1274dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
1275dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	localsub(timep, 0L, tmp, &st);
1276dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
1277dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
1278dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project/*
1279dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project** gmtsub is to gmtime as localsub is to localtime.
1280dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project*/
1281dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
1282dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic struct tm *
1283dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectgmtsub(timep, offset, tmp)
1284dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectconst time_t * const	timep;
1285dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectconst long		offset;
1286dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstruct tm * const	tmp;
1287dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
1288dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	register struct tm *	result;
1289dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
1290dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	if (!gmt_is_set) {
1291dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		gmt_is_set = TRUE;
1292dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#ifdef ALL_STATE
1293dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		gmtptr = (struct state *) malloc(sizeof *gmtptr);
1294dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		if (gmtptr != NULL)
1295dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#endif /* defined ALL_STATE */
1296dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			gmtload(gmtptr);
1297dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	}
1298dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	result = timesub(timep, offset, gmtptr, tmp);
1299dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#ifdef TM_ZONE
1300dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	/*
1301dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	** Could get fancy here and deliver something such as
1302dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	** "UTC+xxxx" or "UTC-xxxx" if offset is non-zero,
1303dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	** but this is no time for a treasure hunt.
1304dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	*/
1305dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	if (offset != 0)
1306dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		tmp->TM_ZONE = wildabbr;
1307dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	else {
1308dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#ifdef ALL_STATE
1309dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		if (gmtptr == NULL)
1310dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			tmp->TM_ZONE = gmt;
1311dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		else	tmp->TM_ZONE = gmtptr->chars;
1312dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#endif /* defined ALL_STATE */
1313dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#ifndef ALL_STATE
1314dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		tmp->TM_ZONE = gmtptr->chars;
1315dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#endif /* State Farm */
1316dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	}
1317dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#endif /* defined TM_ZONE */
1318dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	return result;
1319dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
1320dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
1321dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project// ============================================================================
1322dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#if 0
1323dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstruct tm *
1324dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectgmtime(timep)
1325dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectconst time_t * const	timep;
1326dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
1327dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	return gmtsub(timep, 0L, &tm);
1328dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
1329dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#endif
1330dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
1331dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project/*
1332dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project* Re-entrant version of gmtime.
1333dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project*/
1334dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
1335dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project// ============================================================================
1336dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#if 0
1337dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstruct tm *
1338dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectgmtime_r(timep, tmp)
1339dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectconst time_t * const	timep;
1340dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstruct tm *		tmp;
1341dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
1342dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	return gmtsub(timep, 0L, tmp);
1343dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
1344dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#endif
1345dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
1346dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#ifdef STD_INSPIRED
1347dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
1348dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project// ============================================================================
1349dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#if 0
1350dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstruct tm *
1351dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectofftime(timep, offset)
1352dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectconst time_t * const	timep;
1353dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectconst long		offset;
1354dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
1355dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	return gmtsub(timep, offset, &tm);
1356dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
1357dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#endif
1358dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
1359dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#endif /* defined STD_INSPIRED */
1360dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
1361dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project/*
1362dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project** Return the number of leap years through the end of the given year
1363dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project** where, to make the math easy, the answer for year zero is defined as zero.
1364dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project*/
1365dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
1366dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic int
1367dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectleaps_thru_end_of(y)
1368dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectregister const int	y;
1369dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
1370dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	return (y >= 0) ? (y / 4 - y / 100 + y / 400) :
1371dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		-(leaps_thru_end_of(-(y + 1)) + 1);
1372dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
1373dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
1374dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic struct tm *
1375dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projecttimesub(timep, offset, sp, tmp)
1376dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectconst time_t * const			timep;
1377dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectconst long				offset;
1378dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectregister const struct state * const	sp;
1379dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectregister struct tm * const		tmp;
1380dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
1381dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	register const struct lsinfo *	lp;
1382dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	register time_t			tdays;
1383dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	register int			idays;	/* unsigned would be so 2003 */
1384dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	register long			rem;
1385dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	int				y;
1386dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	register const int *		ip;
1387dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	register long			corr;
1388dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	register int			hit;
1389dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	register int			i;
1390dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
1391dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	corr = 0;
1392dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	hit = 0;
1393dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#ifdef ALL_STATE
1394dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	i = (sp == NULL) ? 0 : sp->leapcnt;
1395dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#endif /* defined ALL_STATE */
1396dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#ifndef ALL_STATE
1397dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	i = sp->leapcnt;
1398dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#endif /* State Farm */
1399dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	while (--i >= 0) {
1400dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		lp = &sp->lsis[i];
1401dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		if (*timep >= lp->ls_trans) {
1402dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			if (*timep == lp->ls_trans) {
1403dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project				hit = ((i == 0 && lp->ls_corr > 0) ||
1404dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project					lp->ls_corr > sp->lsis[i - 1].ls_corr);
1405dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project				if (hit)
1406dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project					while (i > 0 &&
1407dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project						sp->lsis[i].ls_trans ==
1408dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project						sp->lsis[i - 1].ls_trans + 1 &&
1409dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project						sp->lsis[i].ls_corr ==
1410dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project						sp->lsis[i - 1].ls_corr + 1) {
1411dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project							++hit;
1412dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project							--i;
1413dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project					}
1414dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			}
1415dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			corr = lp->ls_corr;
1416dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			break;
1417dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		}
1418dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	}
1419dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	y = EPOCH_YEAR;
1420dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	tdays = *timep / SECSPERDAY;
1421dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	rem = *timep - tdays * SECSPERDAY;
1422dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	while (tdays < 0 || tdays >= year_lengths[isleap(y)]) {
1423dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		int		newy;
1424dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		register time_t	tdelta;
1425dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		register int	idelta;
1426dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		register int	leapdays;
1427dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
1428dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		tdelta = tdays / DAYSPERLYEAR;
1429dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		idelta = tdelta;
1430dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		if (tdelta - idelta >= 1 || idelta - tdelta >= 1)
1431dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			return NULL;
1432dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		if (idelta == 0)
1433dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			idelta = (tdays < 0) ? -1 : 1;
1434dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		newy = y;
1435dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		if (increment_overflow(&newy, idelta))
1436dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			return NULL;
1437dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		leapdays = leaps_thru_end_of(newy - 1) -
1438dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			leaps_thru_end_of(y - 1);
1439dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		tdays -= ((time_t) newy - y) * DAYSPERNYEAR;
1440dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		tdays -= leapdays;
1441dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		y = newy;
1442dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	}
1443dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	{
1444dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		register long	seconds;
1445dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
1446dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		seconds = tdays * SECSPERDAY + 0.5;
1447dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		tdays = seconds / SECSPERDAY;
1448dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		rem += seconds - tdays * SECSPERDAY;
1449dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	}
1450dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	/*
1451dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	** Given the range, we can now fearlessly cast...
1452dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	*/
1453dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	idays = tdays;
1454dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	rem += offset - corr;
1455dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	while (rem < 0) {
1456dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		rem += SECSPERDAY;
1457dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		--idays;
1458dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	}
1459dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	while (rem >= SECSPERDAY) {
1460dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		rem -= SECSPERDAY;
1461dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		++idays;
1462dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	}
1463dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	while (idays < 0) {
1464dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		if (increment_overflow(&y, -1))
1465dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			return NULL;
1466dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		idays += year_lengths[isleap(y)];
1467dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	}
1468dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	while (idays >= year_lengths[isleap(y)]) {
1469dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		idays -= year_lengths[isleap(y)];
1470dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		if (increment_overflow(&y, 1))
1471dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			return NULL;
1472dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	}
1473dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	tmp->tm_year = y;
1474dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	if (increment_overflow(&tmp->tm_year, -TM_YEAR_BASE))
1475dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		return NULL;
1476dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	tmp->tm_yday = idays;
1477dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	/*
1478dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	** The "extra" mods below avoid overflow problems.
1479dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	*/
1480dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	tmp->tm_wday = EPOCH_WDAY +
1481dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		((y - EPOCH_YEAR) % DAYSPERWEEK) *
1482dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		(DAYSPERNYEAR % DAYSPERWEEK) +
1483dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		leaps_thru_end_of(y - 1) -
1484dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		leaps_thru_end_of(EPOCH_YEAR - 1) +
1485dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		idays;
1486dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	tmp->tm_wday %= DAYSPERWEEK;
1487dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	if (tmp->tm_wday < 0)
1488dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		tmp->tm_wday += DAYSPERWEEK;
1489dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	tmp->tm_hour = (int) (rem / SECSPERHOUR);
1490dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	rem %= SECSPERHOUR;
1491dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	tmp->tm_min = (int) (rem / SECSPERMIN);
1492dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	/*
1493dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	** A positive leap second requires a special
1494dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	** representation. This uses "... ??:59:60" et seq.
1495dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	*/
1496dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	tmp->tm_sec = (int) (rem % SECSPERMIN) + hit;
1497dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	ip = mon_lengths[isleap(y)];
1498dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	for (tmp->tm_mon = 0; idays >= ip[tmp->tm_mon]; ++(tmp->tm_mon))
1499dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		idays -= ip[tmp->tm_mon];
1500dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	tmp->tm_mday = (int) (idays + 1);
1501dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	tmp->tm_isdst = 0;
1502dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#ifdef TM_GMTOFF
1503dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	tmp->TM_GMTOFF = offset;
1504dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#endif /* defined TM_GMTOFF */
1505dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	return tmp;
1506dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
1507dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
1508dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project// ============================================================================
1509dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#if 0
1510dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectchar *
1511dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectctime(timep)
1512dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectconst time_t * const	timep;
1513dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
1514dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project/*
1515dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project** Section 4.12.3.2 of X3.159-1989 requires that
1516dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project**	The ctime function converts the calendar time pointed to by timer
1517dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project**	to local time in the form of a string. It is equivalent to
1518dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project**		asctime(localtime(timer))
1519dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project*/
1520dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	return asctime(localtime(timep));
1521dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
1522dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#endif
1523dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
1524dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project// ============================================================================
1525dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#if 0
1526dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectchar *
1527dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectctime_r(timep, buf)
1528dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectconst time_t * const	timep;
1529dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectchar *			buf;
1530dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
1531dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	struct tm	mytm;
1532dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
1533dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	return asctime_r(localtime_r(timep, &mytm), buf);
1534dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
1535dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#endif
1536dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
1537dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project/*
1538dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project** Adapted from code provided by Robert Elz, who writes:
1539dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project**	The "best" way to do mktime I think is based on an idea of Bob
1540dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project**	Kridle's (so its said...) from a long time ago.
1541dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project**	It does a binary search of the time_t space. Since time_t's are
1542dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project**	just 32 bits, its a max of 32 iterations (even at 64 bits it
1543dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project**	would still be very reasonable).
1544dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project*/
1545dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
1546dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#ifndef WRONG
1547dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#define WRONG	(-1)
1548dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#endif /* !defined WRONG */
1549dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
1550dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project/*
1551dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project** Simplified normalize logic courtesy Paul Eggert.
1552dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project*/
1553dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
1554dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic int
1555dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectincrement_overflow(number, delta)
1556dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectint *	number;
1557dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectint	delta;
1558dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
1559dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	int	number0;
1560dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
1561dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	number0 = *number;
1562dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	*number += delta;
1563dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	return (*number < number0) != (delta < 0);
1564dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
1565dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
1566dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic int
1567dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectlong_increment_overflow(number, delta)
1568dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectlong *	number;
1569dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectint	delta;
1570dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
1571dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	long	number0;
1572dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
1573dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	number0 = *number;
1574dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	*number += delta;
1575dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	return (*number < number0) != (delta < 0);
1576dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
1577dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
1578dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic int
1579dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectnormalize_overflow(tensptr, unitsptr, base)
1580dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectint * const	tensptr;
1581dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectint * const	unitsptr;
1582dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectconst int	base;
1583dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
1584dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	register int	tensdelta;
1585dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
1586dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	tensdelta = (*unitsptr >= 0) ?
1587dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		(*unitsptr / base) :
1588dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		(-1 - (-1 - *unitsptr) / base);
1589dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	*unitsptr -= tensdelta * base;
1590dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	return increment_overflow(tensptr, tensdelta);
1591dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
1592dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
1593dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic int
1594dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectlong_normalize_overflow(tensptr, unitsptr, base)
1595dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectlong * const	tensptr;
1596dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectint * const	unitsptr;
1597dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectconst int	base;
1598dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
1599dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	register int	tensdelta;
1600dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
1601dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	tensdelta = (*unitsptr >= 0) ?
1602dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		(*unitsptr / base) :
1603dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		(-1 - (-1 - *unitsptr) / base);
1604dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	*unitsptr -= tensdelta * base;
1605dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	return long_increment_overflow(tensptr, tensdelta);
1606dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
1607dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
1608dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic int
1609dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projecttmcomp(atmp, btmp)
1610dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectregister const struct tm * const atmp;
1611dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectregister const struct tm * const btmp;
1612dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
1613dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	register int	result;
1614dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
1615dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	if ((result = (atmp->tm_year - btmp->tm_year)) == 0 &&
1616dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		(result = (atmp->tm_mon - btmp->tm_mon)) == 0 &&
1617dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		(result = (atmp->tm_mday - btmp->tm_mday)) == 0 &&
1618dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		(result = (atmp->tm_hour - btmp->tm_hour)) == 0 &&
1619dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		(result = (atmp->tm_min - btmp->tm_min)) == 0)
1620dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			result = atmp->tm_sec - btmp->tm_sec;
1621dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	return result;
1622dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
1623dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
1624dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic time_t
1625dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projecttime2sub(tmp, funcp, offset, okayp, do_norm_secs, sp)
1626dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstruct tm * const	tmp;
1627dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstruct tm * (* const	funcp) P((const time_t*, long, struct tm*,const struct state *sp));
1628dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectconst long		offset;
1629dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectint * const		okayp;
1630dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectconst int		do_norm_secs;
1631dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectconst struct state *	sp;
1632dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
1633dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	register int			dir;
1634dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	register int			i, j;
1635dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	register int			saved_seconds;
1636dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	register long			li;
1637dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	register time_t			lo;
1638dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	register time_t			hi;
1639dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	long				y;
1640dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	time_t				newt;
1641dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	time_t				t;
1642dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	struct tm			yourtm, mytm;
1643dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
1644dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	*okayp = FALSE;
1645dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	yourtm = *tmp;
1646dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	if (do_norm_secs) {
1647dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		if (normalize_overflow(&yourtm.tm_min, &yourtm.tm_sec,
1648dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			SECSPERMIN))
1649dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project				return WRONG;
1650dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	}
1651dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	if (normalize_overflow(&yourtm.tm_hour, &yourtm.tm_min, MINSPERHOUR))
1652dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		return WRONG;
1653dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	if (normalize_overflow(&yourtm.tm_mday, &yourtm.tm_hour, HOURSPERDAY))
1654dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		return WRONG;
1655dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	y = yourtm.tm_year;
1656dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	if (long_normalize_overflow(&y, &yourtm.tm_mon, MONSPERYEAR))
1657dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		return WRONG;
1658dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	/*
1659dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	** Turn y into an actual year number for now.
1660dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	** It is converted back to an offset from TM_YEAR_BASE later.
1661dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	*/
1662dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	if (long_increment_overflow(&y, TM_YEAR_BASE))
1663dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		return WRONG;
1664dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	while (yourtm.tm_mday <= 0) {
1665dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		if (long_increment_overflow(&y, -1))
1666dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			return WRONG;
1667dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		li = y + (1 < yourtm.tm_mon);
1668dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		yourtm.tm_mday += year_lengths[isleap(li)];
1669dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	}
1670dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	while (yourtm.tm_mday > DAYSPERLYEAR) {
1671dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		li = y + (1 < yourtm.tm_mon);
1672dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		yourtm.tm_mday -= year_lengths[isleap(li)];
1673dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		if (long_increment_overflow(&y, 1))
1674dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			return WRONG;
1675dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	}
1676dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	for ( ; ; ) {
1677dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		i = mon_lengths[isleap(y)][yourtm.tm_mon];
1678dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		if (yourtm.tm_mday <= i)
1679dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			break;
1680dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		yourtm.tm_mday -= i;
1681dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		if (++yourtm.tm_mon >= MONSPERYEAR) {
1682dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			yourtm.tm_mon = 0;
1683dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			if (long_increment_overflow(&y, 1))
1684dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project				return WRONG;
1685dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		}
1686dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	}
1687dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	if (long_increment_overflow(&y, -TM_YEAR_BASE))
1688dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		return WRONG;
1689dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	yourtm.tm_year = y;
1690dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	if (yourtm.tm_year != y)
1691dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		return WRONG;
1692dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	if (yourtm.tm_sec >= 0 && yourtm.tm_sec < SECSPERMIN)
1693dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		saved_seconds = 0;
1694dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	else if (y + TM_YEAR_BASE < EPOCH_YEAR) {
1695dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		/*
1696dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		** We can't set tm_sec to 0, because that might push the
1697dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		** time below the minimum representable time.
1698dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		** Set tm_sec to 59 instead.
1699dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		** This assumes that the minimum representable time is
1700dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		** not in the same minute that a leap second was deleted from,
1701dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		** which is a safer assumption than using 58 would be.
1702dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		*/
1703dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		if (increment_overflow(&yourtm.tm_sec, 1 - SECSPERMIN))
1704dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			return WRONG;
1705dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		saved_seconds = yourtm.tm_sec;
1706dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		yourtm.tm_sec = SECSPERMIN - 1;
1707dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	} else {
1708dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		saved_seconds = yourtm.tm_sec;
1709dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		yourtm.tm_sec = 0;
1710dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	}
1711dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	/*
1712dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	** Do a binary search (this works whatever time_t's type is).
1713dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	*/
1714dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	if (!TYPE_SIGNED(time_t)) {
1715dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		lo = 0;
1716dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		hi = lo - 1;
1717dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	} else if (!TYPE_INTEGRAL(time_t)) {
1718dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		if (sizeof(time_t) > sizeof(float))
1719dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			hi = (time_t) DBL_MAX;
1720dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		else	hi = (time_t) FLT_MAX;
1721dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		lo = -hi;
1722dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	} else {
1723dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		lo = 1;
1724dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		for (i = 0; i < (int) TYPE_BIT(time_t) - 1; ++i)
1725dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			lo *= 2;
1726dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		hi = -(lo + 1);
1727dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	}
1728dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	for ( ; ; ) {
1729dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		t = lo / 2 + hi / 2;
1730dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		if (t < lo)
1731dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			t = lo;
1732dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		else if (t > hi)
1733dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			t = hi;
1734dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		if ((*funcp)(&t, offset, &mytm, sp) == NULL) {
1735dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			/*
1736dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			** Assume that t is too extreme to be represented in
1737dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			** a struct tm; arrange things so that it is less
1738dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			** extreme on the next pass.
1739dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			*/
1740dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			dir = (t > 0) ? 1 : -1;
1741dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		} else	dir = tmcomp(&mytm, &yourtm);
1742dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		if (dir != 0) {
1743dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			if (t == lo) {
1744dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project				++t;
1745dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project				if (t <= lo)
1746dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project					return WRONG;
1747dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project				++lo;
1748dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			} else if (t == hi) {
1749dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project				--t;
1750dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project				if (t >= hi)
1751dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project					return WRONG;
1752dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project				--hi;
1753dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			}
1754dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			if (lo > hi)
1755dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project				return WRONG;
1756dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			if (dir > 0)
1757dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project				hi = t;
1758dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			else	lo = t;
1759dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			continue;
1760dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		}
1761dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		if (yourtm.tm_isdst < 0 || mytm.tm_isdst == yourtm.tm_isdst)
1762dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			break;
1763dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		/*
1764dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		** Right time, wrong type.
1765dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		** Hunt for right time, right type.
1766dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		** It's okay to guess wrong since the guess
1767dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		** gets checked.
1768dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		*/
1769dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		/*
1770dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		** The (void *) casts are the benefit of SunOS 3.3 on Sun 2's.
1771dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		*/
1772dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#ifdef ALL_STATE
1773dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		if (sp == NULL)
1774dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			return WRONG;
1775dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#endif /* defined ALL_STATE */
1776dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		for (i = sp->typecnt - 1; i >= 0; --i) {
1777dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			if (sp->ttis[i].tt_isdst != yourtm.tm_isdst)
1778dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project				continue;
1779dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			for (j = sp->typecnt - 1; j >= 0; --j) {
1780dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project				if (sp->ttis[j].tt_isdst == yourtm.tm_isdst)
1781dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project					continue;
1782dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project				newt = t + sp->ttis[j].tt_gmtoff -
1783dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project					sp->ttis[i].tt_gmtoff;
1784dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project				if ((*funcp)(&newt, offset, &mytm, sp) == NULL)
1785dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project					continue;
1786dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project				if (tmcomp(&mytm, &yourtm) != 0)
1787dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project					continue;
1788dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project				if (mytm.tm_isdst != yourtm.tm_isdst)
1789dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project					continue;
1790dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project				/*
1791dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project				** We have a match.
1792dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project				*/
1793dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project				t = newt;
1794dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project				goto label;
1795dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			}
1796dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		}
1797dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		return WRONG;
1798dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	}
1799dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectlabel:
1800dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	newt = t + saved_seconds;
1801dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	if ((newt < t) != (saved_seconds < 0))
1802dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		return WRONG;
1803dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	t = newt;
1804dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	if ((*funcp)(&t, offset, tmp, sp))
1805dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		*okayp = TRUE;
1806dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	return t;
1807dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
1808dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
1809dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic time_t
1810dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projecttime2(tmp, funcp, offset, okayp, sp)
1811dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstruct tm * const	tmp;
1812dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstruct tm * (* const	funcp) P((const time_t*, long, struct tm*,
1813dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            const struct state* sp));
1814dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectconst long		offset;
1815dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectint * const		okayp;
1816dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectconst struct state *	sp;
1817dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
1818dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	time_t	t;
1819dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
1820dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	/*
1821dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	** First try without normalization of seconds
1822dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	** (in case tm_sec contains a value associated with a leap second).
1823dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	** If that fails, try with normalization of seconds.
1824dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	*/
1825dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	t = time2sub(tmp, funcp, offset, okayp, FALSE, sp);
1826dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	return *okayp ? t : time2sub(tmp, funcp, offset, okayp, TRUE, sp);
1827dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
1828dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
1829dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic time_t
1830dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projecttime1(tmp, funcp, offset, sp)
1831dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstruct tm * const	tmp;
1832dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstruct tm * (* const	funcp) P((const time_t *, long, struct tm *, const struct state* sp));
1833dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectconst long		offset;
1834dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectconst struct state *	sp;
1835dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
1836dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	register time_t			t;
1837dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	register int			samei, otheri;
1838dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	register int			sameind, otherind;
1839dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	register int			i;
1840dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	register int			nseen;
1841dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	int				seen[TZ_MAX_TYPES];
1842dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	int				types[TZ_MAX_TYPES];
1843dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	int				okay;
1844dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
1845dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	if (tmp->tm_isdst > 1)
1846dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		tmp->tm_isdst = 1;
1847dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	t = time2(tmp, funcp, offset, &okay, sp);
1848dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#define PCTS 1
1849dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#ifdef PCTS
1850dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	/*
1851dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	** PCTS code courtesy Grant Sullivan.
1852dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	*/
1853dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	if (okay)
1854dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		return t;
1855dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	if (tmp->tm_isdst < 0)
1856dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		tmp->tm_isdst = 0;	/* reset to std and try again */
1857dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#endif /* defined PCTS */
1858dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#ifndef PCTS
1859dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	if (okay || tmp->tm_isdst < 0)
1860dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		return t;
1861dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#endif /* !defined PCTS */
1862dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	/*
1863dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	** We're supposed to assume that somebody took a time of one type
1864dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	** and did some math on it that yielded a "struct tm" that's bad.
1865dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	** We try to divine the type they started from and adjust to the
1866dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	** type they need.
1867dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	*/
1868dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	/*
1869dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	** The (void *) casts are the benefit of SunOS 3.3 on Sun 2's.
1870dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	*/
1871dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#ifdef ALL_STATE
1872dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	if (sp == NULL)
1873dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		return WRONG;
1874dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#endif /* defined ALL_STATE */
1875dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	for (i = 0; i < sp->typecnt; ++i)
1876dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		seen[i] = FALSE;
1877dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	nseen = 0;
1878dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	for (i = sp->timecnt - 1; i >= 0; --i)
1879dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		if (!seen[sp->types[i]]) {
1880dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			seen[sp->types[i]] = TRUE;
1881dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			types[nseen++] = sp->types[i];
1882dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		}
1883dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	for (sameind = 0; sameind < nseen; ++sameind) {
1884dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		samei = types[sameind];
1885dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		if (sp->ttis[samei].tt_isdst != tmp->tm_isdst)
1886dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			continue;
1887dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		for (otherind = 0; otherind < nseen; ++otherind) {
1888dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			otheri = types[otherind];
1889dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			if (sp->ttis[otheri].tt_isdst == tmp->tm_isdst)
1890dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project				continue;
1891dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			tmp->tm_sec += sp->ttis[otheri].tt_gmtoff -
1892dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project					sp->ttis[samei].tt_gmtoff;
1893dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			tmp->tm_isdst = !tmp->tm_isdst;
1894dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			t = time2(tmp, funcp, offset, &okay, sp);
1895dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			if (okay)
1896dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project				return t;
1897dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			tmp->tm_sec -= sp->ttis[otheri].tt_gmtoff -
1898dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project					sp->ttis[samei].tt_gmtoff;
1899dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			tmp->tm_isdst = !tmp->tm_isdst;
1900dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		}
1901dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	}
1902dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	return WRONG;
1903dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
1904dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
1905dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project// ============================================================================
1906dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projecttime_t
1907dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectmktime_tz(struct tm * const	tmp, char const * tz)
1908dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
1909dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    struct state st;
1910dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if (tzload(tz, &st, TRUE) != 0) {
1911dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        // not sure what's best here, but for now, we fall back to gmt
1912dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        gmtload(&st);
1913dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
1914dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	return time1(tmp, localsub, 0L, &st);
1915dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
1916