da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/***********************************************************************
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* This software is part of the ast package *
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner* Copyright (c) 1985-2010 AT&T Intellectual Property *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* and is licensed under the *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* Common Public License, Version 1.0 *
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin* by AT&T Intellectual Property *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* A copy of the License is available at *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* http://www.opensource.org/licenses/cpl1.0.txt *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* (with md5 checksum 059e8cd6165cb4c31e351f2b69388fd9) *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* Information and Software Systems Research *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* AT&T Research *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* Florham Park NJ *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* Glenn Fowler <gsf@research.att.com> *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* David Korn <dgk@research.att.com> *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* Phong Vo <kpv@research.att.com> *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin***********************************************************************/
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#pragma prototyped
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * Glenn Fowler
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * AT&T Research
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * time conversion support
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#include <tm.h>
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#include <ctype.h>
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#include <namval.h>
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#include "FEATURE/tmlib"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#ifndef tzname
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin# if defined(__DYNAMIC__)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin# define tzname __DYNAMIC__(tzname)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin# else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin# if !_dat_tzname
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin# if _dat__tzname
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin# undef _dat_tzname
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin# define _dat_tzname 1
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin# define tzname _tzname
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin# endif
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin# endif
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin# endif
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin# if _dat_tzname
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin extern char* tzname[];
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin# endif
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define TM_type (-1)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstatic const Namval_t options[] =
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin "adjust", TM_ADJUST,
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin "format", TM_DEFAULT,
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin "leap", TM_LEAP,
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin "subsecond", TM_SUBSECOND,
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin "type", TM_type,
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin "utc", TM_UTC,
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin 0, 0
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin};
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * 2007-03-19 move tm_info from _tm_info_ to (*_tm_infop_)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * to allow future Tm_info_t growth
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * by 2009 _tm_info_ can be static
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#if _BLD_ast && defined(__EXPORT__)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define extern extern __EXPORT__
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinextern Tm_info_t _tm_info_;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#undef extern
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinTm_info_t _tm_info_ = { 0 };
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin__EXTERN__(Tm_info_t, _tm_info_);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin__EXTERN__(Tm_info_t*, _tm_infop_);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinTm_info_t* _tm_infop_ = &_tm_info_;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#if _tzset_environ
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstatic char TZ[256];
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstatic char* TE[2];
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstruct tm*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin_tm_localtime(const time_t* t)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin struct tm* r;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin char* e;
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner char** v = environ;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (TZ[0])
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (!environ || !*environ)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin environ = TE;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin e = environ[0];
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin environ[0] = TZ;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin r = localtime(t);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (TZ[0])
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner if (environ != v)
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner environ = v;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin environ[0] = e;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return r;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * return minutes west of GMT for local time clock
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * isdst will point to non-zero if DST is in effect
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * this routine also kicks in the local initialization
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstatic int
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chintzwest(time_t* clock, int* isdst)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register struct tm* tp;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register int n;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register int m;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin int h;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin time_t epoch;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * convert to GMT assuming local time
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (!(tp = gmtime(clock)))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * some systems return 0 for negative time_t
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin epoch = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin clock = &epoch;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin tp = gmtime(clock);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin n = tp->tm_yday;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin h = tp->tm_hour;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin m = tp->tm_min;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * tmlocaltime() handles DST and GMT offset
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin tp = tmlocaltime(clock);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (n = tp->tm_yday - n)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (n > 1)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin n = -1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if (n < -1)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin n = 1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *isdst = tp->tm_isdst;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return (h - tp->tm_hour - n * 24) * 60 + m - tp->tm_min;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * stropt() option handler
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstatic int
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chintmopt(void* a, const void* p, int n, const char* v)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin Tm_zone_t* zp;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin NoP(a);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (p)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin switch (((Namval_t*)p)->value)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case TM_DEFAULT:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin tm_info.deformat = (n && (n = strlen(v)) > 0 && (n < 2 || v[n-2] != '%' || v[n-1] != '?')) ? strdup(v) : tm_info.format[TM_DEFAULT];
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case TM_type:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin tm_info.local->type = (n && *v) ? ((zp = tmtype(v, NiL)) ? zp->type : strdup(v)) : 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin default:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (n)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin tm_info.flags |= ((Namval_t*)p)->value;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin tm_info.flags &= ~((Namval_t*)p)->value;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * initialize the local timezone
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstatic void
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chintmlocal(void)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register Tm_zone_t* zp;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register int n;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register char* s;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register char* e;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin int i;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin int m;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin int isdst;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin char* t;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin struct tm* tp;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin time_t now;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin char buf[16];
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin static Tm_zone_t local;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#if _tzset_environ
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner char** v = environ;
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner if (s = getenv("TZ"))
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner {
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner sfsprintf(TZ, sizeof(TZ), "TZ=%s", s);
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner if (!environ || !*environ)
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner environ = TE;
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner else
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner e = environ[0];
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner environ[0] = TZ;
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner {
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner TZ[0] = 0;
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner e = 0;
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner#if _lib_tzset
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner tzset();
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner#if _tzset_environ
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner if (environ != v)
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner environ = v;
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner else if (e)
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner environ[0] = e;
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#if _dat_tzname
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin local.standard = strdup(tzname[0]);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin local.daylight = strdup(tzname[1]);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin tmlocale();
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * tm_info.local
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin tm_info.zone = tm_info.local = &local;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin time(&now);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin n = tzwest(&now, &isdst);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * compute local DST offset by roaming
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * through the last 12 months until tzwest() changes
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin for (i = 0; i < 12; i++)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin now -= 31 * 24 * 60 * 60;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if ((m = tzwest(&now, &isdst)) != n)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (!isdst)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin isdst = n;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin n = m;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin m = isdst;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin m -= n;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin local.west = n;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin local.dst = m;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * now get the time zone names
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#if _dat_tzname
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (tzname[0])
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * POSIX
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (!local.standard)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin local.standard = strdup(tzname[0]);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (!local.daylight)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin local.daylight = strdup(tzname[1]);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if ((s = getenv("TZNAME")) && *s && (s = strdup(s)))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * BSD
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin local.standard = s;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (s = strchr(s, ','))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *s++ = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin s = "";
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin local.daylight = s;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if ((s = getenv("TZ")) && *s && *s != ':' && (s = strdup(s)))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * POSIX style but skipped by tmlocaltime()
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin local.standard = s;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (*++s && *++s && *++s)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *s++ = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin tmgoff(s, &t, 0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin for (s = t; isalpha(*t); t++);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *t = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin s = "";
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin local.daylight = s;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * tm_data.zone table lookup
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin t = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin for (zp = tm_data.zone; zp->standard; zp++)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (zp->type)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin t = zp->type;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (zp->west == n && zp->dst == m)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin local.type = t;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin local.standard = zp->standard;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (!(s = zp->daylight))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin e = (s = buf) + sizeof(buf);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin s = tmpoff(s, e - s, zp->standard, 0, 0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (s < e - 1)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *s++ = ' ';
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin tmpoff(s, e - s, tm_info.format[TM_DT], m, TM_DST);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin s = strdup(buf);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin local.daylight = s;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (!zp->standard)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * not in the table
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin e = (s = buf) + sizeof(buf);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin s = tmpoff(s, e - s, tm_info.format[TM_UT], n, 0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin local.standard = strdup(buf);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (s < e - 1)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *s++ = ' ';
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin tmpoff(s, e - s, tm_info.format[TM_UT], m, TM_DST);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin local.daylight = strdup(buf);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * set the options
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin stropt(getenv("TM_OPTIONS"), options, sizeof(*options), tmopt, NiL);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * the time zone type is probably related to the locale
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (!local.type)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin s = local.standard;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin t = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin for (zp = tm_data.zone; zp->standard; zp++)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (zp->type)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin t = zp->type;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (tmword(s, NiL, zp->standard, NiL, 0))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin local.type = t;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * tm_info.flags
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (!(tm_info.flags & TM_ADJUST))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin now = (time_t)78811200; /* Jun 30 1972 23:59:60 */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin tp = tmlocaltime(&now);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (tp->tm_sec != 60)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin tm_info.flags |= TM_ADJUST;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (!(tm_info.flags & TM_UTC))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin s = local.standard;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin zp = tm_data.zone;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (local.daylight)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin zp++;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin for (; !zp->type && zp->standard; zp++)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (tmword(s, NiL, zp->standard, NiL, 0))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin tm_info.flags |= TM_UTC;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * initialize tm data
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinvoid
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chintminit(register Tm_zone_t* zp)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin static uint32_t serial = ~(uint32_t)0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (serial != ast.env_serial)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin serial = ast.env_serial;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (tm_info.local)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin memset(tm_info.local, 0, sizeof(*tm_info.local));
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin tm_info.local = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (!tm_info.local)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin tmlocal();
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (!zp)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin zp = tm_info.local;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin tm_info.zone = zp;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}