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