1*b30d1939SAndy Fiddaman /***********************************************************************
2*b30d1939SAndy Fiddaman *                                                                      *
3*b30d1939SAndy Fiddaman *               This software is part of the ast package               *
4*b30d1939SAndy Fiddaman *          Copyright (c) 1985-2011 AT&T Intellectual Property          *
5*b30d1939SAndy Fiddaman *                      and is licensed under the                       *
6*b30d1939SAndy Fiddaman *                 Eclipse Public License, Version 1.0                  *
7*b30d1939SAndy Fiddaman *                    by AT&T Intellectual Property                     *
8*b30d1939SAndy Fiddaman *                                                                      *
9*b30d1939SAndy Fiddaman *                A copy of the License is available at                 *
10*b30d1939SAndy Fiddaman *          http://www.eclipse.org/org/documents/epl-v10.html           *
11*b30d1939SAndy Fiddaman *         (with md5 checksum b35adb5213ca9657e911e9befb180842)         *
12*b30d1939SAndy Fiddaman *                                                                      *
13*b30d1939SAndy Fiddaman *              Information and Software Systems Research               *
14*b30d1939SAndy Fiddaman *                            AT&T Research                             *
15*b30d1939SAndy Fiddaman *                           Florham Park NJ                            *
16*b30d1939SAndy Fiddaman *                                                                      *
17*b30d1939SAndy Fiddaman *                 Glenn Fowler <gsf@research.att.com>                  *
18*b30d1939SAndy Fiddaman *                  David Korn <dgk@research.att.com>                   *
19*b30d1939SAndy Fiddaman *                   Phong Vo <kpv@research.att.com>                    *
20*b30d1939SAndy Fiddaman *                                                                      *
21*b30d1939SAndy Fiddaman ***********************************************************************/
22*b30d1939SAndy Fiddaman #pragma prototyped
23*b30d1939SAndy Fiddaman /*
24*b30d1939SAndy Fiddaman  * Glenn Fowler
25*b30d1939SAndy Fiddaman  * AT&T Research
26*b30d1939SAndy Fiddaman  *
27*b30d1939SAndy Fiddaman  * time conversion support
28*b30d1939SAndy Fiddaman  */
29*b30d1939SAndy Fiddaman 
30*b30d1939SAndy Fiddaman #include <tm.h>
31*b30d1939SAndy Fiddaman #include <ctype.h>
32*b30d1939SAndy Fiddaman #include <namval.h>
33*b30d1939SAndy Fiddaman 
34*b30d1939SAndy Fiddaman #include "FEATURE/tmlib"
35*b30d1939SAndy Fiddaman 
36*b30d1939SAndy Fiddaman #ifndef tzname
37*b30d1939SAndy Fiddaman #	if defined(__DYNAMIC__)
38*b30d1939SAndy Fiddaman #		undef	_dat_tzname
39*b30d1939SAndy Fiddaman #		define	tzname		__DYNAMIC__(tzname)
40*b30d1939SAndy Fiddaman #	else
41*b30d1939SAndy Fiddaman #		if !_dat_tzname
42*b30d1939SAndy Fiddaman #			if _dat__tzname
43*b30d1939SAndy Fiddaman #				undef	_dat_tzname
44*b30d1939SAndy Fiddaman #				define _dat_tzname	1
45*b30d1939SAndy Fiddaman #				define tzname		_tzname
46*b30d1939SAndy Fiddaman #			endif
47*b30d1939SAndy Fiddaman #		endif
48*b30d1939SAndy Fiddaman #	endif
49*b30d1939SAndy Fiddaman #	if _dat_tzname && !defined(tzname)
50*b30d1939SAndy Fiddaman 		extern char*		tzname[];
51*b30d1939SAndy Fiddaman #	endif
52*b30d1939SAndy Fiddaman #endif
53*b30d1939SAndy Fiddaman 
54*b30d1939SAndy Fiddaman #define TM_type		(-1)
55*b30d1939SAndy Fiddaman 
56*b30d1939SAndy Fiddaman static const Namval_t		options[] =
57*b30d1939SAndy Fiddaman {
58*b30d1939SAndy Fiddaman 	"adjust",	TM_ADJUST,
59*b30d1939SAndy Fiddaman 	"format",	TM_DEFAULT,
60*b30d1939SAndy Fiddaman 	"leap",		TM_LEAP,
61*b30d1939SAndy Fiddaman 	"subsecond",	TM_SUBSECOND,
62*b30d1939SAndy Fiddaman 	"type",		TM_type,
63*b30d1939SAndy Fiddaman 	"utc",		TM_UTC,
64*b30d1939SAndy Fiddaman 	0,		0
65*b30d1939SAndy Fiddaman };
66*b30d1939SAndy Fiddaman 
67*b30d1939SAndy Fiddaman /*
68*b30d1939SAndy Fiddaman  * 2007-03-19 move tm_info from _tm_info_ to (*_tm_infop_)
69*b30d1939SAndy Fiddaman  *	      to allow future Tm_info_t growth
70*b30d1939SAndy Fiddaman  *            by 2009 _tm_info_ can be static
71*b30d1939SAndy Fiddaman  */
72*b30d1939SAndy Fiddaman 
73*b30d1939SAndy Fiddaman #if _BLD_ast && defined(__EXPORT__)
74*b30d1939SAndy Fiddaman #define extern		extern __EXPORT__
75*b30d1939SAndy Fiddaman #endif
76*b30d1939SAndy Fiddaman 
77*b30d1939SAndy Fiddaman extern Tm_info_t	_tm_info_;
78*b30d1939SAndy Fiddaman 
79*b30d1939SAndy Fiddaman #undef	extern
80*b30d1939SAndy Fiddaman 
81*b30d1939SAndy Fiddaman Tm_info_t		_tm_info_ = { 0 };
82*b30d1939SAndy Fiddaman 
83*b30d1939SAndy Fiddaman __EXTERN__(Tm_info_t, _tm_info_);
84*b30d1939SAndy Fiddaman 
85*b30d1939SAndy Fiddaman __EXTERN__(Tm_info_t*, _tm_infop_);
86*b30d1939SAndy Fiddaman 
87*b30d1939SAndy Fiddaman Tm_info_t*		_tm_infop_ = &_tm_info_;
88*b30d1939SAndy Fiddaman 
89*b30d1939SAndy Fiddaman #if _tzset_environ
90*b30d1939SAndy Fiddaman 
91*b30d1939SAndy Fiddaman static char	TZ[256];
92*b30d1939SAndy Fiddaman static char*	TE[2];
93*b30d1939SAndy Fiddaman 
94*b30d1939SAndy Fiddaman struct tm*
_tm_localtime(const time_t * t)95*b30d1939SAndy Fiddaman _tm_localtime(const time_t* t)
96*b30d1939SAndy Fiddaman {
97*b30d1939SAndy Fiddaman 	struct tm*	r;
98*b30d1939SAndy Fiddaman 	char*		e;
99*b30d1939SAndy Fiddaman 	char**		v = environ;
100*b30d1939SAndy Fiddaman 
101*b30d1939SAndy Fiddaman 	if (TZ[0])
102*b30d1939SAndy Fiddaman 	{
103*b30d1939SAndy Fiddaman 		if (!environ || !*environ)
104*b30d1939SAndy Fiddaman 			environ = TE;
105*b30d1939SAndy Fiddaman 		else
106*b30d1939SAndy Fiddaman 			e = environ[0];
107*b30d1939SAndy Fiddaman 		environ[0] = TZ;
108*b30d1939SAndy Fiddaman 	}
109*b30d1939SAndy Fiddaman 	r = localtime(t);
110*b30d1939SAndy Fiddaman 	if (TZ[0])
111*b30d1939SAndy Fiddaman 	{
112*b30d1939SAndy Fiddaman 		if (environ != v)
113*b30d1939SAndy Fiddaman 			environ = v;
114*b30d1939SAndy Fiddaman 		else
115*b30d1939SAndy Fiddaman 			environ[0] = e;
116*b30d1939SAndy Fiddaman 	}
117*b30d1939SAndy Fiddaman 	return r;
118*b30d1939SAndy Fiddaman }
119*b30d1939SAndy Fiddaman 
120*b30d1939SAndy Fiddaman #endif
121*b30d1939SAndy Fiddaman 
122*b30d1939SAndy Fiddaman /*
123*b30d1939SAndy Fiddaman  * return minutes west of GMT for local time clock
124*b30d1939SAndy Fiddaman  *
125*b30d1939SAndy Fiddaman  * isdst will point to non-zero if DST is in effect
126*b30d1939SAndy Fiddaman  * this routine also kicks in the local initialization
127*b30d1939SAndy Fiddaman  */
128*b30d1939SAndy Fiddaman 
129*b30d1939SAndy Fiddaman static int
tzwest(time_t * clock,int * isdst)130*b30d1939SAndy Fiddaman tzwest(time_t* clock, int* isdst)
131*b30d1939SAndy Fiddaman {
132*b30d1939SAndy Fiddaman 	register struct tm*	tp;
133*b30d1939SAndy Fiddaman 	register int		n;
134*b30d1939SAndy Fiddaman 	register int		m;
135*b30d1939SAndy Fiddaman 	int			h;
136*b30d1939SAndy Fiddaman 	time_t			epoch;
137*b30d1939SAndy Fiddaman 
138*b30d1939SAndy Fiddaman 	/*
139*b30d1939SAndy Fiddaman 	 * convert to GMT assuming local time
140*b30d1939SAndy Fiddaman 	 */
141*b30d1939SAndy Fiddaman 
142*b30d1939SAndy Fiddaman 	if (!(tp = gmtime(clock)))
143*b30d1939SAndy Fiddaman 	{
144*b30d1939SAndy Fiddaman 		/*
145*b30d1939SAndy Fiddaman 		 * some systems return 0 for negative time_t
146*b30d1939SAndy Fiddaman 		 */
147*b30d1939SAndy Fiddaman 
148*b30d1939SAndy Fiddaman 		epoch = 0;
149*b30d1939SAndy Fiddaman 		clock = &epoch;
150*b30d1939SAndy Fiddaman 		tp = gmtime(clock);
151*b30d1939SAndy Fiddaman 	}
152*b30d1939SAndy Fiddaman 	n = tp->tm_yday;
153*b30d1939SAndy Fiddaman 	h = tp->tm_hour;
154*b30d1939SAndy Fiddaman 	m = tp->tm_min;
155*b30d1939SAndy Fiddaman 
156*b30d1939SAndy Fiddaman 	/*
157*b30d1939SAndy Fiddaman 	 * tmlocaltime() handles DST and GMT offset
158*b30d1939SAndy Fiddaman 	 */
159*b30d1939SAndy Fiddaman 
160*b30d1939SAndy Fiddaman 	tp = tmlocaltime(clock);
161*b30d1939SAndy Fiddaman 	if (n = tp->tm_yday - n)
162*b30d1939SAndy Fiddaman 	{
163*b30d1939SAndy Fiddaman 		if (n > 1)
164*b30d1939SAndy Fiddaman 			n = -1;
165*b30d1939SAndy Fiddaman 		else if (n < -1)
166*b30d1939SAndy Fiddaman 			n = 1;
167*b30d1939SAndy Fiddaman 	}
168*b30d1939SAndy Fiddaman 	*isdst = tp->tm_isdst;
169*b30d1939SAndy Fiddaman 	return (h - tp->tm_hour - n * 24) * 60 + m - tp->tm_min;
170*b30d1939SAndy Fiddaman }
171*b30d1939SAndy Fiddaman 
172*b30d1939SAndy Fiddaman /*
173*b30d1939SAndy Fiddaman  * stropt() option handler
174*b30d1939SAndy Fiddaman  */
175*b30d1939SAndy Fiddaman 
176*b30d1939SAndy Fiddaman static int
tmopt(void * a,const void * p,int n,const char * v)177*b30d1939SAndy Fiddaman tmopt(void* a, const void* p, int n, const char* v)
178*b30d1939SAndy Fiddaman {
179*b30d1939SAndy Fiddaman 	Tm_zone_t*	zp;
180*b30d1939SAndy Fiddaman 
181*b30d1939SAndy Fiddaman 	NoP(a);
182*b30d1939SAndy Fiddaman 	if (p)
183*b30d1939SAndy Fiddaman 		switch (((Namval_t*)p)->value)
184*b30d1939SAndy Fiddaman 		{
185*b30d1939SAndy Fiddaman 		case TM_DEFAULT:
186*b30d1939SAndy Fiddaman 			tm_info.deformat = (n && (n = strlen(v)) > 0 && (n < 2 || v[n-2] != '%' || v[n-1] != '?')) ? strdup(v) : tm_info.format[TM_DEFAULT];
187*b30d1939SAndy Fiddaman 			break;
188*b30d1939SAndy Fiddaman 		case TM_type:
189*b30d1939SAndy Fiddaman 			tm_info.local->type = (n && *v) ? ((zp = tmtype(v, NiL)) ? zp->type : strdup(v)) : 0;
190*b30d1939SAndy Fiddaman 			break;
191*b30d1939SAndy Fiddaman 		default:
192*b30d1939SAndy Fiddaman 			if (n)
193*b30d1939SAndy Fiddaman 				tm_info.flags |= ((Namval_t*)p)->value;
194*b30d1939SAndy Fiddaman 			else
195*b30d1939SAndy Fiddaman 				tm_info.flags &= ~((Namval_t*)p)->value;
196*b30d1939SAndy Fiddaman 			break;
197*b30d1939SAndy Fiddaman 		}
198*b30d1939SAndy Fiddaman 	return 0;
199*b30d1939SAndy Fiddaman }
200*b30d1939SAndy Fiddaman 
201*b30d1939SAndy Fiddaman /*
202*b30d1939SAndy Fiddaman  * initialize the local timezone
203*b30d1939SAndy Fiddaman  */
204*b30d1939SAndy Fiddaman 
205*b30d1939SAndy Fiddaman static void
tmlocal(void)206*b30d1939SAndy Fiddaman tmlocal(void)
207*b30d1939SAndy Fiddaman {
208*b30d1939SAndy Fiddaman 	register Tm_zone_t*	zp;
209*b30d1939SAndy Fiddaman 	register int		n;
210*b30d1939SAndy Fiddaman 	register char*		s;
211*b30d1939SAndy Fiddaman 	register char*		e;
212*b30d1939SAndy Fiddaman 	int			i;
213*b30d1939SAndy Fiddaman 	int			m;
214*b30d1939SAndy Fiddaman 	int			isdst;
215*b30d1939SAndy Fiddaman 	char*			t;
216*b30d1939SAndy Fiddaman 	struct tm*		tp;
217*b30d1939SAndy Fiddaman 	time_t			now;
218*b30d1939SAndy Fiddaman 	char			buf[16];
219*b30d1939SAndy Fiddaman 
220*b30d1939SAndy Fiddaman 	static Tm_zone_t	local;
221*b30d1939SAndy Fiddaman 
222*b30d1939SAndy Fiddaman #if _tzset_environ
223*b30d1939SAndy Fiddaman 	{
224*b30d1939SAndy Fiddaman 		char**	v = environ;
225*b30d1939SAndy Fiddaman 
226*b30d1939SAndy Fiddaman 		if (s = getenv("TZ"))
227*b30d1939SAndy Fiddaman 		{
228*b30d1939SAndy Fiddaman 			sfsprintf(TZ, sizeof(TZ), "TZ=%s", s);
229*b30d1939SAndy Fiddaman 			if (!environ || !*environ)
230*b30d1939SAndy Fiddaman 				environ = TE;
231*b30d1939SAndy Fiddaman 			else
232*b30d1939SAndy Fiddaman 				e = environ[0];
233*b30d1939SAndy Fiddaman 			environ[0] = TZ;
234*b30d1939SAndy Fiddaman 		}
235*b30d1939SAndy Fiddaman 		else
236*b30d1939SAndy Fiddaman 		{
237*b30d1939SAndy Fiddaman 			TZ[0] = 0;
238*b30d1939SAndy Fiddaman 			e = 0;
239*b30d1939SAndy Fiddaman 		}
240*b30d1939SAndy Fiddaman #endif
241*b30d1939SAndy Fiddaman #if _lib_tzset
242*b30d1939SAndy Fiddaman 		tzset();
243*b30d1939SAndy Fiddaman #endif
244*b30d1939SAndy Fiddaman #if _tzset_environ
245*b30d1939SAndy Fiddaman 		if (environ != v)
246*b30d1939SAndy Fiddaman 			environ = v;
247*b30d1939SAndy Fiddaman 		else if (e)
248*b30d1939SAndy Fiddaman 			environ[0] = e;
249*b30d1939SAndy Fiddaman 	}
250*b30d1939SAndy Fiddaman #endif
251*b30d1939SAndy Fiddaman #if _dat_tzname
252*b30d1939SAndy Fiddaman 	local.standard = strdup(tzname[0]);
253*b30d1939SAndy Fiddaman 	local.daylight = strdup(tzname[1]);
254*b30d1939SAndy Fiddaman #endif
255*b30d1939SAndy Fiddaman 	tmlocale();
256*b30d1939SAndy Fiddaman 
257*b30d1939SAndy Fiddaman 	/*
258*b30d1939SAndy Fiddaman 	 * tm_info.local
259*b30d1939SAndy Fiddaman 	 */
260*b30d1939SAndy Fiddaman 
261*b30d1939SAndy Fiddaman 	tm_info.zone = tm_info.local = &local;
262*b30d1939SAndy Fiddaman 	time(&now);
263*b30d1939SAndy Fiddaman 	n = tzwest(&now, &isdst);
264*b30d1939SAndy Fiddaman 
265*b30d1939SAndy Fiddaman 	/*
266*b30d1939SAndy Fiddaman 	 * compute local DST offset by roaming
267*b30d1939SAndy Fiddaman 	 * through the last 12 months until tzwest() changes
268*b30d1939SAndy Fiddaman 	 */
269*b30d1939SAndy Fiddaman 
270*b30d1939SAndy Fiddaman 	for (i = 0; i < 12; i++)
271*b30d1939SAndy Fiddaman 	{
272*b30d1939SAndy Fiddaman 		now -= 31 * 24 * 60 * 60;
273*b30d1939SAndy Fiddaman 		if ((m = tzwest(&now, &isdst)) != n)
274*b30d1939SAndy Fiddaman 		{
275*b30d1939SAndy Fiddaman 			if (!isdst)
276*b30d1939SAndy Fiddaman 			{
277*b30d1939SAndy Fiddaman 				isdst = n;
278*b30d1939SAndy Fiddaman 				n = m;
279*b30d1939SAndy Fiddaman 				m = isdst;
280*b30d1939SAndy Fiddaman 			}
281*b30d1939SAndy Fiddaman 			m -= n;
282*b30d1939SAndy Fiddaman 			break;
283*b30d1939SAndy Fiddaman 		}
284*b30d1939SAndy Fiddaman 	}
285*b30d1939SAndy Fiddaman 	local.west = n;
286*b30d1939SAndy Fiddaman 	local.dst = m;
287*b30d1939SAndy Fiddaman 
288*b30d1939SAndy Fiddaman 	/*
289*b30d1939SAndy Fiddaman 	 * now get the time zone names
290*b30d1939SAndy Fiddaman 	 */
291*b30d1939SAndy Fiddaman 
292*b30d1939SAndy Fiddaman #if _dat_tzname
293*b30d1939SAndy Fiddaman 	if (tzname[0])
294*b30d1939SAndy Fiddaman 	{
295*b30d1939SAndy Fiddaman 		/*
296*b30d1939SAndy Fiddaman 		 * POSIX
297*b30d1939SAndy Fiddaman 		 */
298*b30d1939SAndy Fiddaman 
299*b30d1939SAndy Fiddaman 		if (!local.standard)
300*b30d1939SAndy Fiddaman 			local.standard = strdup(tzname[0]);
301*b30d1939SAndy Fiddaman 		if (!local.daylight)
302*b30d1939SAndy Fiddaman 			local.daylight = strdup(tzname[1]);
303*b30d1939SAndy Fiddaman 	}
304*b30d1939SAndy Fiddaman 	else
305*b30d1939SAndy Fiddaman #endif
306*b30d1939SAndy Fiddaman 	if ((s = getenv("TZNAME")) && *s && (s = strdup(s)))
307*b30d1939SAndy Fiddaman 	{
308*b30d1939SAndy Fiddaman 		/*
309*b30d1939SAndy Fiddaman 		 * BSD
310*b30d1939SAndy Fiddaman 		 */
311*b30d1939SAndy Fiddaman 
312*b30d1939SAndy Fiddaman 		local.standard = s;
313*b30d1939SAndy Fiddaman 		if (s = strchr(s, ','))
314*b30d1939SAndy Fiddaman 			*s++ = 0;
315*b30d1939SAndy Fiddaman 		else
316*b30d1939SAndy Fiddaman 			s = "";
317*b30d1939SAndy Fiddaman 		local.daylight = s;
318*b30d1939SAndy Fiddaman 	}
319*b30d1939SAndy Fiddaman 	else if ((s = getenv("TZ")) && *s && *s != ':' && (s = strdup(s)))
320*b30d1939SAndy Fiddaman 	{
321*b30d1939SAndy Fiddaman 		/*
322*b30d1939SAndy Fiddaman 		 * POSIX style but skipped by tmlocaltime()
323*b30d1939SAndy Fiddaman 		 */
324*b30d1939SAndy Fiddaman 
325*b30d1939SAndy Fiddaman 		local.standard = s;
326*b30d1939SAndy Fiddaman 		if (*++s && *++s && *++s)
327*b30d1939SAndy Fiddaman 		{
328*b30d1939SAndy Fiddaman 			*s++ = 0;
329*b30d1939SAndy Fiddaman 			tmgoff(s, &t, 0);
330*b30d1939SAndy Fiddaman 			for (s = t; isalpha(*t); t++);
331*b30d1939SAndy Fiddaman 			*t = 0;
332*b30d1939SAndy Fiddaman 		}
333*b30d1939SAndy Fiddaman 		else
334*b30d1939SAndy Fiddaman 			s = "";
335*b30d1939SAndy Fiddaman 		local.daylight = s;
336*b30d1939SAndy Fiddaman 	}
337*b30d1939SAndy Fiddaman 	else
338*b30d1939SAndy Fiddaman 	{
339*b30d1939SAndy Fiddaman 		/*
340*b30d1939SAndy Fiddaman 		 * tm_data.zone table lookup
341*b30d1939SAndy Fiddaman 		 */
342*b30d1939SAndy Fiddaman 
343*b30d1939SAndy Fiddaman 		t = 0;
344*b30d1939SAndy Fiddaman 		for (zp = tm_data.zone; zp->standard; zp++)
345*b30d1939SAndy Fiddaman 		{
346*b30d1939SAndy Fiddaman 			if (zp->type)
347*b30d1939SAndy Fiddaman 				t = zp->type;
348*b30d1939SAndy Fiddaman 			if (zp->west == n && zp->dst == m)
349*b30d1939SAndy Fiddaman 			{
350*b30d1939SAndy Fiddaman 				local.type = t;
351*b30d1939SAndy Fiddaman 				local.standard = zp->standard;
352*b30d1939SAndy Fiddaman 				if (!(s = zp->daylight))
353*b30d1939SAndy Fiddaman 				{
354*b30d1939SAndy Fiddaman 					e = (s = buf) + sizeof(buf);
355*b30d1939SAndy Fiddaman 					s = tmpoff(s, e - s, zp->standard, 0, 0);
356*b30d1939SAndy Fiddaman 					if (s < e - 1)
357*b30d1939SAndy Fiddaman 					{
358*b30d1939SAndy Fiddaman 						*s++ = ' ';
359*b30d1939SAndy Fiddaman 						tmpoff(s, e - s, tm_info.format[TM_DT], m, TM_DST);
360*b30d1939SAndy Fiddaman 					}
361*b30d1939SAndy Fiddaman 					s = strdup(buf);
362*b30d1939SAndy Fiddaman 				}
363*b30d1939SAndy Fiddaman 				local.daylight = s;
364*b30d1939SAndy Fiddaman 				break;
365*b30d1939SAndy Fiddaman 			}
366*b30d1939SAndy Fiddaman 		}
367*b30d1939SAndy Fiddaman 		if (!zp->standard)
368*b30d1939SAndy Fiddaman 		{
369*b30d1939SAndy Fiddaman 			/*
370*b30d1939SAndy Fiddaman 			 * not in the table
371*b30d1939SAndy Fiddaman 			 */
372*b30d1939SAndy Fiddaman 
373*b30d1939SAndy Fiddaman 			e = (s = buf) + sizeof(buf);
374*b30d1939SAndy Fiddaman 			s = tmpoff(s, e - s, tm_info.format[TM_UT], n, 0);
375*b30d1939SAndy Fiddaman 			local.standard = strdup(buf);
376*b30d1939SAndy Fiddaman 			if (s < e - 1)
377*b30d1939SAndy Fiddaman 			{
378*b30d1939SAndy Fiddaman 				*s++ = ' ';
379*b30d1939SAndy Fiddaman 				tmpoff(s, e - s, tm_info.format[TM_UT], m, TM_DST);
380*b30d1939SAndy Fiddaman 				local.daylight = strdup(buf);
381*b30d1939SAndy Fiddaman 			}
382*b30d1939SAndy Fiddaman 		}
383*b30d1939SAndy Fiddaman 	}
384*b30d1939SAndy Fiddaman 
385*b30d1939SAndy Fiddaman 	/*
386*b30d1939SAndy Fiddaman 	 * set the options
387*b30d1939SAndy Fiddaman 	 */
388*b30d1939SAndy Fiddaman 
389*b30d1939SAndy Fiddaman 	stropt(getenv("TM_OPTIONS"), options, sizeof(*options), tmopt, NiL);
390*b30d1939SAndy Fiddaman 
391*b30d1939SAndy Fiddaman 	/*
392*b30d1939SAndy Fiddaman 	 * the time zone type is probably related to the locale
393*b30d1939SAndy Fiddaman 	 */
394*b30d1939SAndy Fiddaman 
395*b30d1939SAndy Fiddaman 	if (!local.type)
396*b30d1939SAndy Fiddaman 	{
397*b30d1939SAndy Fiddaman 		s = local.standard;
398*b30d1939SAndy Fiddaman 		t = 0;
399*b30d1939SAndy Fiddaman 		for (zp = tm_data.zone; zp->standard; zp++)
400*b30d1939SAndy Fiddaman 		{
401*b30d1939SAndy Fiddaman 			if (zp->type)
402*b30d1939SAndy Fiddaman 				t = zp->type;
403*b30d1939SAndy Fiddaman 			if (tmword(s, NiL, zp->standard, NiL, 0))
404*b30d1939SAndy Fiddaman 			{
405*b30d1939SAndy Fiddaman 				local.type = t;
406*b30d1939SAndy Fiddaman 				break;
407*b30d1939SAndy Fiddaman 			}
408*b30d1939SAndy Fiddaman 		}
409*b30d1939SAndy Fiddaman 	}
410*b30d1939SAndy Fiddaman 
411*b30d1939SAndy Fiddaman 	/*
412*b30d1939SAndy Fiddaman 	 * tm_info.flags
413*b30d1939SAndy Fiddaman 	 */
414*b30d1939SAndy Fiddaman 
415*b30d1939SAndy Fiddaman 	if (!(tm_info.flags & TM_ADJUST))
416*b30d1939SAndy Fiddaman 	{
417*b30d1939SAndy Fiddaman 		now = (time_t)78811200;		/* Jun 30 1972 23:59:60 */
418*b30d1939SAndy Fiddaman 		tp = tmlocaltime(&now);
419*b30d1939SAndy Fiddaman 		if (tp->tm_sec != 60)
420*b30d1939SAndy Fiddaman 			tm_info.flags |= TM_ADJUST;
421*b30d1939SAndy Fiddaman 	}
422*b30d1939SAndy Fiddaman 	if (!(tm_info.flags & TM_UTC))
423*b30d1939SAndy Fiddaman 	{
424*b30d1939SAndy Fiddaman 		s = local.standard;
425*b30d1939SAndy Fiddaman 		zp = tm_data.zone;
426*b30d1939SAndy Fiddaman 		if (local.daylight)
427*b30d1939SAndy Fiddaman 			zp++;
428*b30d1939SAndy Fiddaman 		for (; !zp->type && zp->standard; zp++)
429*b30d1939SAndy Fiddaman 			if (tmword(s, NiL, zp->standard, NiL, 0))
430*b30d1939SAndy Fiddaman 			{
431*b30d1939SAndy Fiddaman 				tm_info.flags |= TM_UTC;
432*b30d1939SAndy Fiddaman 				break;
433*b30d1939SAndy Fiddaman 			}
434*b30d1939SAndy Fiddaman 	}
435*b30d1939SAndy Fiddaman }
436*b30d1939SAndy Fiddaman 
437*b30d1939SAndy Fiddaman /*
438*b30d1939SAndy Fiddaman  * initialize tm data
439*b30d1939SAndy Fiddaman  */
440*b30d1939SAndy Fiddaman 
441*b30d1939SAndy Fiddaman void
tminit(register Tm_zone_t * zp)442*b30d1939SAndy Fiddaman tminit(register Tm_zone_t* zp)
443*b30d1939SAndy Fiddaman {
444*b30d1939SAndy Fiddaman 	static uint32_t		serial = ~(uint32_t)0;
445*b30d1939SAndy Fiddaman 
446*b30d1939SAndy Fiddaman 	if (serial != ast.env_serial)
447*b30d1939SAndy Fiddaman 	{
448*b30d1939SAndy Fiddaman 		serial = ast.env_serial;
449*b30d1939SAndy Fiddaman 		if (tm_info.local)
450*b30d1939SAndy Fiddaman 		{
451*b30d1939SAndy Fiddaman 			memset(tm_info.local, 0, sizeof(*tm_info.local));
452*b30d1939SAndy Fiddaman 			tm_info.local = 0;
453*b30d1939SAndy Fiddaman 		}
454*b30d1939SAndy Fiddaman 	}
455*b30d1939SAndy Fiddaman 	if (!tm_info.local)
456*b30d1939SAndy Fiddaman 		tmlocal();
457*b30d1939SAndy Fiddaman 	if (!zp)
458*b30d1939SAndy Fiddaman 		zp = tm_info.local;
459*b30d1939SAndy Fiddaman 	tm_info.zone = zp;
460*b30d1939SAndy Fiddaman }
461