1 1.147 christos /* $NetBSD: localtime.c,v 1.147 2025/01/31 22:08:18 christos Exp $ */ 2 1.113 christos 3 1.113 christos /* Convert timestamp from time_t to struct tm. */ 4 1.7 jtc 5 1.7 jtc /* 6 1.7 jtc ** This file is in the public domain, so clarified as of 7 1.45 mlelstv ** 1996-06-05 by Arthur David Olson. 8 1.7 jtc */ 9 1.2 jtc 10 1.11 christos #include <sys/cdefs.h> 11 1.24 msaitoh #if defined(LIBC_SCCS) && !defined(lint) 12 1.11 christos #if 0 13 1.58 christos static char elsieid[] = "@(#)localtime.c 8.17"; 14 1.11 christos #else 15 1.147 christos __RCSID("$NetBSD: localtime.c,v 1.147 2025/01/31 22:08:18 christos Exp $"); 16 1.11 christos #endif 17 1.24 msaitoh #endif /* LIBC_SCCS and not lint */ 18 1.1 jtc 19 1.1 jtc /* 20 1.45 mlelstv ** Leap second handling from Bradley White. 21 1.141 christos ** POSIX.1-1988 style TZ environment variable handling from Guy Harris. 22 1.1 jtc */ 23 1.1 jtc 24 1.1 jtc /*LINTLIBRARY*/ 25 1.1 jtc 26 1.12 jtc #include "namespace.h" 27 1.78 christos #include <assert.h> 28 1.87 christos #define LOCALTIME_IMPLEMENTATION 29 1.1 jtc #include "private.h" 30 1.87 christos 31 1.1 jtc #include "tzfile.h" 32 1.106 christos #include <fcntl.h> 33 1.12 jtc 34 1.42 christos #if defined(__weak_alias) 35 1.25 kleink __weak_alias(daylight,_daylight) 36 1.23 mycroft __weak_alias(tzname,_tzname) 37 1.12 jtc #endif 38 1.1 jtc 39 1.145 christos #if HAVE_SYS_STAT_H 40 1.145 christos # include <sys/stat.h> 41 1.145 christos #endif 42 1.145 christos #if !defined S_ISREG && defined S_IFREG 43 1.145 christos /* Ancient UNIX or recent MS-Windows. */ 44 1.145 christos # define S_ISREG(mode) (((mode) & S_IFMT) == S_IFREG) 45 1.145 christos #endif 46 1.145 christos 47 1.145 christos #ifdef __NetBSD__ 48 1.145 christos #define lock() (rwlock_wrlock(&__lcl_lock), 0) 49 1.145 christos #define unlock() rwlock_unlock(&__lcl_lock) 50 1.145 christos #else 51 1.145 christos #if defined THREAD_SAFE && THREAD_SAFE 52 1.145 christos # include <pthread.h> 53 1.145 christos static pthread_mutex_t locallock = PTHREAD_MUTEX_INITIALIZER; 54 1.145 christos static int lock(void) { return pthread_mutex_lock(&locallock); } 55 1.145 christos static void unlock(void) { pthread_mutex_unlock(&locallock); } 56 1.145 christos #else 57 1.145 christos static int lock(void) { return 0; } 58 1.145 christos static void unlock(void) { } 59 1.145 christos #endif 60 1.145 christos #endif 61 1.145 christos 62 1.145 christos /* Unless intptr_t is missing, pacify gcc -Wcast-qual on char const * exprs. 63 1.145 christos Use this carefully, as the casts disable type checking. 64 1.145 christos This is a macro so that it can be used in static initializers. */ 65 1.145 christos #ifdef INTPTR_MAX 66 1.145 christos # define UNCONST(a) ((char *) (intptr_t) (a)) 67 1.145 christos #else 68 1.145 christos # define UNCONST(a) ((char *) (a)) 69 1.145 christos #endif 70 1.145 christos 71 1.145 christos /* A signed type wider than int, so that we can add 1900 + tm_mon/12 to tm_year 72 1.145 christos without overflow. The static_assert checks that it is indeed wider 73 1.145 christos than int; if this fails on your platform please let us know. */ 74 1.145 christos #if INT_MAX < LONG_MAX 75 1.145 christos typedef long iinntt; 76 1.145 christos # define IINNTT_MIN LONG_MIN 77 1.145 christos # define IINNTT_MAX LONG_MAX 78 1.145 christos #elif INT_MAX < LLONG_MAX 79 1.145 christos typedef long long iinntt; 80 1.145 christos # define IINNTT_MIN LLONG_MIN 81 1.145 christos # define IINNTT_MAX LLONG_MAX 82 1.145 christos #else 83 1.145 christos typedef intmax_t iinntt; 84 1.145 christos # define IINNTT_MIN INTMAX_MIN 85 1.145 christos # define IINNTT_MAX INTMAX_MAX 86 1.145 christos #endif 87 1.145 christos /*CONSTCOND*/ 88 1.145 christos static_assert(IINNTT_MIN < INT_MIN && INT_MAX < IINNTT_MAX); 89 1.145 christos 90 1.145 christos /* On platforms where offtime or mktime might overflow, 91 1.145 christos strftime.c defines USE_TIMEX_T to be true and includes us. 92 1.145 christos This tells us to #define time_t to an internal type timex_t that is 93 1.145 christos wide enough so that strftime %s never suffers from integer overflow, 94 1.145 christos and to #define offtime (if TM_GMTOFF is defined) or mktime (otherwise) 95 1.145 christos to a static function that returns the redefined time_t. 96 1.145 christos It also tells us to define only data and code needed 97 1.145 christos to support the offtime or mktime variant. */ 98 1.145 christos #ifndef USE_TIMEX_T 99 1.145 christos # define USE_TIMEX_T false 100 1.145 christos #endif 101 1.145 christos #if USE_TIMEX_T 102 1.145 christos # undef TIME_T_MIN 103 1.145 christos # undef TIME_T_MAX 104 1.145 christos # undef time_t 105 1.145 christos # define time_t timex_t 106 1.145 christos # if MKTIME_FITS_IN(LONG_MIN, LONG_MAX) 107 1.145 christos typedef long timex_t; 108 1.145 christos # define TIME_T_MIN LONG_MIN 109 1.145 christos # define TIME_T_MAX LONG_MAX 110 1.145 christos # elif MKTIME_FITS_IN(LLONG_MIN, LLONG_MAX) 111 1.145 christos typedef long long timex_t; 112 1.145 christos # define TIME_T_MIN LLONG_MIN 113 1.145 christos # define TIME_T_MAX LLONG_MAX 114 1.145 christos # else 115 1.145 christos typedef intmax_t timex_t; 116 1.145 christos # define TIME_T_MIN INTMAX_MIN 117 1.145 christos # define TIME_T_MAX INTMAX_MAX 118 1.145 christos # endif 119 1.145 christos 120 1.145 christos # ifdef TM_GMTOFF 121 1.145 christos # undef timeoff 122 1.145 christos # define timeoff timex_timeoff 123 1.145 christos # undef EXTERN_TIMEOFF 124 1.145 christos # else 125 1.145 christos # undef mktime 126 1.145 christos # define mktime timex_mktime 127 1.145 christos # endif 128 1.145 christos #endif 129 1.145 christos 130 1.45 mlelstv #ifndef TZ_ABBR_CHAR_SET 131 1.134 christos # define TZ_ABBR_CHAR_SET \ 132 1.45 mlelstv "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789 :+-._" 133 1.45 mlelstv #endif /* !defined TZ_ABBR_CHAR_SET */ 134 1.45 mlelstv 135 1.45 mlelstv #ifndef TZ_ABBR_ERR_CHAR 136 1.134 christos # define TZ_ABBR_ERR_CHAR '_' 137 1.45 mlelstv #endif /* !defined TZ_ABBR_ERR_CHAR */ 138 1.45 mlelstv 139 1.145 christos /* Port to platforms that lack some O_* flags. Unless otherwise 140 1.145 christos specified, the flags are standardized by POSIX. */ 141 1.1 jtc 142 1.1 jtc #ifndef O_BINARY 143 1.145 christos # define O_BINARY 0 /* MS-Windows */ 144 1.145 christos #endif 145 1.145 christos #ifndef O_CLOEXEC 146 1.145 christos # define O_CLOEXEC 0 147 1.145 christos #endif 148 1.145 christos #ifndef O_CLOFORK 149 1.145 christos # define O_CLOFORK 0 150 1.145 christos #endif 151 1.145 christos #ifndef O_IGNORE_CTTY 152 1.145 christos # define O_IGNORE_CTTY 0 /* GNU/Hurd */ 153 1.145 christos #endif 154 1.145 christos #ifndef O_NOCTTY 155 1.145 christos # define O_NOCTTY 0 156 1.134 christos #endif 157 1.1 jtc 158 1.1 jtc #ifndef WILDABBR 159 1.1 jtc /* 160 1.1 jtc ** Someone might make incorrect use of a time zone abbreviation: 161 1.1 jtc ** 1. They might reference tzname[0] before calling tzset (explicitly 162 1.1 jtc ** or implicitly). 163 1.1 jtc ** 2. They might reference tzname[1] before calling tzset (explicitly 164 1.1 jtc ** or implicitly). 165 1.1 jtc ** 3. They might reference tzname[1] after setting to a time zone 166 1.1 jtc ** in which Daylight Saving Time is never observed. 167 1.1 jtc ** 4. They might reference tzname[0] after setting to a time zone 168 1.1 jtc ** in which Standard Time is never observed. 169 1.1 jtc ** 5. They might reference tm.TM_ZONE after calling offtime. 170 1.1 jtc ** What's best to do in the above cases is open to debate; 171 1.1 jtc ** for now, we just set things up so that in any of the five cases 172 1.45 mlelstv ** WILDABBR is used. Another possibility: initialize tzname[0] to the 173 1.1 jtc ** string "tzname[0] used before set", and similarly for the other cases. 174 1.45 mlelstv ** And another: initialize tzname[0] to "ERA", with an explanation in the 175 1.1 jtc ** manual page of what this "time zone abbreviation" means (doing this so 176 1.1 jtc ** that tzname[0] has the "normal" length of three characters). 177 1.1 jtc */ 178 1.134 christos # define WILDABBR " " 179 1.1 jtc #endif /* !defined WILDABBR */ 180 1.1 jtc 181 1.45 mlelstv static const char wildabbr[] = WILDABBR; 182 1.1 jtc 183 1.134 christos static char const etc_utc[] = "Etc/UTC"; 184 1.145 christos 185 1.145 christos #if !USE_TIMEX_T || defined TM_ZONE || !defined TM_GMTOFF 186 1.134 christos static char const *utc = etc_utc + sizeof "Etc/" - 1; 187 1.145 christos #endif 188 1.1 jtc 189 1.22 kleink /* 190 1.22 kleink ** The DST rules to use if TZ has no rules and we can't load TZDEFRULES. 191 1.109 christos ** Default to US rules as of 2017-05-07. 192 1.112 christos ** POSIX does not specify the default DST rules; 193 1.112 christos ** for historical reasons, US rules are a common default. 194 1.22 kleink */ 195 1.22 kleink #ifndef TZDEFRULESTRING 196 1.134 christos # define TZDEFRULESTRING ",M3.2.0,M11.1.0" 197 1.109 christos #endif 198 1.22 kleink 199 1.126 christos typedef int_fast64_t __time_t; 200 1.126 christos 201 1.145 christos /* Limit to time zone abbreviation length in proleptic TZ strings. 202 1.145 christos This is distinct from TZ_MAX_CHARS, which limits TZif file contents. 203 1.145 christos It defaults to 254, not 255, so that desigidx_type can be an unsigned char. 204 1.145 christos unsigned char suffices for TZif files, so the only reason to increase 205 1.145 christos TZNAME_MAXIMUM is to support TZ strings specifying abbreviations 206 1.145 christos longer than 254 bytes. There is little reason to do that, though, 207 1.145 christos as strings that long are hardly "abbreviations". */ 208 1.145 christos #ifndef TZNAME_MAXIMUM 209 1.145 christos # define TZNAME_MAXIMUM 254 210 1.145 christos #endif 211 1.145 christos 212 1.145 christos #if TZNAME_MAXIMUM < UCHAR_MAX 213 1.145 christos typedef unsigned char desigidx_type; 214 1.145 christos #elif TZNAME_MAXIMUM < INT_MAX 215 1.145 christos typedef int desigidx_type; 216 1.145 christos #elif TZNAME_MAXIMUM < PTRDIFF_MAX 217 1.145 christos typedef ptrdiff_t desigidx_type; 218 1.145 christos #else 219 1.145 christos # error "TZNAME_MAXIMUM too large" 220 1.145 christos #endif 221 1.145 christos 222 1.1 jtc struct ttinfo { /* time type information */ 223 1.145 christos int_least32_t tt_utoff; /* UT offset in seconds */ 224 1.145 christos desigidx_type tt_desigidx; /* abbreviation list index */ 225 1.87 christos bool tt_isdst; /* used to set tm_isdst */ 226 1.87 christos bool tt_ttisstd; /* transition is std time */ 227 1.122 christos bool tt_ttisut; /* transition is UT */ 228 1.1 jtc }; 229 1.1 jtc 230 1.1 jtc struct lsinfo { /* leap second information */ 231 1.126 christos __time_t ls_trans; /* transition time */ 232 1.124 christos int_fast32_t ls_corr; /* correction to apply */ 233 1.1 jtc }; 234 1.1 jtc 235 1.129 christos /* This abbreviation means local time is unspecified. */ 236 1.129 christos static char const UNSPEC[] = "-00"; 237 1.129 christos 238 1.129 christos /* How many extra bytes are needed at the end of struct state's chars array. 239 1.129 christos This needs to be at least 1 for null termination in case the input 240 1.129 christos data isn't properly terminated, and it also needs to be big enough 241 1.129 christos for ttunspecified to work without crashing. */ 242 1.134 christos enum { CHARS_EXTRA = max(sizeof UNSPEC, 2) - 1 }; 243 1.129 christos 244 1.87 christos #define state __state 245 1.139 christos /* A representation of the contents of a TZif file. Ideally this 246 1.139 christos would have no size limits; the following sizes should suffice for 247 1.139 christos practical use. This struct should not be too large, as instances 248 1.139 christos are put on the stack and stacks are relatively small on some platforms. 249 1.139 christos See tzfile.h for more about the sizes. */ 250 1.87 christos struct state { 251 1.1 jtc int leapcnt; 252 1.1 jtc int timecnt; 253 1.1 jtc int typecnt; 254 1.1 jtc int charcnt; 255 1.87 christos bool goback; 256 1.87 christos bool goahead; 257 1.126 christos __time_t ats[TZ_MAX_TIMES]; 258 1.1 jtc unsigned char types[TZ_MAX_TIMES]; 259 1.1 jtc struct ttinfo ttis[TZ_MAX_TYPES]; 260 1.140 christos /*CONSTCOND*/ 261 1.134 christos char chars[max(max(TZ_MAX_CHARS + CHARS_EXTRA, sizeof "UTC"), 262 1.138 christos 2 * (TZNAME_MAXIMUM + 1))]; 263 1.1 jtc struct lsinfo lsis[TZ_MAX_LEAPS]; 264 1.1 jtc }; 265 1.1 jtc 266 1.96 christos enum r_type { 267 1.96 christos JULIAN_DAY, /* Jn = Julian day */ 268 1.96 christos DAY_OF_YEAR, /* n = day of year */ 269 1.96 christos MONTH_NTH_DAY_OF_WEEK /* Mm.n.d = month, week, day of week */ 270 1.96 christos }; 271 1.96 christos 272 1.1 jtc struct rule { 273 1.96 christos enum r_type r_type; /* type of rule */ 274 1.1 jtc int r_day; /* day number of rule */ 275 1.1 jtc int r_week; /* week number of rule */ 276 1.1 jtc int r_mon; /* month number of rule */ 277 1.74 christos int_fast32_t r_time; /* transition time of rule */ 278 1.1 jtc }; 279 1.1 jtc 280 1.87 christos static struct tm *gmtsub(struct state const *, time_t const *, int_fast32_t, 281 1.87 christos struct tm *); 282 1.87 christos static bool increment_overflow(int *, int); 283 1.126 christos static bool increment_overflow_time(__time_t *, int_fast32_t); 284 1.140 christos static int_fast32_t leapcorr(struct state const *, __time_t); 285 1.87 christos static struct tm *timesub(time_t const *, int_fast32_t, struct state const *, 286 1.87 christos struct tm *); 287 1.139 christos static bool tzparse(char const *, struct state *, struct state const *); 288 1.1 jtc 289 1.145 christos #ifndef ALL_STATE 290 1.145 christos static struct state * gmtptr; 291 1.145 christos #else 292 1.145 christos static struct state gmtmem; 293 1.145 christos static struct state *const gmtptr = &gmtmem; 294 1.145 christos #endif 295 1.1 jtc 296 1.1 jtc #ifndef TZ_STRLEN_MAX 297 1.134 christos # define TZ_STRLEN_MAX 255 298 1.1 jtc #endif /* !defined TZ_STRLEN_MAX */ 299 1.1 jtc 300 1.145 christos #if !USE_TIMEX_T || !defined TM_GMTOFF 301 1.45 mlelstv static char lcl_TZname[TZ_STRLEN_MAX + 1]; 302 1.45 mlelstv static int lcl_is_set; 303 1.145 christos #endif 304 1.42 christos 305 1.42 christos 306 1.117 christos #if !defined(__LIBC12_SOURCE__) 307 1.145 christos # ifndef ALL_STATE 308 1.145 christos struct state * __lclptr; 309 1.145 christos # else 310 1.145 christos static struct state lclmem; 311 1.145 christos struct state *const __lclptr = &lclmem; 312 1.145 christos # endif 313 1.145 christos # ifdef _REENTRANT 314 1.117 christos rwlock_t __lcl_lock = RWLOCK_INITIALIZER; 315 1.145 christos # endif 316 1.19 kleink #endif 317 1.19 kleink 318 1.1 jtc /* 319 1.1 jtc ** Section 4.12.3 of X3.159-1989 requires that 320 1.1 jtc ** Except for the strftime function, these functions [asctime, 321 1.1 jtc ** ctime, gmtime, localtime] return values in one of two static 322 1.1 jtc ** objects: a broken-down time structure and an array of char. 323 1.45 mlelstv ** Thanks to Paul Eggert for noting this. 324 1.138 christos ** 325 1.144 christos ** Although this requirement was removed in C99 it is still present in POSIX. 326 1.144 christos ** Follow the requirement if SUPPORT_C89, even though this is more likely to 327 1.144 christos ** trigger latent bugs in programs. 328 1.1 jtc */ 329 1.1 jtc 330 1.145 christos #if !USE_TIMEX_T 331 1.145 christos 332 1.145 christos # if SUPPORT_C89 333 1.1 jtc static struct tm tm; 334 1.145 christos # endif 335 1.102 christos 336 1.145 christos # if 2 <= HAVE_TZNAME + TZ_TIME_T || defined(__NetBSD__) 337 1.145 christos # if !defined(__LIBC12_SOURCE__) 338 1.145 christos __aconst char *tzname[2] = { 339 1.145 christos (__aconst char *) UNCONST(wildabbr), 340 1.145 christos (__aconst char *) UNCONST(wildabbr), 341 1.102 christos }; 342 1.145 christos # else 343 1.102 christos 344 1.102 christos extern __aconst char * tzname[2]; 345 1.102 christos 346 1.145 christos # endif /* __LIBC12_SOURCE__ */ 347 1.145 christos # endif 348 1.102 christos 349 1.145 christos # if 2 <= USG_COMPAT + TZ_TIME_T || defined(__NetBSD__) 350 1.145 christos # if !defined(__LIBC12_SOURCE__) 351 1.42 christos long timezone = 0; 352 1.1 jtc int daylight = 0; 353 1.145 christos # endif /* __LIBC12_SOURCE__ */ 354 1.145 christos # endif /* 2<= USG_COMPAT + TZ_TIME_T */ 355 1.1 jtc 356 1.145 christos # if 2 <= ALTZONE + TZ_TIME_T 357 1.81 christos long altzone = 0; 358 1.145 christos # endif /* 2 <= ALTZONE + TZ_TIME_T */ 359 1.145 christos #endif 360 1.1 jtc 361 1.122 christos /* Initialize *S to a value based on UTOFF, ISDST, and DESIGIDX. */ 362 1.91 christos static void 363 1.145 christos init_ttinfo(struct ttinfo *s, int_fast32_t utoff, bool isdst, 364 1.145 christos desigidx_type desigidx) 365 1.91 christos { 366 1.147 christos s->tt_utoff = (int_least32_t)utoff; 367 1.131 rillig s->tt_isdst = isdst; 368 1.131 rillig s->tt_desigidx = desigidx; 369 1.131 rillig s->tt_ttisstd = false; 370 1.131 rillig s->tt_ttisut = false; 371 1.91 christos } 372 1.91 christos 373 1.129 christos /* Return true if SP's time type I does not specify local time. */ 374 1.129 christos static bool 375 1.129 christos ttunspecified(struct state const *sp, int i) 376 1.129 christos { 377 1.129 christos char const *abbr = &sp->chars[sp->ttis[i].tt_desigidx]; 378 1.129 christos /* memcmp is likely faster than strcmp, and is safe due to CHARS_EXTRA. */ 379 1.129 christos return memcmp(abbr, UNSPEC, sizeof UNSPEC) == 0; 380 1.129 christos } 381 1.129 christos 382 1.74 christos static int_fast32_t 383 1.49 christos detzcode(const char *const codep) 384 1.1 jtc { 385 1.130 rillig register int_fast32_t result; 386 1.130 rillig register int i; 387 1.95 christos int_fast32_t one = 1; 388 1.95 christos int_fast32_t halfmaxval = one << (32 - 2); 389 1.95 christos int_fast32_t maxval = halfmaxval - 1 + halfmaxval; 390 1.95 christos int_fast32_t minval = -1 - maxval; 391 1.45 mlelstv 392 1.95 christos result = codep[0] & 0x7f; 393 1.95 christos for (i = 1; i < 4; ++i) 394 1.45 mlelstv result = (result << 8) | (codep[i] & 0xff); 395 1.95 christos 396 1.95 christos if (codep[0] & 0x80) { 397 1.95 christos /* Do two's-complement negation even on non-two's-complement machines. 398 1.95 christos If the result would be minval - 1, return minval. */ 399 1.131 rillig result -= !TWOS_COMPLEMENT(int_fast32_t) && result != 0; 400 1.131 rillig result += minval; 401 1.95 christos } 402 1.131 rillig return result; 403 1.45 mlelstv } 404 1.45 mlelstv 405 1.81 christos static int_fast64_t 406 1.49 christos detzcode64(const char *const codep) 407 1.45 mlelstv { 408 1.130 rillig register int_fast64_t result; 409 1.130 rillig register int i; 410 1.95 christos int_fast64_t one = 1; 411 1.95 christos int_fast64_t halfmaxval = one << (64 - 2); 412 1.95 christos int_fast64_t maxval = halfmaxval - 1 + halfmaxval; 413 1.95 christos int_fast64_t minval = -TWOS_COMPLEMENT(int_fast64_t) - maxval; 414 1.1 jtc 415 1.95 christos result = codep[0] & 0x7f; 416 1.95 christos for (i = 1; i < 8; ++i) 417 1.81 christos result = (result << 8) | (codep[i] & 0xff); 418 1.95 christos 419 1.95 christos if (codep[0] & 0x80) { 420 1.95 christos /* Do two's-complement negation even on non-two's-complement machines. 421 1.95 christos If the result would be minval - 1, return minval. */ 422 1.95 christos result -= !TWOS_COMPLEMENT(int_fast64_t) && result != 0; 423 1.95 christos result += minval; 424 1.95 christos } 425 1.131 rillig return result; 426 1.1 jtc } 427 1.1 jtc 428 1.121 christos #include <stdio.h> 429 1.121 christos 430 1.49 christos const char * 431 1.49 christos tzgetname(const timezone_t sp, int isdst) 432 1.49 christos { 433 1.49 christos int i; 434 1.121 christos const char *name = NULL; 435 1.103 ginsbach for (i = 0; i < sp->typecnt; ++i) { 436 1.120 christos const struct ttinfo *const ttisp = &sp->ttis[i]; 437 1.49 christos if (ttisp->tt_isdst == isdst) 438 1.122 christos name = &sp->chars[ttisp->tt_desigidx]; 439 1.49 christos } 440 1.121 christos if (name != NULL) 441 1.121 christos return name; 442 1.88 christos errno = ESRCH; 443 1.49 christos return NULL; 444 1.49 christos } 445 1.49 christos 446 1.99 christos long 447 1.99 christos tzgetgmtoff(const timezone_t sp, int isdst) 448 1.99 christos { 449 1.99 christos int i; 450 1.99 christos long l = -1; 451 1.103 ginsbach for (i = 0; i < sp->typecnt; ++i) { 452 1.120 christos const struct ttinfo *const ttisp = &sp->ttis[i]; 453 1.99 christos 454 1.99 christos if (ttisp->tt_isdst == isdst) { 455 1.122 christos l = ttisp->tt_utoff; 456 1.99 christos } 457 1.99 christos } 458 1.99 christos if (l == -1) 459 1.99 christos errno = ESRCH; 460 1.99 christos return l; 461 1.99 christos } 462 1.99 christos 463 1.145 christos #if !USE_TIMEX_T || !defined TM_GMTOFF 464 1.145 christos 465 1.49 christos static void 466 1.132 rillig update_tzname_etc(struct state const *sp, struct ttinfo const *ttisp) 467 1.92 christos { 468 1.145 christos # if HAVE_TZNAME 469 1.145 christos tzname[ttisp->tt_isdst] = UNCONST(&sp->chars[ttisp->tt_desigidx]); 470 1.145 christos # endif 471 1.145 christos # if USG_COMPAT 472 1.131 rillig if (!ttisp->tt_isdst) 473 1.131 rillig timezone = - ttisp->tt_utoff; 474 1.145 christos # endif 475 1.145 christos # if ALTZONE 476 1.131 rillig if (ttisp->tt_isdst) 477 1.131 rillig altzone = - ttisp->tt_utoff; 478 1.145 christos # endif 479 1.92 christos } 480 1.92 christos 481 1.134 christos /* If STDDST_MASK indicates that SP's TYPE provides useful info, 482 1.134 christos update tzname, timezone, and/or altzone and return STDDST_MASK, 483 1.134 christos diminished by the provided info if it is a specified local time. 484 1.134 christos Otherwise, return STDDST_MASK. See settzname for STDDST_MASK. */ 485 1.134 christos static int 486 1.134 christos may_update_tzname_etc(int stddst_mask, struct state *sp, int type) 487 1.134 christos { 488 1.134 christos struct ttinfo *ttisp = &sp->ttis[type]; 489 1.134 christos int this_bit = 1 << ttisp->tt_isdst; 490 1.134 christos if (stddst_mask & this_bit) { 491 1.134 christos update_tzname_etc(sp, ttisp); 492 1.134 christos if (!ttunspecified(sp, type)) 493 1.134 christos return stddst_mask & ~this_bit; 494 1.134 christos } 495 1.134 christos return stddst_mask; 496 1.134 christos } 497 1.134 christos 498 1.45 mlelstv static void 499 1.45 mlelstv settzname(void) 500 1.1 jtc { 501 1.130 rillig register timezone_t const sp = __lclptr; 502 1.130 rillig register int i; 503 1.1 jtc 504 1.134 christos /* If STDDST_MASK & 1 we need info about a standard time. 505 1.134 christos If STDDST_MASK & 2 we need info about a daylight saving time. 506 1.134 christos When STDDST_MASK becomes zero we can stop looking. */ 507 1.134 christos int stddst_mask = 0; 508 1.134 christos 509 1.145 christos # if HAVE_TZNAME 510 1.145 christos tzname[0] = tzname[1] = UNCONST(sp ? wildabbr : utc); 511 1.134 christos stddst_mask = 3; 512 1.145 christos # endif 513 1.145 christos # if USG_COMPAT 514 1.1 jtc timezone = 0; 515 1.134 christos stddst_mask = 3; 516 1.145 christos # endif 517 1.145 christos # if ALTZONE 518 1.1 jtc altzone = 0; 519 1.134 christos stddst_mask |= 2; 520 1.145 christos # endif 521 1.58 christos /* 522 1.113 christos ** And to get the latest time zone abbreviations into tzname. . . 523 1.58 christos */ 524 1.134 christos if (sp) { 525 1.134 christos for (i = sp->timecnt - 1; stddst_mask && 0 <= i; i--) 526 1.134 christos stddst_mask = may_update_tzname_etc(stddst_mask, sp, sp->types[i]); 527 1.134 christos for (i = sp->typecnt - 1; stddst_mask && 0 <= i; i--) 528 1.134 christos stddst_mask = may_update_tzname_etc(stddst_mask, sp, i); 529 1.145 christos } 530 1.1 jtc 531 1.145 christos # if USG_COMPAT 532 1.140 christos daylight = (unsigned int)stddst_mask >> 1 ^ 1; 533 1.145 christos # endif 534 1.1 jtc } 535 1.1 jtc 536 1.138 christos /* Replace bogus characters in time zone abbreviations. 537 1.138 christos Return 0 on success, an errno value if a time zone abbreviation is 538 1.138 christos too long. */ 539 1.138 christos static int 540 1.124 christos scrub_abbrs(struct state *sp) 541 1.45 mlelstv { 542 1.124 christos int i; 543 1.138 christos 544 1.138 christos /* Reject overlong abbreviations. */ 545 1.138 christos for (i = 0; i < sp->charcnt - (TZNAME_MAXIMUM + 1); ) { 546 1.140 christos int len = (int)strlen(&sp->chars[i]); 547 1.138 christos if (TZNAME_MAXIMUM < len) 548 1.138 christos return EOVERFLOW; 549 1.138 christos i += len + 1; 550 1.138 christos } 551 1.138 christos 552 1.138 christos /* Replace bogus characters. */ 553 1.124 christos for (i = 0; i < sp->charcnt; ++i) 554 1.124 christos if (strchr(TZ_ABBR_CHAR_SET, sp->chars[i]) == NULL) 555 1.124 christos sp->chars[i] = TZ_ABBR_ERR_CHAR; 556 1.124 christos 557 1.138 christos return 0; 558 1.45 mlelstv } 559 1.45 mlelstv 560 1.145 christos #endif 561 1.145 christos 562 1.124 christos /* Input buffer for data read from a compiled tz file. */ 563 1.91 christos union input_buffer { 564 1.131 rillig /* The first part of the buffer, interpreted as a header. */ 565 1.131 rillig struct tzhead tzhead; 566 1.91 christos 567 1.139 christos /* The entire buffer. Ideally this would have no size limits; 568 1.139 christos the following should suffice for practical use. */ 569 1.131 rillig char buf[2 * sizeof(struct tzhead) + 2 * sizeof(struct state) 570 1.131 rillig + 4 * TZ_MAX_TIMES]; 571 1.91 christos }; 572 1.91 christos 573 1.109 christos /* TZDIR with a trailing '/' rather than a trailing '\0'. */ 574 1.109 christos static char const tzdirslash[sizeof TZDIR] = TZDIR "/"; 575 1.109 christos 576 1.91 christos /* Local storage needed for 'tzloadbody'. */ 577 1.91 christos union local_storage { 578 1.131 rillig /* The results of analyzing the file's contents after it is opened. */ 579 1.131 rillig struct file_analysis { 580 1.131 rillig /* The input buffer. */ 581 1.131 rillig union input_buffer u; 582 1.131 rillig 583 1.131 rillig /* A temporary state used for parsing a TZ string in the file. */ 584 1.131 rillig struct state st; 585 1.131 rillig } u; 586 1.131 rillig 587 1.139 christos /* The name of the file to be opened. Ideally this would have no 588 1.139 christos size limits, to support arbitrarily long Zone names. 589 1.139 christos Limiting Zone names to 1024 bytes should suffice for practical use. 590 1.139 christos However, there is no need for this to be smaller than struct 591 1.139 christos file_analysis as that struct is allocated anyway, as the other 592 1.139 christos union member. */ 593 1.134 christos char fullname[max(sizeof(struct file_analysis), sizeof tzdirslash + 1024)]; 594 1.91 christos }; 595 1.91 christos 596 1.145 christos /* These tzload flags can be ORed together, and fit into 'char'. */ 597 1.145 christos enum { TZLOAD_FROMENV = 1 }; /* The TZ string came from the environment. */ 598 1.145 christos enum { TZLOAD_TZSTRING = 2 }; /* Read any newline-surrounded TZ string. */ 599 1.145 christos 600 1.145 christos /* Load tz data from the file named NAME into *SP. Respect TZLOADFLAGS. 601 1.145 christos Use *LSP for temporary storage. Return 0 on 602 1.91 christos success, an errno value on failure. */ 603 1.91 christos static int 604 1.145 christos tzloadbody(char const *name, struct state *sp, char tzloadflags, 605 1.131 rillig union local_storage *lsp) 606 1.49 christos { 607 1.130 rillig register int i; 608 1.130 rillig register int fid; 609 1.130 rillig register int stored; 610 1.130 rillig register ssize_t nread; 611 1.130 rillig register bool doaccess; 612 1.130 rillig register union input_buffer *up = &lsp->u.u; 613 1.130 rillig register size_t tzheadsize = sizeof(struct tzhead); 614 1.83 christos 615 1.87 christos sp->goback = sp->goahead = false; 616 1.83 christos 617 1.83 christos if (! name) { 618 1.83 christos name = TZDEFAULT; 619 1.83 christos if (! name) 620 1.131 rillig return EINVAL; 621 1.83 christos } 622 1.83 christos 623 1.83 christos if (name[0] == ':') 624 1.83 christos ++name; 625 1.112 christos #ifdef SUPPRESS_TZDIR 626 1.112 christos /* Do not prepend TZDIR. This is intended for specialized 627 1.112 christos applications only, due to its security implications. */ 628 1.112 christos doaccess = true; 629 1.112 christos #else 630 1.83 christos doaccess = name[0] == '/'; 631 1.112 christos #endif 632 1.83 christos if (!doaccess) { 633 1.114 christos char const *dot; 634 1.136 christos if (sizeof lsp->fullname - sizeof tzdirslash <= strlen(name)) 635 1.131 rillig return ENAMETOOLONG; 636 1.109 christos 637 1.109 christos /* Create a string "TZDIR/NAME". Using sprintf here 638 1.109 christos would pull in stdio (and would fail if the 639 1.109 christos resulting string length exceeded INT_MAX!). */ 640 1.109 christos memcpy(lsp->fullname, tzdirslash, sizeof tzdirslash); 641 1.109 christos strcpy(lsp->fullname + sizeof tzdirslash, name); 642 1.109 christos 643 1.114 christos /* Set doaccess if NAME contains a ".." file name 644 1.114 christos component, as such a name could read a file outside 645 1.114 christos the TZDIR virtual subtree. */ 646 1.132 rillig for (dot = name; (dot = strchr(dot, '.')); dot++) 647 1.114 christos if ((dot == name || dot[-1] == '/') && dot[1] == '.' 648 1.114 christos && (dot[2] == '/' || !dot[2])) { 649 1.114 christos doaccess = true; 650 1.114 christos break; 651 1.114 christos } 652 1.114 christos 653 1.110 kre name = lsp->fullname; 654 1.1 jtc } 655 1.145 christos if (doaccess && (tzloadflags & TZLOAD_FROMENV)) { 656 1.145 christos /* Check for security violations and for devices whose mere 657 1.145 christos opening could have unwanted side effects. Although these 658 1.145 christos checks are racy, they're better than nothing and there is 659 1.145 christos no portable way to fix the races. */ 660 1.145 christos if (access(name, R_OK) < 0) 661 1.145 christos return errno; 662 1.145 christos #if 0 /* handle with O_REGULAR instead */ 663 1.145 christos #ifdef S_ISREG 664 1.145 christos { 665 1.145 christos struct stat st; 666 1.145 christos if (stat(name, &st) < 0) 667 1.145 christos return errno; 668 1.145 christos if (!S_ISREG(st.st_mode)) 669 1.145 christos return EINVAL; 670 1.145 christos } 671 1.145 christos #endif 672 1.145 christos #endif 673 1.145 christos } 674 1.145 christos fid = open(name, (O_RDONLY | O_BINARY | O_CLOEXEC | O_CLOFORK 675 1.145 christos | O_IGNORE_CTTY | O_NOCTTY | O_REGULAR)); 676 1.83 christos if (fid < 0) 677 1.131 rillig return errno; 678 1.124 christos 679 1.58 christos nread = read(fid, up->buf, sizeof up->buf); 680 1.91 christos if (nread < (ssize_t)tzheadsize) { 681 1.131 rillig int err = nread < 0 ? errno : EINVAL; 682 1.131 rillig close(fid); 683 1.131 rillig return err; 684 1.91 christos } 685 1.91 christos if (close(fid) < 0) 686 1.131 rillig return errno; 687 1.45 mlelstv for (stored = 4; stored <= 8; stored *= 2) { 688 1.129 christos char version = up->tzhead.tzh_version[0]; 689 1.129 christos bool skip_datablock = stored == 4 && version; 690 1.129 christos int_fast32_t datablock_size; 691 1.129 christos int_fast32_t ttisstdcnt = detzcode(up->tzhead.tzh_ttisstdcnt); 692 1.129 christos int_fast32_t ttisutcnt = detzcode(up->tzhead.tzh_ttisutcnt); 693 1.129 christos int_fast64_t prevtr = -1; 694 1.129 christos int_fast32_t prevcorr = 0; 695 1.129 christos int_fast32_t leapcnt = detzcode(up->tzhead.tzh_leapcnt); 696 1.129 christos int_fast32_t timecnt = detzcode(up->tzhead.tzh_timecnt); 697 1.129 christos int_fast32_t typecnt = detzcode(up->tzhead.tzh_typecnt); 698 1.129 christos int_fast32_t charcnt = detzcode(up->tzhead.tzh_charcnt); 699 1.129 christos char const *p = up->buf + tzheadsize; 700 1.129 christos /* Although tzfile(5) currently requires typecnt to be nonzero, 701 1.129 christos support future formats that may allow zero typecnt 702 1.129 christos in files that have a TZ string and no transitions. */ 703 1.129 christos if (! (0 <= leapcnt && leapcnt < TZ_MAX_LEAPS 704 1.129 christos && 0 <= typecnt && typecnt < TZ_MAX_TYPES 705 1.129 christos && 0 <= timecnt && timecnt < TZ_MAX_TIMES 706 1.129 christos && 0 <= charcnt && charcnt < TZ_MAX_CHARS 707 1.129 christos && 0 <= ttisstdcnt && ttisstdcnt < TZ_MAX_TYPES 708 1.129 christos && 0 <= ttisutcnt && ttisutcnt < TZ_MAX_TYPES)) 709 1.129 christos return EINVAL; 710 1.129 christos datablock_size 711 1.129 christos = (timecnt * stored /* ats */ 712 1.87 christos + timecnt /* types */ 713 1.87 christos + typecnt * 6 /* ttinfos */ 714 1.87 christos + charcnt /* chars */ 715 1.87 christos + leapcnt * (stored + 4) /* lsinfos */ 716 1.87 christos + ttisstdcnt /* ttisstds */ 717 1.129 christos + ttisutcnt); /* ttisuts */ 718 1.129 christos if (nread < (ssize_t)(tzheadsize + datablock_size)) 719 1.129 christos return EINVAL; 720 1.129 christos if (skip_datablock) 721 1.129 christos p += datablock_size; 722 1.129 christos else { 723 1.129 christos if (! ((ttisstdcnt == typecnt || ttisstdcnt == 0) 724 1.129 christos && (ttisutcnt == typecnt || ttisutcnt == 0))) 725 1.91 christos return EINVAL; 726 1.129 christos 727 1.142 christos sp->leapcnt = (int)leapcnt; 728 1.142 christos sp->timecnt = (int)timecnt; 729 1.142 christos sp->typecnt = (int)typecnt; 730 1.142 christos sp->charcnt = (int)charcnt; 731 1.87 christos 732 1.87 christos /* Read transitions, discarding those out of time_t range. 733 1.109 christos But pretend the last transition before TIME_T_MIN 734 1.109 christos occurred at TIME_T_MIN. */ 735 1.81 christos timecnt = 0; 736 1.1 jtc for (i = 0; i < sp->timecnt; ++i) { 737 1.81 christos int_fast64_t at 738 1.81 christos = stored == 4 ? detzcode(p) : detzcode64(p); 739 1.109 christos sp->types[i] = at <= TIME_T_MAX; 740 1.81 christos if (sp->types[i]) { 741 1.131 rillig time_t attime 742 1.131 rillig = ((TYPE_SIGNED(time_t) ? at < TIME_T_MIN : at < 0) 743 1.131 rillig ? TIME_T_MIN : (time_t)at); 744 1.131 rillig if (timecnt && attime <= sp->ats[timecnt - 1]) { 745 1.131 rillig if (attime < sp->ats[timecnt - 1]) 746 1.131 rillig return EINVAL; 747 1.131 rillig sp->types[i - 1] = 0; 748 1.131 rillig timecnt--; 749 1.131 rillig } 750 1.131 rillig sp->ats[timecnt++] = attime; 751 1.81 christos } 752 1.45 mlelstv p += stored; 753 1.1 jtc } 754 1.87 christos 755 1.81 christos timecnt = 0; 756 1.1 jtc for (i = 0; i < sp->timecnt; ++i) { 757 1.81 christos unsigned char typ = *p++; 758 1.81 christos if (sp->typecnt <= typ) 759 1.91 christos return EINVAL; 760 1.81 christos if (sp->types[i]) 761 1.81 christos sp->types[timecnt++] = typ; 762 1.1 jtc } 763 1.142 christos sp->timecnt = (int)timecnt; 764 1.1 jtc for (i = 0; i < sp->typecnt; ++i) { 765 1.130 rillig register struct ttinfo * ttisp; 766 1.122 christos unsigned char isdst, desigidx; 767 1.1 jtc 768 1.1 jtc ttisp = &sp->ttis[i]; 769 1.146 christos ttisp->tt_utoff = (int_least32_t)detzcode(p); 770 1.1 jtc p += 4; 771 1.87 christos isdst = *p++; 772 1.87 christos if (! (isdst < 2)) 773 1.131 rillig return EINVAL; 774 1.87 christos ttisp->tt_isdst = isdst; 775 1.122 christos desigidx = *p++; 776 1.122 christos if (! (desigidx < sp->charcnt)) 777 1.131 rillig return EINVAL; 778 1.122 christos ttisp->tt_desigidx = desigidx; 779 1.1 jtc } 780 1.1 jtc for (i = 0; i < sp->charcnt; ++i) 781 1.1 jtc sp->chars[i] = *p++; 782 1.129 christos /* Ensure '\0'-terminated, and make it safe to call 783 1.129 christos ttunspecified later. */ 784 1.129 christos memset(&sp->chars[i], 0, CHARS_EXTRA); 785 1.87 christos 786 1.87 christos /* Read leap seconds, discarding those out of time_t range. */ 787 1.87 christos leapcnt = 0; 788 1.1 jtc for (i = 0; i < sp->leapcnt; ++i) { 789 1.131 rillig int_fast64_t tr = stored == 4 ? detzcode(p) : detzcode64(p); 790 1.131 rillig int_fast32_t corr = detzcode(p + stored); 791 1.131 rillig p += stored + 4; 792 1.131 rillig 793 1.131 rillig /* Leap seconds cannot occur before the Epoch, 794 1.131 rillig or out of order. */ 795 1.131 rillig if (tr <= prevtr) 796 1.131 rillig return EINVAL; 797 1.131 rillig 798 1.131 rillig /* To avoid other botches in this code, each leap second's 799 1.131 rillig correction must differ from the previous one's by 1 800 1.131 rillig second or less, except that the first correction can be 801 1.131 rillig any value; these requirements are more generous than 802 1.145 christos RFC 9636, to allow future RFC extensions. */ 803 1.131 rillig if (! (i == 0 804 1.131 rillig || (prevcorr < corr 805 1.131 rillig ? corr == prevcorr + 1 806 1.131 rillig : (corr == prevcorr 807 1.131 rillig || corr == prevcorr - 1)))) 808 1.131 rillig return EINVAL; 809 1.131 rillig prevtr = tr; 810 1.131 rillig prevcorr = corr; 811 1.131 rillig 812 1.131 rillig if (tr <= TIME_T_MAX) { 813 1.131 rillig sp->lsis[leapcnt].ls_trans = (time_t)tr; 814 1.131 rillig sp->lsis[leapcnt].ls_corr = corr; 815 1.131 rillig leapcnt++; 816 1.131 rillig } 817 1.87 christos } 818 1.142 christos sp->leapcnt = (int)leapcnt; 819 1.1 jtc 820 1.1 jtc for (i = 0; i < sp->typecnt; ++i) { 821 1.130 rillig register struct ttinfo * ttisp; 822 1.1 jtc 823 1.1 jtc ttisp = &sp->ttis[i]; 824 1.1 jtc if (ttisstdcnt == 0) 825 1.87 christos ttisp->tt_ttisstd = false; 826 1.1 jtc else { 827 1.87 christos if (*p != true && *p != false) 828 1.91 christos return EINVAL; 829 1.1 jtc ttisp->tt_ttisstd = *p++; 830 1.1 jtc } 831 1.1 jtc } 832 1.1 jtc for (i = 0; i < sp->typecnt; ++i) { 833 1.130 rillig register struct ttinfo * ttisp; 834 1.1 jtc 835 1.1 jtc ttisp = &sp->ttis[i]; 836 1.122 christos if (ttisutcnt == 0) 837 1.122 christos ttisp->tt_ttisut = false; 838 1.1 jtc else { 839 1.87 christos if (*p != true && *p != false) 840 1.91 christos return EINVAL; 841 1.122 christos ttisp->tt_ttisut = *p++; 842 1.1 jtc } 843 1.1 jtc } 844 1.129 christos } 845 1.129 christos 846 1.129 christos nread -= p - up->buf; 847 1.129 christos memmove(up->buf, p, (size_t)nread); 848 1.129 christos 849 1.129 christos /* If this is an old file, we're done. */ 850 1.129 christos if (!version) 851 1.129 christos break; 852 1.45 mlelstv } 853 1.145 christos if ((tzloadflags & TZLOAD_TZSTRING) && nread > 2 && 854 1.58 christos up->buf[0] == '\n' && up->buf[nread - 1] == '\n' && 855 1.45 mlelstv sp->typecnt + 2 <= TZ_MAX_TYPES) { 856 1.131 rillig struct state *ts = &lsp->u.st; 857 1.45 mlelstv 858 1.58 christos up->buf[nread - 1] = '\0'; 859 1.124 christos if (tzparse(&up->buf[1], ts, sp)) { 860 1.98 christos 861 1.98 christos /* Attempt to reuse existing abbreviations. 862 1.106 christos Without this, America/Anchorage would be right on 863 1.106 christos the edge after 2037 when TZ_MAX_CHARS is 50, as 864 1.106 christos sp->charcnt equals 40 (for LMT AST AWT APT AHST 865 1.98 christos AHDT YST AKDT AKST) and ts->charcnt equals 10 866 1.98 christos (for AKST AKDT). Reusing means sp->charcnt can 867 1.106 christos stay 40 in this example. */ 868 1.98 christos int gotabbr = 0; 869 1.98 christos int charcnt = sp->charcnt; 870 1.113 christos for (i = 0; i < ts->typecnt; i++) { 871 1.122 christos char *tsabbr = ts->chars + ts->ttis[i].tt_desigidx; 872 1.98 christos int j; 873 1.98 christos for (j = 0; j < charcnt; j++) 874 1.98 christos if (strcmp(sp->chars + j, tsabbr) == 0) { 875 1.122 christos ts->ttis[i].tt_desigidx = j; 876 1.98 christos gotabbr++; 877 1.98 christos break; 878 1.98 christos } 879 1.98 christos if (! (j < charcnt)) { 880 1.99 christos size_t tsabbrlen = strlen(tsabbr); 881 1.98 christos if (j + tsabbrlen < TZ_MAX_CHARS) { 882 1.98 christos strcpy(sp->chars + j, tsabbr); 883 1.142 christos charcnt = (int)(j + tsabbrlen + 1); 884 1.122 christos ts->ttis[i].tt_desigidx = j; 885 1.98 christos gotabbr++; 886 1.98 christos } 887 1.98 christos } 888 1.98 christos } 889 1.113 christos if (gotabbr == ts->typecnt) { 890 1.98 christos sp->charcnt = charcnt; 891 1.106 christos 892 1.106 christos /* Ignore any trailing, no-op transitions generated 893 1.106 christos by zic as they don't help here and can run afoul 894 1.106 christos of bugs in zic 2016j or earlier. */ 895 1.106 christos while (1 < sp->timecnt 896 1.106 christos && (sp->types[sp->timecnt - 1] 897 1.106 christos == sp->types[sp->timecnt - 2])) 898 1.106 christos sp->timecnt--; 899 1.106 christos 900 1.139 christos sp->goahead = ts->goahead; 901 1.139 christos 902 1.139 christos for (i = 0; i < ts->timecnt; i++) { 903 1.126 christos __time_t t = ts->ats[i]; 904 1.124 christos if (increment_overflow_time(&t, leapcorr(sp, t)) 905 1.124 christos || (0 < sp->timecnt 906 1.124 christos && t <= sp->ats[sp->timecnt - 1])) 907 1.124 christos continue; 908 1.139 christos if (TZ_MAX_TIMES <= sp->timecnt) { 909 1.139 christos sp->goahead = false; 910 1.139 christos break; 911 1.139 christos } 912 1.124 christos sp->ats[sp->timecnt] = t; 913 1.98 christos sp->types[sp->timecnt] = (sp->typecnt 914 1.98 christos + ts->types[i]); 915 1.98 christos sp->timecnt++; 916 1.98 christos } 917 1.113 christos for (i = 0; i < ts->typecnt; i++) 918 1.113 christos sp->ttis[sp->typecnt++] = ts->ttis[i]; 919 1.98 christos } 920 1.45 mlelstv } 921 1.45 mlelstv } 922 1.113 christos if (sp->typecnt == 0) 923 1.113 christos return EINVAL; 924 1.113 christos 925 1.91 christos return 0; 926 1.91 christos } 927 1.91 christos 928 1.145 christos /* Load tz data from the file named NAME into *SP. Respect TZLOADFLAGS. 929 1.145 christos Return 0 on success, an errno value on failure. */ 930 1.91 christos static int 931 1.145 christos tzload(char const *name, struct state *sp, char tzloadflags) 932 1.91 christos { 933 1.145 christos #ifdef ALL_STATE 934 1.131 rillig union local_storage *lsp = malloc(sizeof *lsp); 935 1.131 rillig if (!lsp) { 936 1.131 rillig return /*CONSTCOND*/HAVE_MALLOC_ERRNO ? errno : ENOMEM; 937 1.131 rillig } else { 938 1.145 christos int err = tzloadbody(name, sp, tzloadflags, lsp); 939 1.131 rillig free(lsp); 940 1.131 rillig return err; 941 1.131 rillig } 942 1.145 christos #else 943 1.145 christos union local_storage ls; 944 1.145 christos return tzloadbody(name, sp, tzloadflags, &ls); 945 1.145 christos #endif 946 1.1 jtc } 947 1.1 jtc 948 1.1 jtc static const int mon_lengths[2][MONSPERYEAR] = { 949 1.1 jtc { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }, 950 1.1 jtc { 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 } 951 1.1 jtc }; 952 1.1 jtc 953 1.1 jtc static const int year_lengths[2] = { 954 1.1 jtc DAYSPERNYEAR, DAYSPERLYEAR 955 1.1 jtc }; 956 1.1 jtc 957 1.124 christos /* Is C an ASCII digit? */ 958 1.124 christos static bool 959 1.124 christos is_digit(char c) 960 1.124 christos { 961 1.124 christos return '0' <= c && c <= '9'; 962 1.124 christos } 963 1.124 christos 964 1.1 jtc /* 965 1.113 christos ** Given a pointer into a timezone string, scan until a character that is not 966 1.113 christos ** a valid character in a time zone abbreviation is found. 967 1.113 christos ** Return a pointer to that character. 968 1.1 jtc */ 969 1.1 jtc 970 1.144 christos ATTRIBUTE_PURE_114833 static const char * 971 1.130 rillig getzname(register const char *strp) 972 1.1 jtc { 973 1.130 rillig register char c; 974 1.1 jtc 975 1.5 jtc while ((c = *strp) != '\0' && !is_digit(c) && c != ',' && c != '-' && 976 1.1 jtc c != '+') 977 1.1 jtc ++strp; 978 1.1 jtc return strp; 979 1.1 jtc } 980 1.1 jtc 981 1.1 jtc /* 982 1.113 christos ** Given a pointer into an extended timezone string, scan until the ending 983 1.113 christos ** delimiter of the time zone abbreviation is located. 984 1.113 christos ** Return a pointer to the delimiter. 985 1.45 mlelstv ** 986 1.45 mlelstv ** As with getzname above, the legal character set is actually quite 987 1.45 mlelstv ** restricted, with other characters producing undefined results. 988 1.45 mlelstv ** We don't do any checking here; checking is done later in common-case code. 989 1.45 mlelstv */ 990 1.45 mlelstv 991 1.144 christos ATTRIBUTE_PURE_114833 static const char * 992 1.130 rillig getqzname(register const char *strp, const int delim) 993 1.45 mlelstv { 994 1.130 rillig register int c; 995 1.45 mlelstv 996 1.45 mlelstv while ((c = *strp) != '\0' && c != delim) 997 1.45 mlelstv ++strp; 998 1.45 mlelstv return strp; 999 1.45 mlelstv } 1000 1.45 mlelstv 1001 1.45 mlelstv /* 1002 1.113 christos ** Given a pointer into a timezone string, extract a number from that string. 1003 1.1 jtc ** Check that the number is within a specified range; if it is not, return 1004 1.1 jtc ** NULL. 1005 1.1 jtc ** Otherwise, return a pointer to the first character not part of the number. 1006 1.1 jtc */ 1007 1.1 jtc 1008 1.1 jtc static const char * 1009 1.130 rillig getnum(register const char *strp, int *const nump, const int min, const int max) 1010 1.1 jtc { 1011 1.130 rillig register char c; 1012 1.130 rillig register int num; 1013 1.1 jtc 1014 1.46 christos if (strp == NULL || !is_digit(c = *strp)) { 1015 1.46 christos errno = EINVAL; 1016 1.1 jtc return NULL; 1017 1.46 christos } 1018 1.1 jtc num = 0; 1019 1.5 jtc do { 1020 1.1 jtc num = num * 10 + (c - '0'); 1021 1.46 christos if (num > max) { 1022 1.46 christos errno = EOVERFLOW; 1023 1.1 jtc return NULL; /* illegal value */ 1024 1.46 christos } 1025 1.5 jtc c = *++strp; 1026 1.5 jtc } while (is_digit(c)); 1027 1.46 christos if (num < min) { 1028 1.46 christos errno = EINVAL; 1029 1.1 jtc return NULL; /* illegal value */ 1030 1.46 christos } 1031 1.1 jtc *nump = num; 1032 1.1 jtc return strp; 1033 1.1 jtc } 1034 1.1 jtc 1035 1.1 jtc /* 1036 1.113 christos ** Given a pointer into a timezone string, extract a number of seconds, 1037 1.1 jtc ** in hh[:mm[:ss]] form, from the string. 1038 1.1 jtc ** If any error occurs, return NULL. 1039 1.1 jtc ** Otherwise, return a pointer to the first character not part of the number 1040 1.1 jtc ** of seconds. 1041 1.1 jtc */ 1042 1.1 jtc 1043 1.1 jtc static const char * 1044 1.130 rillig getsecs(register const char *strp, int_fast32_t *const secsp) 1045 1.1 jtc { 1046 1.1 jtc int num; 1047 1.124 christos int_fast32_t secsperhour = SECSPERHOUR; 1048 1.1 jtc 1049 1.1 jtc /* 1050 1.139 christos ** 'HOURSPERDAY * DAYSPERWEEK - 1' allows quasi-POSIX rules like 1051 1.139 christos ** "M10.4.6/26", which does not conform to POSIX, 1052 1.1 jtc ** but which specifies the equivalent of 1053 1.83 christos ** "02:00 on the first Sunday on or after 23 Oct". 1054 1.1 jtc */ 1055 1.1 jtc strp = getnum(strp, &num, 0, HOURSPERDAY * DAYSPERWEEK - 1); 1056 1.1 jtc if (strp == NULL) 1057 1.1 jtc return NULL; 1058 1.124 christos *secsp = num * secsperhour; 1059 1.1 jtc if (*strp == ':') { 1060 1.1 jtc ++strp; 1061 1.1 jtc strp = getnum(strp, &num, 0, MINSPERHOUR - 1); 1062 1.1 jtc if (strp == NULL) 1063 1.1 jtc return NULL; 1064 1.1 jtc *secsp += num * SECSPERMIN; 1065 1.1 jtc if (*strp == ':') { 1066 1.1 jtc ++strp; 1067 1.83 christos /* 'SECSPERMIN' allows for leap seconds. */ 1068 1.1 jtc strp = getnum(strp, &num, 0, SECSPERMIN); 1069 1.1 jtc if (strp == NULL) 1070 1.1 jtc return NULL; 1071 1.1 jtc *secsp += num; 1072 1.1 jtc } 1073 1.1 jtc } 1074 1.1 jtc return strp; 1075 1.1 jtc } 1076 1.1 jtc 1077 1.1 jtc /* 1078 1.113 christos ** Given a pointer into a timezone string, extract an offset, in 1079 1.1 jtc ** [+-]hh[:mm[:ss]] form, from the string. 1080 1.1 jtc ** If any error occurs, return NULL. 1081 1.1 jtc ** Otherwise, return a pointer to the first character not part of the time. 1082 1.1 jtc */ 1083 1.1 jtc 1084 1.1 jtc static const char * 1085 1.130 rillig getoffset(register const char *strp, int_fast32_t *const offsetp) 1086 1.1 jtc { 1087 1.130 rillig register bool neg = false; 1088 1.1 jtc 1089 1.1 jtc if (*strp == '-') { 1090 1.87 christos neg = true; 1091 1.1 jtc ++strp; 1092 1.5 jtc } else if (*strp == '+') 1093 1.5 jtc ++strp; 1094 1.1 jtc strp = getsecs(strp, offsetp); 1095 1.1 jtc if (strp == NULL) 1096 1.1 jtc return NULL; /* illegal time */ 1097 1.1 jtc if (neg) 1098 1.1 jtc *offsetp = -*offsetp; 1099 1.1 jtc return strp; 1100 1.1 jtc } 1101 1.1 jtc 1102 1.1 jtc /* 1103 1.113 christos ** Given a pointer into a timezone string, extract a rule in the form 1104 1.141 christos ** date[/time]. See POSIX Base Definitions section 8.3 variable TZ 1105 1.141 christos ** for the format of "date" and "time". 1106 1.1 jtc ** If a valid rule is not found, return NULL. 1107 1.1 jtc ** Otherwise, return a pointer to the first character not part of the rule. 1108 1.1 jtc */ 1109 1.1 jtc 1110 1.1 jtc static const char * 1111 1.130 rillig getrule(const char *strp, register struct rule *const rulep) 1112 1.1 jtc { 1113 1.1 jtc if (*strp == 'J') { 1114 1.1 jtc /* 1115 1.1 jtc ** Julian day. 1116 1.1 jtc */ 1117 1.1 jtc rulep->r_type = JULIAN_DAY; 1118 1.1 jtc ++strp; 1119 1.1 jtc strp = getnum(strp, &rulep->r_day, 1, DAYSPERNYEAR); 1120 1.1 jtc } else if (*strp == 'M') { 1121 1.1 jtc /* 1122 1.1 jtc ** Month, week, day. 1123 1.1 jtc */ 1124 1.1 jtc rulep->r_type = MONTH_NTH_DAY_OF_WEEK; 1125 1.1 jtc ++strp; 1126 1.1 jtc strp = getnum(strp, &rulep->r_mon, 1, MONSPERYEAR); 1127 1.1 jtc if (strp == NULL) 1128 1.1 jtc return NULL; 1129 1.1 jtc if (*strp++ != '.') 1130 1.1 jtc return NULL; 1131 1.1 jtc strp = getnum(strp, &rulep->r_week, 1, 5); 1132 1.1 jtc if (strp == NULL) 1133 1.1 jtc return NULL; 1134 1.1 jtc if (*strp++ != '.') 1135 1.1 jtc return NULL; 1136 1.1 jtc strp = getnum(strp, &rulep->r_day, 0, DAYSPERWEEK - 1); 1137 1.5 jtc } else if (is_digit(*strp)) { 1138 1.1 jtc /* 1139 1.1 jtc ** Day of year. 1140 1.1 jtc */ 1141 1.1 jtc rulep->r_type = DAY_OF_YEAR; 1142 1.1 jtc strp = getnum(strp, &rulep->r_day, 0, DAYSPERLYEAR - 1); 1143 1.1 jtc } else return NULL; /* invalid format */ 1144 1.1 jtc if (strp == NULL) 1145 1.1 jtc return NULL; 1146 1.1 jtc if (*strp == '/') { 1147 1.1 jtc /* 1148 1.1 jtc ** Time specified. 1149 1.1 jtc */ 1150 1.1 jtc ++strp; 1151 1.78 christos strp = getoffset(strp, &rulep->r_time); 1152 1.1 jtc } else rulep->r_time = 2 * SECSPERHOUR; /* default = 2:00:00 */ 1153 1.1 jtc return strp; 1154 1.1 jtc } 1155 1.1 jtc 1156 1.1 jtc /* 1157 1.81 christos ** Given a year, a rule, and the offset from UT at the time that rule takes 1158 1.81 christos ** effect, calculate the year-relative time that rule takes effect. 1159 1.1 jtc */ 1160 1.1 jtc 1161 1.109 christos static int_fast32_t 1162 1.130 rillig transtime(const int year, register const struct rule *const rulep, 1163 1.81 christos const int_fast32_t offset) 1164 1.49 christos { 1165 1.130 rillig register bool leapyear; 1166 1.130 rillig register int_fast32_t value; 1167 1.130 rillig register int i; 1168 1.1 jtc int d, m1, yy0, yy1, yy2, dow; 1169 1.1 jtc 1170 1.1 jtc leapyear = isleap(year); 1171 1.1 jtc switch (rulep->r_type) { 1172 1.1 jtc 1173 1.1 jtc case JULIAN_DAY: 1174 1.1 jtc /* 1175 1.1 jtc ** Jn - Julian day, 1 == January 1, 60 == March 1 even in leap 1176 1.1 jtc ** years. 1177 1.1 jtc ** In non-leap years, or if the day number is 59 or less, just 1178 1.1 jtc ** add SECSPERDAY times the day number-1 to the time of 1179 1.1 jtc ** January 1, midnight, to get the day. 1180 1.1 jtc */ 1181 1.81 christos value = (rulep->r_day - 1) * SECSPERDAY; 1182 1.1 jtc if (leapyear && rulep->r_day >= 60) 1183 1.1 jtc value += SECSPERDAY; 1184 1.1 jtc break; 1185 1.1 jtc 1186 1.1 jtc case DAY_OF_YEAR: 1187 1.1 jtc /* 1188 1.1 jtc ** n - day of year. 1189 1.1 jtc ** Just add SECSPERDAY times the day number to the time of 1190 1.1 jtc ** January 1, midnight, to get the day. 1191 1.1 jtc */ 1192 1.81 christos value = rulep->r_day * SECSPERDAY; 1193 1.1 jtc break; 1194 1.1 jtc 1195 1.1 jtc case MONTH_NTH_DAY_OF_WEEK: 1196 1.1 jtc /* 1197 1.1 jtc ** Mm.n.d - nth "dth day" of month m. 1198 1.1 jtc */ 1199 1.1 jtc 1200 1.1 jtc /* 1201 1.1 jtc ** Use Zeller's Congruence to get day-of-week of first day of 1202 1.1 jtc ** month. 1203 1.1 jtc */ 1204 1.1 jtc m1 = (rulep->r_mon + 9) % 12 + 1; 1205 1.1 jtc yy0 = (rulep->r_mon <= 2) ? (year - 1) : year; 1206 1.1 jtc yy1 = yy0 / 100; 1207 1.1 jtc yy2 = yy0 % 100; 1208 1.1 jtc dow = ((26 * m1 - 2) / 10 + 1209 1.1 jtc 1 + yy2 + yy2 / 4 + yy1 / 4 - 2 * yy1) % 7; 1210 1.1 jtc if (dow < 0) 1211 1.1 jtc dow += DAYSPERWEEK; 1212 1.1 jtc 1213 1.1 jtc /* 1214 1.45 mlelstv ** "dow" is the day-of-week of the first day of the month. Get 1215 1.1 jtc ** the day-of-month (zero-origin) of the first "dow" day of the 1216 1.1 jtc ** month. 1217 1.1 jtc */ 1218 1.1 jtc d = rulep->r_day - dow; 1219 1.1 jtc if (d < 0) 1220 1.1 jtc d += DAYSPERWEEK; 1221 1.1 jtc for (i = 1; i < rulep->r_week; ++i) { 1222 1.1 jtc if (d + DAYSPERWEEK >= 1223 1.1 jtc mon_lengths[leapyear][rulep->r_mon - 1]) 1224 1.1 jtc break; 1225 1.1 jtc d += DAYSPERWEEK; 1226 1.1 jtc } 1227 1.1 jtc 1228 1.1 jtc /* 1229 1.1 jtc ** "d" is the day-of-month (zero-origin) of the day we want. 1230 1.1 jtc */ 1231 1.81 christos value = d * SECSPERDAY; 1232 1.81 christos for (i = 0; i < rulep->r_mon - 1; ++i) 1233 1.81 christos value += mon_lengths[leapyear][i] * SECSPERDAY; 1234 1.1 jtc break; 1235 1.124 christos 1236 1.135 christos default: unreachable(); 1237 1.1 jtc } 1238 1.1 jtc 1239 1.1 jtc /* 1240 1.81 christos ** "value" is the year-relative time of 00:00:00 UT on the day in 1241 1.81 christos ** question. To get the year-relative time of the specified local 1242 1.1 jtc ** time on that day, add the transition time and the current offset 1243 1.78 christos ** from UT. 1244 1.1 jtc */ 1245 1.81 christos return value + rulep->r_time + offset; 1246 1.1 jtc } 1247 1.1 jtc 1248 1.1 jtc /* 1249 1.144 christos ** Given a POSIX.1 proleptic TZ string, fill in the rule tables as 1250 1.1 jtc ** appropriate. 1251 1.1 jtc */ 1252 1.1 jtc 1253 1.87 christos static bool 1254 1.139 christos tzparse(const char *name, struct state *sp, struct state const *basep) 1255 1.87 christos { 1256 1.131 rillig const char * stdname; 1257 1.131 rillig const char * dstname; 1258 1.131 rillig int_fast32_t stdoffset; 1259 1.131 rillig int_fast32_t dstoffset; 1260 1.130 rillig register char * cp; 1261 1.130 rillig register bool load_ok; 1262 1.136 christos ptrdiff_t stdlen, dstlen, charcnt; 1263 1.140 christos __time_t atlo = TIME_T_MIN, leaplo = TIME_T_MIN; 1264 1.1 jtc 1265 1.84 martin dstname = NULL; /* XXX gcc */ 1266 1.1 jtc stdname = name; 1267 1.124 christos if (*name == '<') { 1268 1.124 christos name++; 1269 1.124 christos stdname = name; 1270 1.124 christos name = getqzname(name, '>'); 1271 1.124 christos if (*name != '>') 1272 1.124 christos return false; 1273 1.124 christos stdlen = name - stdname; 1274 1.124 christos name++; 1275 1.1 jtc } else { 1276 1.124 christos name = getzname(name); 1277 1.124 christos stdlen = name - stdname; 1278 1.1 jtc } 1279 1.138 christos if (! (0 < stdlen && stdlen <= TZNAME_MAXIMUM)) 1280 1.124 christos return false; 1281 1.124 christos name = getoffset(name, &stdoffset); 1282 1.124 christos if (name == NULL) 1283 1.124 christos return false; 1284 1.96 christos charcnt = stdlen + 1; 1285 1.124 christos if (basep) { 1286 1.124 christos if (0 < basep->timecnt) 1287 1.124 christos atlo = basep->ats[basep->timecnt - 1]; 1288 1.124 christos load_ok = false; 1289 1.124 christos sp->leapcnt = basep->leapcnt; 1290 1.124 christos memcpy(sp->lsis, basep->lsis, sp->leapcnt * sizeof *sp->lsis); 1291 1.124 christos } else { 1292 1.145 christos load_ok = tzload(TZDEFRULES, sp, 0) == 0; 1293 1.124 christos if (!load_ok) 1294 1.124 christos sp->leapcnt = 0; /* So, we're off a little. */ 1295 1.124 christos } 1296 1.124 christos if (0 < sp->leapcnt) 1297 1.124 christos leaplo = sp->lsis[sp->leapcnt - 1].ls_trans; 1298 1.139 christos sp->goback = sp->goahead = false; 1299 1.1 jtc if (*name != '\0') { 1300 1.45 mlelstv if (*name == '<') { 1301 1.45 mlelstv dstname = ++name; 1302 1.45 mlelstv name = getqzname(name, '>'); 1303 1.45 mlelstv if (*name != '>') 1304 1.131 rillig return false; 1305 1.45 mlelstv dstlen = name - dstname; 1306 1.45 mlelstv name++; 1307 1.45 mlelstv } else { 1308 1.45 mlelstv dstname = name; 1309 1.45 mlelstv name = getzname(name); 1310 1.113 christos dstlen = name - dstname; /* length of DST abbr. */ 1311 1.45 mlelstv } 1312 1.138 christos if (! (0 < dstlen && dstlen <= TZNAME_MAXIMUM)) 1313 1.96 christos return false; 1314 1.96 christos charcnt += dstlen + 1; 1315 1.1 jtc if (*name != '\0' && *name != ',' && *name != ';') { 1316 1.45 mlelstv name = getoffset(name, &dstoffset); 1317 1.1 jtc if (name == NULL) 1318 1.87 christos return false; 1319 1.1 jtc } else dstoffset = stdoffset - SECSPERHOUR; 1320 1.87 christos if (*name == '\0' && !load_ok) 1321 1.22 kleink name = TZDEFRULESTRING; 1322 1.1 jtc if (*name == ',' || *name == ';') { 1323 1.1 jtc struct rule start; 1324 1.1 jtc struct rule end; 1325 1.130 rillig register int year; 1326 1.130 rillig register int timecnt; 1327 1.126 christos __time_t janfirst; 1328 1.106 christos int_fast32_t janoffset = 0; 1329 1.124 christos int yearbeg, yearlim; 1330 1.1 jtc 1331 1.1 jtc ++name; 1332 1.45 mlelstv if ((name = getrule(name, &start)) == NULL) 1333 1.131 rillig return false; 1334 1.1 jtc if (*name++ != ',') 1335 1.131 rillig return false; 1336 1.45 mlelstv if ((name = getrule(name, &end)) == NULL) 1337 1.131 rillig return false; 1338 1.1 jtc if (*name != '\0') 1339 1.131 rillig return false; 1340 1.1 jtc sp->typecnt = 2; /* standard time and DST */ 1341 1.1 jtc /* 1342 1.45 mlelstv ** Two transitions per year, from EPOCH_YEAR forward. 1343 1.1 jtc */ 1344 1.113 christos init_ttinfo(&sp->ttis[0], -stdoffset, false, 0); 1345 1.130 rillig init_ttinfo(&sp->ttis[1], -dstoffset, true, 1346 1.91 christos (int)(stdlen + 1)); 1347 1.81 christos timecnt = 0; 1348 1.1 jtc janfirst = 0; 1349 1.106 christos yearbeg = EPOCH_YEAR; 1350 1.106 christos 1351 1.106 christos do { 1352 1.106 christos int_fast32_t yearsecs 1353 1.106 christos = year_lengths[isleap(yearbeg - 1)] * SECSPERDAY; 1354 1.144 christos __time_t janfirst1 = janfirst; 1355 1.106 christos yearbeg--; 1356 1.144 christos if (increment_overflow_time(&janfirst1, -yearsecs)) { 1357 1.106 christos janoffset = -yearsecs; 1358 1.106 christos break; 1359 1.106 christos } 1360 1.144 christos janfirst = janfirst1; 1361 1.124 christos } while (atlo < janfirst 1362 1.124 christos && EPOCH_YEAR - YEARSPERREPEAT / 2 < yearbeg); 1363 1.124 christos 1364 1.140 christos for (;;) { 1365 1.124 christos int_fast32_t yearsecs 1366 1.124 christos = year_lengths[isleap(yearbeg)] * SECSPERDAY; 1367 1.124 christos int yearbeg1 = yearbeg; 1368 1.126 christos __time_t janfirst1 = janfirst; 1369 1.124 christos if (increment_overflow_time(&janfirst1, yearsecs) 1370 1.124 christos || increment_overflow(&yearbeg1, 1) 1371 1.124 christos || atlo <= janfirst1) 1372 1.124 christos break; 1373 1.124 christos yearbeg = yearbeg1; 1374 1.124 christos janfirst = janfirst1; 1375 1.124 christos } 1376 1.106 christos 1377 1.124 christos yearlim = yearbeg; 1378 1.141 christos if (increment_overflow(&yearlim, years_of_observations)) 1379 1.124 christos yearlim = INT_MAX; 1380 1.106 christos for (year = yearbeg; year < yearlim; year++) { 1381 1.81 christos int_fast32_t 1382 1.81 christos starttime = transtime(year, &start, stdoffset), 1383 1.81 christos endtime = transtime(year, &end, dstoffset); 1384 1.81 christos int_fast32_t 1385 1.81 christos yearsecs = (year_lengths[isleap(year)] 1386 1.81 christos * SECSPERDAY); 1387 1.87 christos bool reversed = endtime < starttime; 1388 1.81 christos if (reversed) { 1389 1.81 christos int_fast32_t swap = starttime; 1390 1.81 christos starttime = endtime; 1391 1.81 christos endtime = swap; 1392 1.81 christos } 1393 1.81 christos if (reversed 1394 1.78 christos || (starttime < endtime 1395 1.124 christos && endtime - starttime < yearsecs)) { 1396 1.81 christos if (TZ_MAX_TIMES - 2 < timecnt) 1397 1.78 christos break; 1398 1.81 christos sp->ats[timecnt] = janfirst; 1399 1.106 christos if (! increment_overflow_time 1400 1.106 christos (&sp->ats[timecnt], 1401 1.124 christos janoffset + starttime) 1402 1.124 christos && atlo <= sp->ats[timecnt]) 1403 1.113 christos sp->types[timecnt++] = !reversed; 1404 1.81 christos sp->ats[timecnt] = janfirst; 1405 1.106 christos if (! increment_overflow_time 1406 1.106 christos (&sp->ats[timecnt], 1407 1.124 christos janoffset + endtime) 1408 1.124 christos && atlo <= sp->ats[timecnt]) { 1409 1.113 christos sp->types[timecnt++] = reversed; 1410 1.113 christos } 1411 1.1 jtc } 1412 1.124 christos if (endtime < leaplo) { 1413 1.124 christos yearlim = year; 1414 1.124 christos if (increment_overflow(&yearlim, 1415 1.141 christos years_of_observations)) 1416 1.124 christos yearlim = INT_MAX; 1417 1.124 christos } 1418 1.106 christos if (increment_overflow_time 1419 1.106 christos (&janfirst, janoffset + yearsecs)) 1420 1.45 mlelstv break; 1421 1.106 christos janoffset = 0; 1422 1.1 jtc } 1423 1.81 christos sp->timecnt = timecnt; 1424 1.113 christos if (! timecnt) { 1425 1.113 christos sp->ttis[0] = sp->ttis[1]; 1426 1.78 christos sp->typecnt = 1; /* Perpetual DST. */ 1427 1.141 christos } else if (years_of_observations <= year - yearbeg) 1428 1.106 christos sp->goback = sp->goahead = true; 1429 1.1 jtc } else { 1430 1.130 rillig register int_fast32_t theirstdoffset; 1431 1.130 rillig register int_fast32_t theirdstoffset; 1432 1.130 rillig register int_fast32_t theiroffset; 1433 1.130 rillig register bool isdst; 1434 1.130 rillig register int i; 1435 1.130 rillig register int j; 1436 1.1 jtc 1437 1.1 jtc if (*name != '\0') 1438 1.131 rillig return false; 1439 1.1 jtc /* 1440 1.69 christos ** Initial values of theirstdoffset and theirdstoffset. 1441 1.1 jtc */ 1442 1.1 jtc theirstdoffset = 0; 1443 1.1 jtc for (i = 0; i < sp->timecnt; ++i) { 1444 1.1 jtc j = sp->types[i]; 1445 1.1 jtc if (!sp->ttis[j].tt_isdst) { 1446 1.5 jtc theirstdoffset = 1447 1.122 christos - sp->ttis[j].tt_utoff; 1448 1.1 jtc break; 1449 1.1 jtc } 1450 1.1 jtc } 1451 1.45 mlelstv theirdstoffset = 0; 1452 1.45 mlelstv for (i = 0; i < sp->timecnt; ++i) { 1453 1.45 mlelstv j = sp->types[i]; 1454 1.45 mlelstv if (sp->ttis[j].tt_isdst) { 1455 1.45 mlelstv theirdstoffset = 1456 1.122 christos - sp->ttis[j].tt_utoff; 1457 1.45 mlelstv break; 1458 1.45 mlelstv } 1459 1.45 mlelstv } 1460 1.1 jtc /* 1461 1.1 jtc ** Initially we're assumed to be in standard time. 1462 1.1 jtc */ 1463 1.87 christos isdst = false; 1464 1.1 jtc /* 1465 1.1 jtc ** Now juggle transition times and types 1466 1.1 jtc ** tracking offsets as you do. 1467 1.1 jtc */ 1468 1.1 jtc for (i = 0; i < sp->timecnt; ++i) { 1469 1.1 jtc j = sp->types[i]; 1470 1.1 jtc sp->types[i] = sp->ttis[j].tt_isdst; 1471 1.122 christos if (sp->ttis[j].tt_ttisut) { 1472 1.1 jtc /* No adjustment to transition time */ 1473 1.1 jtc } else { 1474 1.1 jtc /* 1475 1.112 christos ** If daylight saving time is in 1476 1.112 christos ** effect, and the transition time was 1477 1.112 christos ** not specified as standard time, add 1478 1.112 christos ** the daylight saving time offset to 1479 1.112 christos ** the transition time; otherwise, add 1480 1.112 christos ** the standard time offset to the 1481 1.112 christos ** transition time. 1482 1.1 jtc */ 1483 1.1 jtc /* 1484 1.1 jtc ** Transitions from DST to DDST 1485 1.1 jtc ** will effectively disappear since 1486 1.144 christos ** proleptic TZ strings have only one 1487 1.141 christos ** DST offset. 1488 1.1 jtc */ 1489 1.45 mlelstv if (isdst && !sp->ttis[j].tt_ttisstd) { 1490 1.66 christos sp->ats[i] += (time_t) 1491 1.66 christos (dstoffset - theirdstoffset); 1492 1.45 mlelstv } else { 1493 1.66 christos sp->ats[i] += (time_t) 1494 1.66 christos (stdoffset - theirstdoffset); 1495 1.45 mlelstv } 1496 1.1 jtc } 1497 1.122 christos theiroffset = -sp->ttis[j].tt_utoff; 1498 1.87 christos if (sp->ttis[j].tt_isdst) 1499 1.145 christos theirdstoffset = theiroffset; 1500 1.145 christos else theirstdoffset = theiroffset; 1501 1.1 jtc } 1502 1.1 jtc /* 1503 1.1 jtc ** Finally, fill in ttis. 1504 1.1 jtc */ 1505 1.91 christos init_ttinfo(&sp->ttis[0], -stdoffset, false, 0); 1506 1.91 christos init_ttinfo(&sp->ttis[1], -dstoffset, true, 1507 1.91 christos (int)(stdlen + 1)); 1508 1.7 jtc sp->typecnt = 2; 1509 1.1 jtc } 1510 1.1 jtc } else { 1511 1.1 jtc dstlen = 0; 1512 1.1 jtc sp->typecnt = 1; /* only standard time */ 1513 1.1 jtc sp->timecnt = 0; 1514 1.91 christos init_ttinfo(&sp->ttis[0], -stdoffset, false, 0); 1515 1.91 christos init_ttinfo(&sp->ttis[1], 0, false, 0); 1516 1.1 jtc } 1517 1.99 christos sp->charcnt = (int)charcnt; 1518 1.1 jtc cp = sp->chars; 1519 1.124 christos memcpy(cp, stdname, stdlen); 1520 1.1 jtc cp += stdlen; 1521 1.1 jtc *cp++ = '\0'; 1522 1.1 jtc if (dstlen != 0) { 1523 1.87 christos (void) memcpy(cp, dstname, dstlen); 1524 1.1 jtc *(cp + dstlen) = '\0'; 1525 1.1 jtc } 1526 1.87 christos return true; 1527 1.1 jtc } 1528 1.1 jtc 1529 1.1 jtc static void 1530 1.87 christos gmtload(struct state *const sp) 1531 1.49 christos { 1532 1.145 christos if (tzload(etc_utc, sp, TZLOAD_TZSTRING) != 0) 1533 1.134 christos (void)tzparse("UTC0", sp, NULL); 1534 1.49 christos } 1535 1.49 christos 1536 1.145 christos #if !USE_TIMEX_T || !defined TM_GMTOFF 1537 1.145 christos 1538 1.124 christos /* Initialize *SP to a value appropriate for the TZ setting NAME. 1539 1.145 christos Respect TZLOADFLAGS. 1540 1.124 christos Return 0 on success, an errno value on failure. */ 1541 1.91 christos static int 1542 1.145 christos zoneinit(struct state *sp, char const *name, char tzloadflags) 1543 1.49 christos { 1544 1.131 rillig if (name && ! name[0]) { 1545 1.131 rillig /* 1546 1.131 rillig ** User wants it fast rather than right. 1547 1.131 rillig */ 1548 1.131 rillig sp->leapcnt = 0; /* so, we're off a little */ 1549 1.131 rillig sp->timecnt = 0; 1550 1.131 rillig sp->typecnt = 1; 1551 1.131 rillig sp->charcnt = 0; 1552 1.131 rillig sp->goback = sp->goahead = false; 1553 1.131 rillig init_ttinfo(&sp->ttis[0], 0, false, 0); 1554 1.134 christos strcpy(sp->chars, utc); 1555 1.131 rillig return 0; 1556 1.131 rillig } else { 1557 1.145 christos int err = tzload(name, sp, tzloadflags); 1558 1.131 rillig if (err != 0 && name && name[0] != ':' && tzparse(name, sp, NULL)) 1559 1.131 rillig err = 0; 1560 1.131 rillig if (err == 0) 1561 1.138 christos err = scrub_abbrs(sp); 1562 1.131 rillig return err; 1563 1.131 rillig } 1564 1.49 christos } 1565 1.130 rillig 1566 1.19 kleink static void 1567 1.87 christos tzsetlcl(char const *name) 1568 1.1 jtc { 1569 1.131 rillig struct state *sp = __lclptr; 1570 1.131 rillig int lcl = name ? strlen(name) < sizeof lcl_TZname : -1; 1571 1.132 rillig if (lcl < 0 1572 1.132 rillig ? lcl_is_set < 0 1573 1.131 rillig : 0 < lcl_is_set && strcmp(lcl_TZname, name) == 0) 1574 1.131 rillig return; 1575 1.131 rillig 1576 1.145 christos # ifndef ALL_STATE 1577 1.131 rillig if (! sp) 1578 1.131 rillig __lclptr = sp = malloc(sizeof *__lclptr); 1579 1.145 christos # endif 1580 1.131 rillig if (sp) { 1581 1.145 christos if (zoneinit(sp, name, TZLOAD_FROMENV | TZLOAD_TZSTRING) != 0) { 1582 1.145 christos zoneinit(sp, "", 0); 1583 1.145 christos strcpy(sp->chars, UNSPEC); 1584 1.145 christos } 1585 1.131 rillig if (0 < lcl) 1586 1.131 rillig strcpy(lcl_TZname, name); 1587 1.131 rillig } 1588 1.131 rillig settzname(); 1589 1.131 rillig lcl_is_set = lcl; 1590 1.1 jtc } 1591 1.145 christos #endif 1592 1.145 christos 1593 1.145 christos #if !USE_TIMEX_T 1594 1.145 christos void 1595 1.145 christos tzset(void) 1596 1.145 christos { 1597 1.145 christos if (lock() != 0) 1598 1.145 christos return; 1599 1.145 christos tzset_unlocked(); 1600 1.145 christos unlock(); 1601 1.145 christos } 1602 1.1 jtc 1603 1.87 christos #ifdef STD_INSPIRED 1604 1.1 jtc void 1605 1.45 mlelstv tzsetwall(void) 1606 1.19 kleink { 1607 1.145 christos if (lock() != 0) 1608 1.145 christos return; 1609 1.87 christos tzsetlcl(NULL); 1610 1.145 christos unlock(); 1611 1.19 kleink } 1612 1.87 christos #endif 1613 1.87 christos 1614 1.117 christos void 1615 1.87 christos tzset_unlocked(void) 1616 1.87 christos { 1617 1.87 christos tzsetlcl(getenv("TZ")); 1618 1.87 christos } 1619 1.145 christos #endif 1620 1.1 jtc 1621 1.87 christos static void 1622 1.87 christos gmtcheck(void) 1623 1.87 christos { 1624 1.131 rillig static bool gmt_is_set; 1625 1.145 christos if (lock() != 0) 1626 1.145 christos return; 1627 1.131 rillig if (! gmt_is_set) { 1628 1.145 christos #ifdef ALL_STATE 1629 1.131 rillig gmtptr = malloc(sizeof *gmtptr); 1630 1.145 christos #endif 1631 1.131 rillig if (gmtptr) 1632 1.131 rillig gmtload(gmtptr); 1633 1.131 rillig gmt_is_set = true; 1634 1.131 rillig } 1635 1.145 christos unlock(); 1636 1.87 christos } 1637 1.1 jtc 1638 1.145 christos #if NETBSD_INSPIRED && !USE_TIMEX_T 1639 1.1 jtc 1640 1.87 christos timezone_t 1641 1.132 rillig tzalloc(char const *name) 1642 1.87 christos { 1643 1.131 rillig timezone_t sp = malloc(sizeof *sp); 1644 1.131 rillig if (sp) { 1645 1.145 christos int err = zoneinit(sp, name, TZLOAD_TZSTRING); 1646 1.131 rillig if (err != 0) { 1647 1.131 rillig free(sp); 1648 1.131 rillig errno = err; 1649 1.131 rillig return NULL; 1650 1.131 rillig } 1651 1.140 christos } else if (/*CONSTCOND*/!HAVE_MALLOC_ERRNO) 1652 1.140 christos /*NOTREACHED*/ 1653 1.131 rillig errno = ENOMEM; 1654 1.131 rillig return sp; 1655 1.1 jtc } 1656 1.1 jtc 1657 1.19 kleink void 1658 1.87 christos tzfree(timezone_t sp) 1659 1.19 kleink { 1660 1.131 rillig free(sp); 1661 1.19 kleink } 1662 1.19 kleink 1663 1.1 jtc /* 1664 1.144 christos ** NetBSD 6.1.4 has ctime_rz, but omit it because C23 deprecates ctime and 1665 1.144 christos ** POSIX.1-2024 removes ctime_r. Both have potential security problems that 1666 1.87 christos ** ctime_rz would share. Callers can instead use localtime_rz + strftime. 1667 1.87 christos ** 1668 1.87 christos ** NetBSD 6.1.4 has tzgetname, but omit it because it doesn't work 1669 1.87 christos ** in zones with three or more time zone abbreviations. 1670 1.87 christos ** Callers can instead use localtime_rz + strftime. 1671 1.87 christos */ 1672 1.87 christos 1673 1.87 christos #endif 1674 1.87 christos 1675 1.145 christos #if !USE_TIMEX_T || !defined TM_GMTOFF 1676 1.145 christos 1677 1.87 christos /* 1678 1.1 jtc ** The easy way to behave "as if no library function calls" localtime 1679 1.83 christos ** is to not call it, so we drop its guts into "localsub", which can be 1680 1.83 christos ** freely called. (And no, the PANS doesn't require the above behavior, 1681 1.1 jtc ** but it *is* desirable.) 1682 1.1 jtc ** 1683 1.93 christos ** If successful and SETNAME is nonzero, 1684 1.91 christos ** set the applicable parts of tzname, timezone and altzone; 1685 1.144 christos ** however, it's OK to omit this step for proleptic TZ strings 1686 1.91 christos ** since in that case tzset should have already done this step correctly. 1687 1.134 christos ** SETNAME's type is int_fast32_t for compatibility with gmtsub, 1688 1.93 christos ** but it is actually a boolean and its value should be 0 or 1. 1689 1.1 jtc */ 1690 1.1 jtc 1691 1.1 jtc /*ARGSUSED*/ 1692 1.45 mlelstv static struct tm * 1693 1.93 christos localsub(struct state const *sp, time_t const *timep, int_fast32_t setname, 1694 1.87 christos struct tm *const tmp) 1695 1.49 christos { 1696 1.130 rillig register const struct ttinfo * ttisp; 1697 1.130 rillig register int i; 1698 1.130 rillig register struct tm * result; 1699 1.1 jtc const time_t t = *timep; 1700 1.1 jtc 1701 1.87 christos if (sp == NULL) { 1702 1.131 rillig /* Don't bother to set tzname etc.; tzset has already done it. */ 1703 1.131 rillig return gmtsub(gmtptr, timep, 0, tmp); 1704 1.87 christos } 1705 1.45 mlelstv if ((sp->goback && t < sp->ats[0]) || 1706 1.45 mlelstv (sp->goahead && t > sp->ats[sp->timecnt - 1])) { 1707 1.131 rillig time_t newt; 1708 1.140 christos register __time_t seconds; 1709 1.130 rillig register time_t years; 1710 1.45 mlelstv 1711 1.45 mlelstv if (t < sp->ats[0]) 1712 1.45 mlelstv seconds = sp->ats[0] - t; 1713 1.45 mlelstv else seconds = t - sp->ats[sp->timecnt - 1]; 1714 1.45 mlelstv --seconds; 1715 1.124 christos 1716 1.124 christos /* Beware integer overflow, as SECONDS might 1717 1.124 christos be close to the maximum time_t. */ 1718 1.124 christos years = (time_t)(seconds / SECSPERREPEAT 1719 1.124 christos * YEARSPERREPEAT); 1720 1.78 christos seconds = (time_t)(years * AVGSECSPERYEAR); 1721 1.124 christos years += YEARSPERREPEAT; 1722 1.45 mlelstv if (t < sp->ats[0]) 1723 1.124 christos newt = (time_t)(t + seconds + SECSPERREPEAT); 1724 1.124 christos else 1725 1.124 christos newt = (time_t)(t - seconds - SECSPERREPEAT); 1726 1.124 christos 1727 1.45 mlelstv if (newt < sp->ats[0] || 1728 1.88 christos newt > sp->ats[sp->timecnt - 1]) { 1729 1.88 christos errno = EINVAL; 1730 1.88 christos return NULL; /* "cannot happen" */ 1731 1.88 christos } 1732 1.93 christos result = localsub(sp, &newt, setname, tmp); 1733 1.87 christos if (result) { 1734 1.145 christos # if defined ckd_add && defined ckd_sub 1735 1.136 christos if (t < sp->ats[0] 1736 1.136 christos ? ckd_sub(&result->tm_year, 1737 1.136 christos result->tm_year, years) 1738 1.136 christos : ckd_add(&result->tm_year, 1739 1.136 christos result->tm_year, years)) 1740 1.136 christos return NULL; 1741 1.145 christos # else 1742 1.130 rillig register int_fast64_t newy; 1743 1.45 mlelstv 1744 1.87 christos newy = result->tm_year; 1745 1.45 mlelstv if (t < sp->ats[0]) 1746 1.78 christos newy -= years; 1747 1.78 christos else newy += years; 1748 1.88 christos if (! (INT_MIN <= newy && newy <= INT_MAX)) { 1749 1.88 christos errno = EOVERFLOW; 1750 1.45 mlelstv return NULL; 1751 1.88 christos } 1752 1.87 christos result->tm_year = (int)newy; 1753 1.145 christos # endif 1754 1.45 mlelstv } 1755 1.45 mlelstv return result; 1756 1.1 jtc } 1757 1.1 jtc if (sp->timecnt == 0 || t < sp->ats[0]) { 1758 1.144 christos i = 0; 1759 1.1 jtc } else { 1760 1.130 rillig register int lo = 1; 1761 1.130 rillig register int hi = sp->timecnt; 1762 1.45 mlelstv 1763 1.45 mlelstv while (lo < hi) { 1764 1.130 rillig register int mid = (lo + hi) / 2; 1765 1.45 mlelstv 1766 1.45 mlelstv if (t < sp->ats[mid]) 1767 1.45 mlelstv hi = mid; 1768 1.45 mlelstv else lo = mid + 1; 1769 1.45 mlelstv } 1770 1.124 christos i = sp->types[lo - 1]; 1771 1.1 jtc } 1772 1.1 jtc ttisp = &sp->ttis[i]; 1773 1.1 jtc /* 1774 1.1 jtc ** To get (wrong) behavior that's compatible with System V Release 2.0 1775 1.1 jtc ** you'd replace the statement below with 1776 1.122 christos ** t += ttisp->tt_utoff; 1777 1.1 jtc ** timesub(&t, 0L, sp, tmp); 1778 1.1 jtc */ 1779 1.122 christos result = timesub(&t, ttisp->tt_utoff, sp, tmp); 1780 1.87 christos if (result) { 1781 1.131 rillig result->tm_isdst = ttisp->tt_isdst; 1782 1.145 christos # ifdef TM_ZONE 1783 1.145 christos result->TM_ZONE = UNCONST(&sp->chars[ttisp->tt_desigidx]); 1784 1.145 christos # endif 1785 1.131 rillig if (setname) 1786 1.131 rillig update_tzname_etc(sp, ttisp); 1787 1.87 christos } 1788 1.45 mlelstv return result; 1789 1.1 jtc } 1790 1.145 christos #endif 1791 1.1 jtc 1792 1.145 christos #if !USE_TIMEX_T 1793 1.49 christos 1794 1.145 christos # if NETBSD_INSPIRED 1795 1.1 jtc struct tm * 1796 1.138 christos localtime_rz(struct state *__restrict sp, time_t const *__restrict timep, 1797 1.138 christos struct tm *__restrict tmp) 1798 1.87 christos { 1799 1.131 rillig return localsub(sp, timep, 0, tmp); 1800 1.87 christos } 1801 1.145 christos # endif 1802 1.87 christos 1803 1.87 christos static struct tm * 1804 1.87 christos localtime_tzset(time_t const *timep, struct tm *tmp, bool setname) 1805 1.1 jtc { 1806 1.145 christos int err = lock(); 1807 1.145 christos if (err) { 1808 1.145 christos errno = err; 1809 1.145 christos return NULL; 1810 1.145 christos } 1811 1.131 rillig if (setname || !lcl_is_set) 1812 1.131 rillig tzset_unlocked(); 1813 1.131 rillig tmp = localsub(__lclptr, timep, setname, tmp); 1814 1.145 christos unlock(); 1815 1.131 rillig return tmp; 1816 1.1 jtc } 1817 1.1 jtc 1818 1.49 christos struct tm * 1819 1.96 christos localtime(const time_t *timep) 1820 1.49 christos { 1821 1.145 christos # if !SUPPORT_C89 1822 1.138 christos static struct tm tm; 1823 1.145 christos # endif 1824 1.131 rillig return localtime_tzset(timep, &tm, true); 1825 1.49 christos } 1826 1.35 kleink 1827 1.18 kleink struct tm * 1828 1.138 christos localtime_r(const time_t *__restrict timep, struct tm *__restrict tmp) 1829 1.18 kleink { 1830 1.145 christos return localtime_tzset(timep, tmp, false); 1831 1.18 kleink } 1832 1.145 christos #endif 1833 1.18 kleink 1834 1.18 kleink /* 1835 1.1 jtc ** gmtsub is to gmtime as localsub is to localtime. 1836 1.1 jtc */ 1837 1.1 jtc 1838 1.45 mlelstv static struct tm * 1839 1.136 christos gmtsub(ATTRIBUTE_MAYBE_UNUSED struct state const *sp, time_t const *timep, 1840 1.136 christos int_fast32_t offset, struct tm *tmp) 1841 1.1 jtc { 1842 1.130 rillig register struct tm * result; 1843 1.19 kleink 1844 1.87 christos result = timesub(timep, offset, gmtptr, tmp); 1845 1.1 jtc #ifdef TM_ZONE 1846 1.1 jtc /* 1847 1.1 jtc ** Could get fancy here and deliver something such as 1848 1.104 christos ** "+xx" or "-xx" if offset is non-zero, 1849 1.1 jtc ** but this is no time for a treasure hunt. 1850 1.1 jtc */ 1851 1.88 christos if (result) 1852 1.145 christos result->TM_ZONE = UNCONST(offset ? wildabbr : gmtptr ? 1853 1.145 christos gmtptr->chars : utc); 1854 1.1 jtc #endif /* defined TM_ZONE */ 1855 1.45 mlelstv return result; 1856 1.1 jtc } 1857 1.1 jtc 1858 1.145 christos #if !USE_TIMEX_T 1859 1.145 christos 1860 1.18 kleink /* 1861 1.131 rillig * Re-entrant version of gmtime. 1862 1.35 kleink */ 1863 1.35 kleink 1864 1.18 kleink struct tm * 1865 1.138 christos gmtime_r(time_t const *__restrict timep, struct tm *__restrict tmp) 1866 1.18 kleink { 1867 1.131 rillig gmtcheck(); 1868 1.131 rillig return gmtsub(NULL, timep, 0, tmp); 1869 1.18 kleink } 1870 1.18 kleink 1871 1.96 christos struct tm * 1872 1.96 christos gmtime(const time_t *timep) 1873 1.96 christos { 1874 1.145 christos # if !SUPPORT_C89 1875 1.138 christos static struct tm tm; 1876 1.145 christos # endif 1877 1.131 rillig return gmtime_r(timep, &tm); 1878 1.96 christos } 1879 1.124 christos 1880 1.145 christos # if STD_INSPIRED 1881 1.1 jtc 1882 1.139 christos /* This function is obsolescent and may disappear in future releases. 1883 1.139 christos Callers can instead use localtime_rz with a fixed-offset zone. */ 1884 1.139 christos 1885 1.1 jtc struct tm * 1886 1.96 christos offtime(const time_t *timep, long offset) 1887 1.1 jtc { 1888 1.131 rillig gmtcheck(); 1889 1.138 christos 1890 1.145 christos # if !SUPPORT_C89 1891 1.138 christos static struct tm tm; 1892 1.145 christos # endif 1893 1.131 rillig return gmtsub(gmtptr, timep, (int_fast32_t)offset, &tm); 1894 1.49 christos } 1895 1.49 christos 1896 1.49 christos struct tm * 1897 1.49 christos offtime_r(const time_t *timep, long offset, struct tm *tmp) 1898 1.49 christos { 1899 1.87 christos gmtcheck(); 1900 1.90 christos return gmtsub(NULL, timep, (int_fast32_t)offset, tmp); 1901 1.1 jtc } 1902 1.1 jtc 1903 1.105 christos # endif 1904 1.105 christos #endif 1905 1.105 christos 1906 1.45 mlelstv /* 1907 1.45 mlelstv ** Return the number of leap years through the end of the given year 1908 1.45 mlelstv ** where, to make the math easy, the answer for year zero is defined as zero. 1909 1.45 mlelstv */ 1910 1.132 rillig 1911 1.124 christos static time_t 1912 1.124 christos leaps_thru_end_of_nonneg(time_t y) 1913 1.109 christos { 1914 1.131 rillig return y / 4 - y / 100 + y / 400; 1915 1.109 christos } 1916 1.45 mlelstv 1917 1.124 christos static time_t 1918 1.132 rillig leaps_thru_end_of(time_t y) 1919 1.45 mlelstv { 1920 1.131 rillig return (y < 0 1921 1.131 rillig ? -1 - leaps_thru_end_of_nonneg(-1 - y) 1922 1.131 rillig : leaps_thru_end_of_nonneg(y)); 1923 1.45 mlelstv } 1924 1.45 mlelstv 1925 1.45 mlelstv static struct tm * 1926 1.96 christos timesub(const time_t *timep, int_fast32_t offset, 1927 1.131 rillig const struct state *sp, struct tm *tmp) 1928 1.49 christos { 1929 1.130 rillig register const struct lsinfo * lp; 1930 1.130 rillig register time_t tdays; 1931 1.130 rillig register const int * ip; 1932 1.130 rillig register int_fast32_t corr; 1933 1.130 rillig register int i; 1934 1.124 christos int_fast32_t idays, rem, dayoff, dayrem; 1935 1.124 christos time_t y; 1936 1.124 christos 1937 1.124 christos /* If less than SECSPERMIN, the number of seconds since the 1938 1.124 christos most recent positive leap second; otherwise, do not add 1 1939 1.124 christos to localtime tm_sec because of leap seconds. */ 1940 1.140 christos __time_t secs_since_posleap = SECSPERMIN; 1941 1.1 jtc 1942 1.1 jtc corr = 0; 1943 1.1 jtc i = (sp == NULL) ? 0 : sp->leapcnt; 1944 1.1 jtc while (--i >= 0) { 1945 1.1 jtc lp = &sp->lsis[i]; 1946 1.1 jtc if (*timep >= lp->ls_trans) { 1947 1.1 jtc corr = lp->ls_corr; 1948 1.124 christos if ((i == 0 ? 0 : lp[-1].ls_corr) < corr) 1949 1.124 christos secs_since_posleap = *timep - lp->ls_trans; 1950 1.1 jtc break; 1951 1.1 jtc } 1952 1.1 jtc } 1953 1.124 christos 1954 1.124 christos /* Calculate the year, avoiding integer overflow even if 1955 1.124 christos time_t is unsigned. */ 1956 1.66 christos tdays = (time_t)(*timep / SECSPERDAY); 1957 1.124 christos rem = (int)(*timep % SECSPERDAY); 1958 1.124 christos rem += offset % SECSPERDAY - corr % SECSPERDAY + 3 * SECSPERDAY; 1959 1.124 christos dayoff = offset / SECSPERDAY - corr / SECSPERDAY + rem / SECSPERDAY - 3; 1960 1.124 christos rem %= SECSPERDAY; 1961 1.124 christos /* y = (EPOCH_YEAR 1962 1.145 christos + floor((tdays + dayoff) / DAYSPERREPEAT) * YEARSPERREPEAT), 1963 1.124 christos sans overflow. But calculate against 1570 (EPOCH_YEAR - 1964 1.124 christos YEARSPERREPEAT) instead of against 1970 so that things work 1965 1.124 christos for localtime values before 1970 when time_t is unsigned. */ 1966 1.124 christos dayrem = (int)(tdays % DAYSPERREPEAT); 1967 1.124 christos dayrem += dayoff % DAYSPERREPEAT; 1968 1.143 christos y = (time_t)(EPOCH_YEAR - YEARSPERREPEAT 1969 1.124 christos + ((1 + dayoff / DAYSPERREPEAT + dayrem / DAYSPERREPEAT 1970 1.124 christos - ((dayrem % DAYSPERREPEAT) < 0) 1971 1.124 christos + tdays / DAYSPERREPEAT) 1972 1.124 christos * YEARSPERREPEAT)); 1973 1.124 christos /* idays = (tdays + dayoff) mod DAYSPERREPEAT, sans overflow. */ 1974 1.124 christos idays = (int)(tdays % DAYSPERREPEAT); 1975 1.142 christos idays += (dayoff % DAYSPERREPEAT + 2 * DAYSPERREPEAT); 1976 1.124 christos idays %= DAYSPERREPEAT; 1977 1.124 christos /* Increase Y and decrease IDAYS until IDAYS is in range for Y. */ 1978 1.124 christos while (year_lengths[isleap(y)] <= idays) { 1979 1.142 christos int_fast32_t tdelta = idays / DAYSPERLYEAR; 1980 1.124 christos int_fast32_t ydelta = tdelta + !tdelta; 1981 1.143 christos time_t newy = (time_t)(y + ydelta); 1982 1.130 rillig register int leapdays; 1983 1.124 christos leapdays = (int)(leaps_thru_end_of(newy - 1) - 1984 1.124 christos leaps_thru_end_of(y - 1)); 1985 1.124 christos idays -= ydelta * DAYSPERNYEAR; 1986 1.124 christos idays -= leapdays; 1987 1.45 mlelstv y = newy; 1988 1.45 mlelstv } 1989 1.124 christos 1990 1.136 christos #ifdef ckd_add 1991 1.136 christos if (ckd_add(&tmp->tm_year, y, -TM_YEAR_BASE)) { 1992 1.136 christos errno = EOVERFLOW; 1993 1.136 christos return NULL; 1994 1.136 christos } 1995 1.136 christos #else 1996 1.124 christos if (!TYPE_SIGNED(time_t) && y < TM_YEAR_BASE) { 1997 1.124 christos int signed_y = (int)y; 1998 1.124 christos tmp->tm_year = signed_y - TM_YEAR_BASE; 1999 1.124 christos } else if ((!TYPE_SIGNED(time_t) || INT_MIN + TM_YEAR_BASE <= y) 2000 1.124 christos && y - TM_YEAR_BASE <= INT_MAX) 2001 1.124 christos tmp->tm_year = (int)(y - TM_YEAR_BASE); 2002 1.124 christos else { 2003 1.124 christos errno = EOVERFLOW; 2004 1.124 christos return NULL; 2005 1.45 mlelstv } 2006 1.136 christos #endif 2007 1.142 christos tmp->tm_yday = (int)idays; 2008 1.45 mlelstv /* 2009 1.45 mlelstv ** The "extra" mods below avoid overflow problems. 2010 1.45 mlelstv */ 2011 1.124 christos tmp->tm_wday = (int)(TM_WDAY_BASE 2012 1.124 christos + ((tmp->tm_year % DAYSPERWEEK) 2013 1.124 christos * (DAYSPERNYEAR % DAYSPERWEEK)) 2014 1.124 christos + leaps_thru_end_of(y - 1) 2015 1.124 christos - leaps_thru_end_of(TM_YEAR_BASE - 1) 2016 1.124 christos + idays); 2017 1.45 mlelstv tmp->tm_wday %= DAYSPERWEEK; 2018 1.45 mlelstv if (tmp->tm_wday < 0) 2019 1.45 mlelstv tmp->tm_wday += DAYSPERWEEK; 2020 1.1 jtc tmp->tm_hour = (int) (rem / SECSPERHOUR); 2021 1.45 mlelstv rem %= SECSPERHOUR; 2022 1.142 christos tmp->tm_min = (int)(rem / SECSPERMIN); 2023 1.142 christos tmp->tm_sec = (int)(rem % SECSPERMIN); 2024 1.124 christos 2025 1.124 christos /* Use "... ??:??:60" at the end of the localtime minute containing 2026 1.124 christos the second just before the positive leap second. */ 2027 1.124 christos tmp->tm_sec += secs_since_posleap <= tmp->tm_sec; 2028 1.124 christos 2029 1.45 mlelstv ip = mon_lengths[isleap(y)]; 2030 1.45 mlelstv for (tmp->tm_mon = 0; idays >= ip[tmp->tm_mon]; ++(tmp->tm_mon)) 2031 1.45 mlelstv idays -= ip[tmp->tm_mon]; 2032 1.142 christos tmp->tm_mday = (int)(idays + 1); 2033 1.1 jtc tmp->tm_isdst = 0; 2034 1.1 jtc #ifdef TM_GMTOFF 2035 1.1 jtc tmp->TM_GMTOFF = offset; 2036 1.1 jtc #endif /* defined TM_GMTOFF */ 2037 1.45 mlelstv return tmp; 2038 1.1 jtc } 2039 1.1 jtc 2040 1.1 jtc /* 2041 1.1 jtc ** Adapted from code provided by Robert Elz, who writes: 2042 1.1 jtc ** The "best" way to do mktime I think is based on an idea of Bob 2043 1.7 jtc ** Kridle's (so its said...) from a long time ago. 2044 1.45 mlelstv ** It does a binary search of the time_t space. Since time_t's are 2045 1.1 jtc ** just 32 bits, its a max of 32 iterations (even at 64 bits it 2046 1.1 jtc ** would still be very reasonable). 2047 1.1 jtc */ 2048 1.1 jtc 2049 1.1 jtc #ifndef WRONG 2050 1.134 christos # define WRONG ((time_t)-1) 2051 1.1 jtc #endif /* !defined WRONG */ 2052 1.1 jtc 2053 1.1 jtc /* 2054 1.87 christos ** Normalize logic courtesy Paul Eggert. 2055 1.1 jtc */ 2056 1.1 jtc 2057 1.87 christos static bool 2058 1.96 christos increment_overflow(int *ip, int j) 2059 1.1 jtc { 2060 1.136 christos #ifdef ckd_add 2061 1.136 christos return ckd_add(ip, *ip, j); 2062 1.136 christos #else 2063 1.130 rillig register int const i = *ip; 2064 1.1 jtc 2065 1.58 christos /* 2066 1.58 christos ** If i >= 0 there can only be overflow if i + j > INT_MAX 2067 1.58 christos ** or if j > INT_MAX - i; given i >= 0, INT_MAX - i cannot overflow. 2068 1.58 christos ** If i < 0 there can only be overflow if i + j < INT_MIN 2069 1.58 christos ** or if j < INT_MIN - i; given i < 0, INT_MIN - i cannot overflow. 2070 1.58 christos */ 2071 1.58 christos if ((i >= 0) ? (j > INT_MAX - i) : (j < INT_MIN - i)) 2072 1.87 christos return true; 2073 1.58 christos *ip += j; 2074 1.87 christos return false; 2075 1.136 christos #endif 2076 1.1 jtc } 2077 1.1 jtc 2078 1.87 christos static bool 2079 1.145 christos increment_overflow_time_iinntt(time_t *tp, iinntt j) 2080 1.45 mlelstv { 2081 1.136 christos #ifdef ckd_add 2082 1.145 christos return ckd_add(tp, *tp, j); 2083 1.136 christos #else 2084 1.145 christos if (j < 0 2085 1.145 christos ? (TYPE_SIGNED(time_t) ? *tp < TIME_T_MIN - j : *tp <= -1 - j) 2086 1.145 christos : TIME_T_MAX - j < *tp) 2087 1.145 christos return true; 2088 1.145 christos *tp += j; 2089 1.145 christos return false; 2090 1.136 christos #endif 2091 1.45 mlelstv } 2092 1.45 mlelstv 2093 1.87 christos static bool 2094 1.126 christos increment_overflow_time(__time_t *tp, int_fast32_t j) 2095 1.81 christos { 2096 1.136 christos #ifdef ckd_add 2097 1.136 christos return ckd_add(tp, *tp, j); 2098 1.136 christos #else 2099 1.81 christos /* 2100 1.81 christos ** This is like 2101 1.109 christos ** 'if (! (TIME_T_MIN <= *tp + j && *tp + j <= TIME_T_MAX)) ...', 2102 1.81 christos ** except that it does the right thing even if *tp + j would overflow. 2103 1.81 christos */ 2104 1.81 christos if (! (j < 0 2105 1.109 christos ? (TYPE_SIGNED(time_t) ? TIME_T_MIN - j <= *tp : -1 - j < *tp) 2106 1.109 christos : *tp <= TIME_T_MAX - j)) 2107 1.87 christos return true; 2108 1.81 christos *tp += j; 2109 1.87 christos return false; 2110 1.136 christos #endif 2111 1.81 christos } 2112 1.81 christos 2113 1.45 mlelstv static int 2114 1.130 rillig tmcomp(register const struct tm *const atmp, 2115 1.130 rillig register const struct tm *const btmp) 2116 1.1 jtc { 2117 1.130 rillig register int result; 2118 1.1 jtc 2119 1.78 christos if (atmp->tm_year != btmp->tm_year) 2120 1.78 christos return atmp->tm_year < btmp->tm_year ? -1 : 1; 2121 1.78 christos if ((result = (atmp->tm_mon - btmp->tm_mon)) == 0 && 2122 1.1 jtc (result = (atmp->tm_mday - btmp->tm_mday)) == 0 && 2123 1.1 jtc (result = (atmp->tm_hour - btmp->tm_hour)) == 0 && 2124 1.1 jtc (result = (atmp->tm_min - btmp->tm_min)) == 0) 2125 1.1 jtc result = atmp->tm_sec - btmp->tm_sec; 2126 1.1 jtc return result; 2127 1.1 jtc } 2128 1.1 jtc 2129 1.136 christos /* Copy to *DEST from *SRC. Copy only the members needed for mktime, 2130 1.136 christos as other members might not be initialized. */ 2131 1.136 christos static void 2132 1.136 christos mktmcpy(struct tm *dest, struct tm const *src) 2133 1.136 christos { 2134 1.136 christos dest->tm_sec = src->tm_sec; 2135 1.136 christos dest->tm_min = src->tm_min; 2136 1.136 christos dest->tm_hour = src->tm_hour; 2137 1.136 christos dest->tm_mday = src->tm_mday; 2138 1.136 christos dest->tm_mon = src->tm_mon; 2139 1.136 christos dest->tm_year = src->tm_year; 2140 1.136 christos dest->tm_isdst = src->tm_isdst; 2141 1.136 christos #if defined TM_GMTOFF && ! UNINIT_TRAP 2142 1.136 christos dest->TM_GMTOFF = src->TM_GMTOFF; 2143 1.136 christos #endif 2144 1.136 christos } 2145 1.136 christos 2146 1.1 jtc static time_t 2147 1.87 christos time2sub(struct tm *const tmp, 2148 1.87 christos struct tm *(*funcp)(struct state const *, time_t const *, 2149 1.87 christos int_fast32_t, struct tm *), 2150 1.87 christos struct state const *sp, 2151 1.131 rillig const int_fast32_t offset, 2152 1.87 christos bool *okayp, 2153 1.87 christos bool do_norm_secs) 2154 1.49 christos { 2155 1.130 rillig register int dir; 2156 1.130 rillig register int i, j; 2157 1.130 rillig register time_t lo; 2158 1.130 rillig register time_t hi; 2159 1.61 christos #ifdef NO_ERROR_IN_DST_GAP 2160 1.132 rillig time_t ilo; 2161 1.61 christos #endif 2162 1.145 christos iinntt y, mday, hour, min, saved_seconds; 2163 1.131 rillig time_t newt; 2164 1.131 rillig time_t t; 2165 1.131 rillig struct tm yourtm, mytm; 2166 1.1 jtc 2167 1.87 christos *okayp = false; 2168 1.136 christos mktmcpy(&yourtm, tmp); 2169 1.136 christos 2170 1.64 christos #ifdef NO_ERROR_IN_DST_GAP 2171 1.64 christos again: 2172 1.64 christos #endif 2173 1.145 christos min = yourtm.tm_min; 2174 1.13 jtc if (do_norm_secs) { 2175 1.145 christos min += yourtm.tm_sec / SECSPERMIN; 2176 1.145 christos yourtm.tm_sec %= SECSPERMIN; 2177 1.145 christos if (yourtm.tm_sec < 0) { 2178 1.145 christos yourtm.tm_sec += SECSPERMIN; 2179 1.145 christos min--; 2180 1.145 christos } 2181 1.145 christos } 2182 1.145 christos 2183 1.145 christos hour = yourtm.tm_hour; 2184 1.145 christos hour += min / MINSPERHOUR; 2185 1.145 christos yourtm.tm_min = min % MINSPERHOUR; 2186 1.145 christos if (yourtm.tm_min < 0) { 2187 1.145 christos yourtm.tm_min += MINSPERHOUR; 2188 1.145 christos hour--; 2189 1.145 christos } 2190 1.145 christos 2191 1.145 christos mday = yourtm.tm_mday; 2192 1.145 christos mday += hour / HOURSPERDAY; 2193 1.145 christos yourtm.tm_hour = hour % HOURSPERDAY; 2194 1.145 christos if (yourtm.tm_hour < 0) { 2195 1.145 christos yourtm.tm_hour += HOURSPERDAY; 2196 1.145 christos mday--; 2197 1.13 jtc } 2198 1.45 mlelstv y = yourtm.tm_year; 2199 1.145 christos y += yourtm.tm_mon / MONSPERYEAR; 2200 1.145 christos yourtm.tm_mon %= MONSPERYEAR; 2201 1.145 christos if (yourtm.tm_mon < 0) { 2202 1.145 christos yourtm.tm_mon += MONSPERYEAR; 2203 1.145 christos y--; 2204 1.145 christos } 2205 1.145 christos 2206 1.1 jtc /* 2207 1.45 mlelstv ** Turn y into an actual year number for now. 2208 1.1 jtc ** It is converted back to an offset from TM_YEAR_BASE later. 2209 1.1 jtc */ 2210 1.145 christos y += TM_YEAR_BASE; 2211 1.145 christos 2212 1.145 christos while (mday <= 0) { 2213 1.145 christos iinntt li = y - (yourtm.tm_mon <= 1); 2214 1.145 christos mday += year_lengths[isleap(li)]; 2215 1.145 christos y--; 2216 1.145 christos } 2217 1.145 christos while (DAYSPERLYEAR < mday) { 2218 1.145 christos iinntt li = y + (1 < yourtm.tm_mon); 2219 1.145 christos mday -= year_lengths[isleap(li)]; 2220 1.145 christos y++; 2221 1.1 jtc } 2222 1.145 christos yourtm.tm_mday = (int)mday; 2223 1.1 jtc for ( ; ; ) { 2224 1.45 mlelstv i = mon_lengths[isleap(y)][yourtm.tm_mon]; 2225 1.1 jtc if (yourtm.tm_mday <= i) 2226 1.1 jtc break; 2227 1.1 jtc yourtm.tm_mday -= i; 2228 1.1 jtc if (++yourtm.tm_mon >= MONSPERYEAR) { 2229 1.1 jtc yourtm.tm_mon = 0; 2230 1.145 christos y++; 2231 1.1 jtc } 2232 1.1 jtc } 2233 1.136 christos #ifdef ckd_add 2234 1.136 christos if (ckd_add(&yourtm.tm_year, y, -TM_YEAR_BASE)) 2235 1.145 christos goto out_of_range; 2236 1.136 christos #else 2237 1.145 christos y -= TM_YEAR_BASE; 2238 1.87 christos if (! (INT_MIN <= y && y <= INT_MAX)) 2239 1.91 christos goto out_of_range; 2240 1.66 christos yourtm.tm_year = (int)y; 2241 1.136 christos #endif 2242 1.29 kleink if (yourtm.tm_sec >= 0 && yourtm.tm_sec < SECSPERMIN) 2243 1.29 kleink saved_seconds = 0; 2244 1.136 christos else if (yourtm.tm_year + TM_YEAR_BASE < EPOCH_YEAR) { 2245 1.1 jtc /* 2246 1.1 jtc ** We can't set tm_sec to 0, because that might push the 2247 1.1 jtc ** time below the minimum representable time. 2248 1.1 jtc ** Set tm_sec to 59 instead. 2249 1.1 jtc ** This assumes that the minimum representable time is 2250 1.1 jtc ** not in the same minute that a leap second was deleted from, 2251 1.1 jtc ** which is a safer assumption than using 58 would be. 2252 1.1 jtc */ 2253 1.145 christos saved_seconds = yourtm.tm_sec; 2254 1.145 christos saved_seconds -= SECSPERMIN - 1; 2255 1.1 jtc yourtm.tm_sec = SECSPERMIN - 1; 2256 1.1 jtc } else { 2257 1.1 jtc saved_seconds = yourtm.tm_sec; 2258 1.1 jtc yourtm.tm_sec = 0; 2259 1.1 jtc } 2260 1.1 jtc /* 2261 1.45 mlelstv ** Do a binary search (this works whatever time_t's type is). 2262 1.1 jtc */ 2263 1.109 christos lo = TIME_T_MIN; 2264 1.109 christos hi = TIME_T_MAX; 2265 1.61 christos #ifdef NO_ERROR_IN_DST_GAP 2266 1.61 christos ilo = lo; 2267 1.61 christos #endif 2268 1.1 jtc for ( ; ; ) { 2269 1.45 mlelstv t = lo / 2 + hi / 2; 2270 1.45 mlelstv if (t < lo) 2271 1.45 mlelstv t = lo; 2272 1.45 mlelstv else if (t > hi) 2273 1.45 mlelstv t = hi; 2274 1.87 christos if (! funcp(sp, &t, offset, &mytm)) { 2275 1.45 mlelstv /* 2276 1.45 mlelstv ** Assume that t is too extreme to be represented in 2277 1.45 mlelstv ** a struct tm; arrange things so that it is less 2278 1.45 mlelstv ** extreme on the next pass. 2279 1.45 mlelstv */ 2280 1.45 mlelstv dir = (t > 0) ? 1 : -1; 2281 1.45 mlelstv } else dir = tmcomp(&mytm, &yourtm); 2282 1.1 jtc if (dir != 0) { 2283 1.45 mlelstv if (t == lo) { 2284 1.109 christos if (t == TIME_T_MAX) 2285 1.91 christos goto out_of_range; 2286 1.45 mlelstv ++t; 2287 1.45 mlelstv ++lo; 2288 1.45 mlelstv } else if (t == hi) { 2289 1.109 christos if (t == TIME_T_MIN) 2290 1.91 christos goto out_of_range; 2291 1.45 mlelstv --t; 2292 1.45 mlelstv --hi; 2293 1.45 mlelstv } 2294 1.59 christos #ifdef NO_ERROR_IN_DST_GAP 2295 1.64 christos if (ilo != lo && lo - 1 == hi && yourtm.tm_isdst < 0 && 2296 1.64 christos do_norm_secs) { 2297 1.59 christos for (i = sp->typecnt - 1; i >= 0; --i) { 2298 1.59 christos for (j = sp->typecnt - 1; j >= 0; --j) { 2299 1.64 christos time_t off; 2300 1.59 christos if (sp->ttis[j].tt_isdst == 2301 1.59 christos sp->ttis[i].tt_isdst) 2302 1.59 christos continue; 2303 1.129 christos if (ttunspecified(sp, j)) 2304 1.129 christos continue; 2305 1.122 christos off = sp->ttis[j].tt_utoff - 2306 1.122 christos sp->ttis[i].tt_utoff; 2307 1.64 christos yourtm.tm_sec += off < 0 ? 2308 1.64 christos -off : off; 2309 1.64 christos goto again; 2310 1.59 christos } 2311 1.59 christos } 2312 1.59 christos } 2313 1.59 christos #endif 2314 1.45 mlelstv if (lo > hi) 2315 1.60 christos goto invalid; 2316 1.45 mlelstv if (dir > 0) 2317 1.45 mlelstv hi = t; 2318 1.45 mlelstv else lo = t; 2319 1.1 jtc continue; 2320 1.1 jtc } 2321 1.87 christos #if defined TM_GMTOFF && ! UNINIT_TRAP 2322 1.87 christos if (mytm.TM_GMTOFF != yourtm.TM_GMTOFF 2323 1.87 christos && (yourtm.TM_GMTOFF < 0 2324 1.87 christos ? (-SECSPERDAY <= yourtm.TM_GMTOFF 2325 1.87 christos && (mytm.TM_GMTOFF <= 2326 1.140 christos /*CONSTCOND*/ 2327 1.134 christos (min(INT_FAST32_MAX, LONG_MAX) 2328 1.87 christos + yourtm.TM_GMTOFF))) 2329 1.87 christos : (yourtm.TM_GMTOFF <= SECSPERDAY 2330 1.140 christos /*CONSTCOND*/ 2331 1.134 christos && ((max(INT_FAST32_MIN, LONG_MIN) 2332 1.87 christos + yourtm.TM_GMTOFF) 2333 1.87 christos <= mytm.TM_GMTOFF)))) { 2334 1.111 christos /* MYTM matches YOURTM except with the wrong UT offset. 2335 1.87 christos YOURTM.TM_GMTOFF is plausible, so try it instead. 2336 1.87 christos It's OK if YOURTM.TM_GMTOFF contains uninitialized data, 2337 1.87 christos since the guess gets checked. */ 2338 1.126 christos __time_t altt = t; 2339 1.87 christos int_fast32_t diff = (int_fast32_t) 2340 1.87 christos (mytm.TM_GMTOFF - yourtm.TM_GMTOFF); 2341 1.87 christos if (!increment_overflow_time(&altt, diff)) { 2342 1.87 christos struct tm alttm; 2343 1.126 christos time_t xaltt = (time_t)altt; 2344 1.126 christos if (funcp(sp, &xaltt, offset, &alttm) 2345 1.87 christos && alttm.tm_isdst == mytm.tm_isdst 2346 1.87 christos && alttm.TM_GMTOFF == yourtm.TM_GMTOFF 2347 1.124 christos && tmcomp(&alttm, &yourtm) == 0) { 2348 1.126 christos t = xaltt; 2349 1.87 christos mytm = alttm; 2350 1.87 christos } 2351 1.87 christos } 2352 1.87 christos } 2353 1.87 christos #endif 2354 1.1 jtc if (yourtm.tm_isdst < 0 || mytm.tm_isdst == yourtm.tm_isdst) 2355 1.1 jtc break; 2356 1.1 jtc /* 2357 1.1 jtc ** Right time, wrong type. 2358 1.1 jtc ** Hunt for right time, right type. 2359 1.1 jtc ** It's okay to guess wrong since the guess 2360 1.1 jtc ** gets checked. 2361 1.1 jtc */ 2362 1.1 jtc if (sp == NULL) 2363 1.60 christos goto invalid; 2364 1.5 jtc for (i = sp->typecnt - 1; i >= 0; --i) { 2365 1.1 jtc if (sp->ttis[i].tt_isdst != yourtm.tm_isdst) 2366 1.1 jtc continue; 2367 1.5 jtc for (j = sp->typecnt - 1; j >= 0; --j) { 2368 1.1 jtc if (sp->ttis[j].tt_isdst == yourtm.tm_isdst) 2369 1.1 jtc continue; 2370 1.145 christos if (ttunspecified(sp, j)) 2371 1.145 christos continue; 2372 1.122 christos newt = (time_t)(t + sp->ttis[j].tt_utoff - 2373 1.122 christos sp->ttis[i].tt_utoff); 2374 1.87 christos if (! funcp(sp, &newt, offset, &mytm)) 2375 1.45 mlelstv continue; 2376 1.1 jtc if (tmcomp(&mytm, &yourtm) != 0) 2377 1.1 jtc continue; 2378 1.1 jtc if (mytm.tm_isdst != yourtm.tm_isdst) 2379 1.1 jtc continue; 2380 1.1 jtc /* 2381 1.1 jtc ** We have a match. 2382 1.1 jtc */ 2383 1.1 jtc t = newt; 2384 1.1 jtc goto label; 2385 1.1 jtc } 2386 1.1 jtc } 2387 1.60 christos goto invalid; 2388 1.1 jtc } 2389 1.1 jtc label: 2390 1.145 christos if (increment_overflow_time_iinntt(&t, saved_seconds)) 2391 1.145 christos return WRONG; 2392 1.87 christos if (funcp(sp, &t, offset, tmp)) { 2393 1.87 christos *okayp = true; 2394 1.51 christos return t; 2395 1.60 christos } 2396 1.91 christos out_of_range: 2397 1.60 christos errno = EOVERFLOW; 2398 1.60 christos return WRONG; 2399 1.60 christos invalid: 2400 1.60 christos errno = EINVAL; 2401 1.60 christos return WRONG; 2402 1.13 jtc } 2403 1.13 jtc 2404 1.13 jtc static time_t 2405 1.87 christos time2(struct tm * const tmp, 2406 1.87 christos struct tm *(*funcp)(struct state const *, time_t const *, 2407 1.87 christos int_fast32_t, struct tm *), 2408 1.87 christos struct state const *sp, 2409 1.87 christos const int_fast32_t offset, 2410 1.87 christos bool *okayp) 2411 1.13 jtc { 2412 1.13 jtc time_t t; 2413 1.13 jtc 2414 1.13 jtc /* 2415 1.13 jtc ** First try without normalization of seconds 2416 1.13 jtc ** (in case tm_sec contains a value associated with a leap second). 2417 1.13 jtc ** If that fails, try with normalization of seconds. 2418 1.13 jtc */ 2419 1.87 christos t = time2sub(tmp, funcp, sp, offset, okayp, false); 2420 1.87 christos return *okayp ? t : time2sub(tmp, funcp, sp, offset, okayp, true); 2421 1.1 jtc } 2422 1.1 jtc 2423 1.1 jtc static time_t 2424 1.87 christos time1(struct tm *const tmp, 2425 1.124 christos struct tm *(*funcp)(struct state const *, time_t const *, 2426 1.124 christos int_fast32_t, struct tm *), 2427 1.87 christos struct state const *sp, 2428 1.87 christos const int_fast32_t offset) 2429 1.49 christos { 2430 1.130 rillig register time_t t; 2431 1.130 rillig register int samei, otheri; 2432 1.130 rillig register int sameind, otherind; 2433 1.130 rillig register int i; 2434 1.130 rillig register int nseen; 2435 1.130 rillig int save_errno; 2436 1.83 christos char seen[TZ_MAX_TYPES]; 2437 1.83 christos unsigned char types[TZ_MAX_TYPES]; 2438 1.87 christos bool okay; 2439 1.1 jtc 2440 1.58 christos if (tmp == NULL) { 2441 1.58 christos errno = EINVAL; 2442 1.58 christos return WRONG; 2443 1.58 christos } 2444 1.1 jtc if (tmp->tm_isdst > 1) 2445 1.1 jtc tmp->tm_isdst = 1; 2446 1.90 christos save_errno = errno; 2447 1.87 christos t = time2(tmp, funcp, sp, offset, &okay); 2448 1.90 christos if (okay) { 2449 1.90 christos errno = save_errno; 2450 1.1 jtc return t; 2451 1.90 christos } 2452 1.1 jtc if (tmp->tm_isdst < 0) 2453 1.82 christos #ifdef PCTS 2454 1.82 christos /* 2455 1.82 christos ** POSIX Conformance Test Suite code courtesy Grant Sullivan. 2456 1.82 christos */ 2457 1.1 jtc tmp->tm_isdst = 0; /* reset to std and try again */ 2458 1.82 christos #else 2459 1.1 jtc return t; 2460 1.1 jtc #endif /* !defined PCTS */ 2461 1.1 jtc /* 2462 1.1 jtc ** We're supposed to assume that somebody took a time of one type 2463 1.1 jtc ** and did some math on it that yielded a "struct tm" that's bad. 2464 1.1 jtc ** We try to divine the type they started from and adjust to the 2465 1.1 jtc ** type they need. 2466 1.1 jtc */ 2467 1.60 christos if (sp == NULL) { 2468 1.60 christos errno = EINVAL; 2469 1.1 jtc return WRONG; 2470 1.60 christos } 2471 1.35 kleink for (i = 0; i < sp->typecnt; ++i) 2472 1.87 christos seen[i] = false; 2473 1.35 kleink nseen = 0; 2474 1.35 kleink for (i = sp->timecnt - 1; i >= 0; --i) 2475 1.129 christos if (!seen[sp->types[i]] && !ttunspecified(sp, sp->types[i])) { 2476 1.87 christos seen[sp->types[i]] = true; 2477 1.35 kleink types[nseen++] = sp->types[i]; 2478 1.35 kleink } 2479 1.35 kleink for (sameind = 0; sameind < nseen; ++sameind) { 2480 1.35 kleink samei = types[sameind]; 2481 1.1 jtc if (sp->ttis[samei].tt_isdst != tmp->tm_isdst) 2482 1.1 jtc continue; 2483 1.35 kleink for (otherind = 0; otherind < nseen; ++otherind) { 2484 1.35 kleink otheri = types[otherind]; 2485 1.1 jtc if (sp->ttis[otheri].tt_isdst == tmp->tm_isdst) 2486 1.1 jtc continue; 2487 1.131 rillig tmp->tm_sec += (int)(sp->ttis[otheri].tt_utoff 2488 1.131 rillig - sp->ttis[samei].tt_utoff); 2489 1.1 jtc tmp->tm_isdst = !tmp->tm_isdst; 2490 1.87 christos t = time2(tmp, funcp, sp, offset, &okay); 2491 1.90 christos if (okay) { 2492 1.90 christos errno = save_errno; 2493 1.1 jtc return t; 2494 1.90 christos } 2495 1.131 rillig tmp->tm_sec -= (int)(sp->ttis[otheri].tt_utoff 2496 1.131 rillig - sp->ttis[samei].tt_utoff); 2497 1.1 jtc tmp->tm_isdst = !tmp->tm_isdst; 2498 1.1 jtc } 2499 1.1 jtc } 2500 1.60 christos errno = EOVERFLOW; 2501 1.1 jtc return WRONG; 2502 1.1 jtc } 2503 1.1 jtc 2504 1.145 christos #if !defined TM_GMTOFF || !USE_TIMEX_T 2505 1.145 christos 2506 1.87 christos static time_t 2507 1.145 christos mktime_tzname(struct state *sp, struct tm *tmp, bool setname) 2508 1.87 christos { 2509 1.131 rillig if (sp) 2510 1.131 rillig return time1(tmp, localsub, sp, setname); 2511 1.131 rillig else { 2512 1.131 rillig gmtcheck(); 2513 1.131 rillig return time1(tmp, gmtsub, gmtptr, 0); 2514 1.131 rillig } 2515 1.87 christos } 2516 1.87 christos 2517 1.145 christos # if USE_TIMEX_T 2518 1.145 christos static 2519 1.145 christos # endif 2520 1.1 jtc time_t 2521 1.145 christos mktime(struct tm *tmp) 2522 1.49 christos { 2523 1.145 christos time_t t; 2524 1.145 christos int err = lock(); 2525 1.145 christos if (err) { 2526 1.145 christos errno = err; 2527 1.145 christos return -1; 2528 1.145 christos } 2529 1.145 christos tzset_unlocked(); 2530 1.145 christos t = mktime_tzname(__lclptr, tmp, true); 2531 1.145 christos unlock(); 2532 1.145 christos return t; 2533 1.49 christos } 2534 1.49 christos 2535 1.87 christos #endif 2536 1.87 christos 2537 1.145 christos #if NETBSD_INSPIRED && !USE_TIMEX_T 2538 1.49 christos time_t 2539 1.145 christos mktime_z(struct state *restrict sp, struct tm *restrict tmp) 2540 1.1 jtc { 2541 1.145 christos return mktime_tzname(sp, tmp, false); 2542 1.1 jtc } 2543 1.145 christos #endif 2544 1.1 jtc 2545 1.145 christos #if STD_INSPIRED && !USE_TIMEX_T 2546 1.144 christos /* This function is obsolescent and may disappear in future releases. 2547 1.139 christos Callers can instead use mktime. */ 2548 1.1 jtc time_t 2549 1.68 christos timelocal_z(const timezone_t sp, struct tm *const tmp) 2550 1.49 christos { 2551 1.49 christos if (tmp != NULL) 2552 1.49 christos tmp->tm_isdst = -1; /* in case it wasn't initialized */ 2553 1.49 christos return mktime_z(sp, tmp); 2554 1.49 christos } 2555 1.49 christos 2556 1.49 christos time_t 2557 1.96 christos timelocal(struct tm *tmp) 2558 1.1 jtc { 2559 1.58 christos if (tmp != NULL) 2560 1.58 christos tmp->tm_isdst = -1; /* in case it wasn't initialized */ 2561 1.1 jtc return mktime(tmp); 2562 1.1 jtc } 2563 1.141 christos #endif 2564 1.141 christos 2565 1.145 christos #if defined TM_GMTOFF || !USE_TIMEX_T 2566 1.145 christos 2567 1.145 christos # ifndef EXTERN_TIMEOFF 2568 1.145 christos # ifndef timeoff 2569 1.145 christos # define timeoff my_timeoff /* Don't collide with OpenBSD 7.4 <time.h>. */ 2570 1.145 christos # endif 2571 1.145 christos # define EXTERN_TIMEOFF static 2572 1.139 christos # endif 2573 1.141 christos 2574 1.144 christos /* This function is obsolescent and may disappear in future releases. 2575 1.139 christos Callers can instead use mktime_z with a fixed-offset zone. */ 2576 1.141 christos EXTERN_TIMEOFF time_t 2577 1.96 christos timeoff(struct tm *tmp, long offset) 2578 1.1 jtc { 2579 1.131 rillig if (tmp) 2580 1.131 rillig tmp->tm_isdst = 0; 2581 1.131 rillig gmtcheck(); 2582 1.131 rillig return time1(tmp, gmtsub, gmtptr, (int_fast32_t)offset); 2583 1.1 jtc } 2584 1.145 christos #endif 2585 1.1 jtc 2586 1.145 christos #if !USE_TIMEX_T 2587 1.136 christos time_t 2588 1.136 christos timegm(struct tm *tmp) 2589 1.136 christos { 2590 1.136 christos time_t t; 2591 1.136 christos struct tm tmcpy; 2592 1.136 christos mktmcpy(&tmcpy, tmp); 2593 1.136 christos tmcpy.tm_wday = -1; 2594 1.136 christos t = timeoff(&tmcpy, 0); 2595 1.136 christos if (0 <= tmcpy.tm_wday) 2596 1.136 christos *tmp = tmcpy; 2597 1.136 christos return t; 2598 1.136 christos } 2599 1.145 christos #endif 2600 1.1 jtc 2601 1.124 christos static int_fast32_t 2602 1.140 christos leapcorr(struct state const *sp, __time_t t) 2603 1.1 jtc { 2604 1.130 rillig register struct lsinfo const * lp; 2605 1.130 rillig register int i; 2606 1.1 jtc 2607 1.1 jtc i = sp->leapcnt; 2608 1.1 jtc while (--i >= 0) { 2609 1.1 jtc lp = &sp->lsis[i]; 2610 1.87 christos if (t >= lp->ls_trans) 2611 1.1 jtc return lp->ls_corr; 2612 1.1 jtc } 2613 1.1 jtc return 0; 2614 1.1 jtc } 2615 1.1 jtc 2616 1.145 christos /* 2617 1.145 christos ** XXX--is the below the right way to conditionalize?? 2618 1.145 christos */ 2619 1.145 christos 2620 1.145 christos #if !USE_TIMEX_T 2621 1.145 christos # if STD_INSPIRED 2622 1.145 christos 2623 1.124 christos /* NETBSD_INSPIRED_EXTERN functions are exported to callers if 2624 1.124 christos NETBSD_INSPIRED is defined, and are private otherwise. */ 2625 1.145 christos # if NETBSD_INSPIRED 2626 1.145 christos # define NETBSD_INSPIRED_EXTERN 2627 1.145 christos # else 2628 1.145 christos # define NETBSD_INSPIRED_EXTERN static 2629 1.145 christos # endif 2630 1.124 christos 2631 1.132 rillig /* 2632 1.132 rillig ** IEEE Std 1003.1 (POSIX) says that 536457599 2633 1.132 rillig ** shall correspond to "Wed Dec 31 23:59:59 UTC 1986", which 2634 1.132 rillig ** is not the case if we are accounting for leap seconds. 2635 1.132 rillig ** So, we provide the following conversion routines for use 2636 1.132 rillig ** when exchanging timestamps with POSIX conforming systems. 2637 1.132 rillig */ 2638 1.124 christos 2639 1.109 christos NETBSD_INSPIRED_EXTERN time_t 2640 1.145 christos time2posix_z(struct state *sp, time_t t) 2641 1.49 christos { 2642 1.131 rillig return (time_t)(t - leapcorr(sp, t)); 2643 1.49 christos } 2644 1.49 christos 2645 1.49 christos time_t 2646 1.49 christos time2posix(time_t t) 2647 1.1 jtc { 2648 1.145 christos int err = lock(); 2649 1.145 christos if (err) { 2650 1.145 christos errno = err; 2651 1.145 christos return -1; 2652 1.145 christos } 2653 1.131 rillig if (!lcl_is_set) 2654 1.131 rillig tzset_unlocked(); 2655 1.131 rillig if (__lclptr) 2656 1.131 rillig t = (time_t)(t - leapcorr(__lclptr, t)); 2657 1.145 christos unlock(); 2658 1.131 rillig return t; 2659 1.1 jtc } 2660 1.1 jtc 2661 1.109 christos NETBSD_INSPIRED_EXTERN time_t 2662 1.145 christos posix2time_z(struct state *sp, time_t t) 2663 1.1 jtc { 2664 1.1 jtc time_t x; 2665 1.1 jtc time_t y; 2666 1.1 jtc /* 2667 1.1 jtc ** For a positive leap second hit, the result 2668 1.45 mlelstv ** is not unique. For a negative leap second 2669 1.1 jtc ** hit, the corresponding time doesn't exist, 2670 1.1 jtc ** so we return an adjacent second. 2671 1.1 jtc */ 2672 1.87 christos x = (time_t)(t + leapcorr(sp, t)); 2673 1.87 christos y = (time_t)(x - leapcorr(sp, x)); 2674 1.1 jtc if (y < t) { 2675 1.1 jtc do { 2676 1.1 jtc x++; 2677 1.87 christos y = (time_t)(x - leapcorr(sp, x)); 2678 1.1 jtc } while (y < t); 2679 1.87 christos x -= y != t; 2680 1.1 jtc } else if (y > t) { 2681 1.1 jtc do { 2682 1.1 jtc --x; 2683 1.87 christos y = (time_t)(x - leapcorr(sp, x)); 2684 1.1 jtc } while (y > t); 2685 1.87 christos x += y != t; 2686 1.1 jtc } 2687 1.49 christos return x; 2688 1.49 christos } 2689 1.49 christos 2690 1.49 christos time_t 2691 1.49 christos posix2time(time_t t) 2692 1.49 christos { 2693 1.145 christos int err = lock(); 2694 1.145 christos if (err) { 2695 1.145 christos errno = err; 2696 1.145 christos return -1; 2697 1.145 christos } 2698 1.131 rillig if (!lcl_is_set) 2699 1.131 rillig tzset_unlocked(); 2700 1.131 rillig if (__lclptr) 2701 1.131 rillig t = posix2time_z(__lclptr, t); 2702 1.145 christos unlock(); 2703 1.131 rillig return t; 2704 1.1 jtc } 2705 1.1 jtc 2706 1.145 christos # endif /* STD_INSPIRED */ 2707 1.145 christos 2708 1.145 christos # if TZ_TIME_T 2709 1.145 christos 2710 1.145 christos # if !USG_COMPAT 2711 1.145 christos # define timezone 0 2712 1.145 christos # endif 2713 1.145 christos 2714 1.145 christos /* Convert from the underlying system's time_t to the ersatz time_tz, 2715 1.145 christos which is called 'time_t' in this file. Typically, this merely 2716 1.145 christos converts the time's integer width. On some platforms, the system 2717 1.145 christos time is local time not UT, or uses some epoch other than the POSIX 2718 1.145 christos epoch. 2719 1.145 christos 2720 1.145 christos Although this code appears to define a function named 'time' that 2721 1.145 christos returns time_t, the macros in private.h cause this code to actually 2722 1.145 christos define a function named 'tz_time' that returns tz_time_t. The call 2723 1.145 christos to sys_time invokes the underlying system's 'time' function. */ 2724 1.145 christos 2725 1.145 christos time_t 2726 1.145 christos time(time_t *p) 2727 1.145 christos { 2728 1.145 christos __time_t r = sys_time(0); 2729 1.145 christos if (r != (time_t) -1) { 2730 1.145 christos iinntt offset = EPOCH_LOCAL ? (daylight ? timezone : altzone) : 0; 2731 1.145 christos if (offset < IINNTT_MIN + EPOCH_OFFSET 2732 1.145 christos || increment_overflow_time_iinntt(&r, offset - EPOCH_OFFSET)) { 2733 1.145 christos errno = EOVERFLOW; 2734 1.145 christos r = -1; 2735 1.145 christos } 2736 1.145 christos } 2737 1.145 christos if (p) 2738 1.145 christos *p = (time_t)r; 2739 1.145 christos return (time_t)r; 2740 1.145 christos } 2741 1.145 christos 2742 1.145 christos # endif 2743 1.145 christos #endif 2744 1.145 christos 2745