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