]> granicus.if.org Git - postgresql/blob - src/timezone/localtime.c
Rename pg_stat_wal_receiver.conn_info to conninfo.
[postgresql] / src / timezone / localtime.c
1 /*
2  * This file is in the public domain, so clarified as of
3  * 1996-06-05 by Arthur David Olson.
4  *
5  * IDENTIFICATION
6  *        src/timezone/localtime.c
7  */
8
9 /*
10  * Leap second handling from Bradley White.
11  * POSIX-style TZ environment variable handling from Guy Harris.
12  */
13
14 /* this file needs to build in both frontend and backend contexts */
15 #include "c.h"
16
17 #include <fcntl.h>
18
19 #include "datatype/timestamp.h"
20 #include "private.h"
21 #include "pgtz.h"
22 #include "tzfile.h"
23
24
25 #ifndef WILDABBR
26 /*
27  * Someone might make incorrect use of a time zone abbreviation:
28  *      1.  They might reference tzname[0] before calling tzset (explicitly
29  *              or implicitly).
30  *      2.  They might reference tzname[1] before calling tzset (explicitly
31  *              or implicitly).
32  *      3.  They might reference tzname[1] after setting to a time zone
33  *              in which Daylight Saving Time is never observed.
34  *      4.  They might reference tzname[0] after setting to a time zone
35  *              in which Standard Time is never observed.
36  *      5.  They might reference tm.TM_ZONE after calling offtime.
37  * What's best to do in the above cases is open to debate;
38  * for now, we just set things up so that in any of the five cases
39  * WILDABBR is used. Another possibility: initialize tzname[0] to the
40  * string "tzname[0] used before set", and similarly for the other cases.
41  * And another: initialize tzname[0] to "ERA", with an explanation in the
42  * manual page of what this "time zone abbreviation" means (doing this so
43  * that tzname[0] has the "normal" length of three characters).
44  */
45 #define WILDABBR        "   "
46 #endif   /* !defined WILDABBR */
47
48 static const char wildabbr[] = WILDABBR;
49
50 static const char gmt[] = "GMT";
51
52 /* The minimum and maximum finite time values.  This assumes no padding.  */
53 static const pg_time_t time_t_min = MINVAL(pg_time_t, TYPE_BIT(pg_time_t));
54 static const pg_time_t time_t_max = MAXVAL(pg_time_t, TYPE_BIT(pg_time_t));
55
56 /*
57  * The DST rules to use if TZ has no rules and we can't load TZDEFRULES.
58  * We default to US rules as of 1999-08-17.
59  * POSIX 1003.1 section 8.1.1 says that the default DST rules are
60  * implementation dependent; for historical reasons, US rules are a
61  * common default.
62  */
63 #define TZDEFRULESTRING ",M4.1.0,M10.5.0"
64
65 /* structs ttinfo, lsinfo, state have been moved to pgtz.h */
66
67 enum r_type
68 {
69         JULIAN_DAY,                                     /* Jn = Julian day */
70         DAY_OF_YEAR,                            /* n = day of year */
71         MONTH_NTH_DAY_OF_WEEK           /* Mm.n.d = month, week, day of week */
72 };
73
74 struct rule
75 {
76         enum r_type r_type;                     /* type of rule */
77         int                     r_day;                  /* day number of rule */
78         int                     r_week;                 /* week number of rule */
79         int                     r_mon;                  /* month number of rule */
80         int32           r_time;                 /* transition time of rule */
81 };
82
83 /*
84  * Prototypes for static functions.
85  */
86
87 static struct pg_tm *gmtsub(pg_time_t const *, int32, struct pg_tm *);
88 static bool increment_overflow(int *, int);
89 static bool increment_overflow_time(pg_time_t *, int32);
90 static struct pg_tm *timesub(pg_time_t const *, int32, struct state const *,
91                 struct pg_tm *);
92 static bool typesequiv(struct state const *, int, int);
93
94
95 /*
96  * Section 4.12.3 of X3.159-1989 requires that
97  *      Except for the strftime function, these functions [asctime,
98  *      ctime, gmtime, localtime] return values in one of two static
99  *      objects: a broken-down time structure and an array of char.
100  * Thanks to Paul Eggert for noting this.
101  */
102
103 static struct pg_tm tm;
104
105 /* Initialize *S to a value based on GMTOFF, ISDST, and ABBRIND.  */
106 static void
107 init_ttinfo(struct ttinfo * s, int32 gmtoff, bool isdst, int abbrind)
108 {
109         s->tt_gmtoff = gmtoff;
110         s->tt_isdst = isdst;
111         s->tt_abbrind = abbrind;
112         s->tt_ttisstd = false;
113         s->tt_ttisgmt = false;
114 }
115
116 static int32
117 detzcode(const char *codep)
118 {
119         int32           result;
120         int                     i;
121         int32           one = 1;
122         int32           halfmaxval = one << (32 - 2);
123         int32           maxval = halfmaxval - 1 + halfmaxval;
124         int32           minval = -1 - maxval;
125
126         result = codep[0] & 0x7f;
127         for (i = 1; i < 4; ++i)
128                 result = (result << 8) | (codep[i] & 0xff);
129
130         if (codep[0] & 0x80)
131         {
132                 /*
133                  * Do two's-complement negation even on non-two's-complement machines.
134                  * If the result would be minval - 1, return minval.
135                  */
136                 result -= !TWOS_COMPLEMENT(int32) &&result != 0;
137                 result += minval;
138         }
139         return result;
140 }
141
142 static int64
143 detzcode64(const char *codep)
144 {
145         uint64          result;
146         int                     i;
147         int64           one = 1;
148         int64           halfmaxval = one << (64 - 2);
149         int64           maxval = halfmaxval - 1 + halfmaxval;
150         int64           minval = -TWOS_COMPLEMENT(int64) -maxval;
151
152         result = codep[0] & 0x7f;
153         for (i = 1; i < 8; ++i)
154                 result = (result << 8) | (codep[i] & 0xff);
155
156         if (codep[0] & 0x80)
157         {
158                 /*
159                  * Do two's-complement negation even on non-two's-complement machines.
160                  * If the result would be minval - 1, return minval.
161                  */
162                 result -= !TWOS_COMPLEMENT(int64) &&result != 0;
163                 result += minval;
164         }
165         return result;
166 }
167
168 static bool
169 differ_by_repeat(const pg_time_t t1, const pg_time_t t0)
170 {
171         if (TYPE_BIT(pg_time_t) -TYPE_SIGNED(pg_time_t) <SECSPERREPEAT_BITS)
172                 return 0;
173         return t1 - t0 == SECSPERREPEAT;
174 }
175
176 /* Input buffer for data read from a compiled tz file.  */
177 union input_buffer
178 {
179         /* The first part of the buffer, interpreted as a header.  */
180         struct tzhead tzhead;
181
182         /* The entire buffer.  */
183         char            buf[2 * sizeof(struct tzhead) + 2 * sizeof(struct state)
184                                         +                       4 * TZ_MAX_TIMES];
185 };
186
187 /* Local storage needed for 'tzloadbody'.  */
188 union local_storage
189 {
190         /* We don't need the "fullname" member */
191
192         /* The results of analyzing the file's contents after it is opened.  */
193         struct
194         {
195                 /* The input buffer.  */
196                 union input_buffer u;
197
198                 /* A temporary state used for parsing a TZ string in the file.  */
199                 struct state st;
200         }                       u;
201 };
202
203 /* Load tz data from the file named NAME into *SP.  Read extended
204  * format if DOEXTEND.  Use *LSP for temporary storage.  Return 0 on
205  * success, an errno value on failure.
206  * PG: If "canonname" is not NULL, then on success the canonical spelling of
207  * given name is stored there (the buffer must be > TZ_STRLEN_MAX bytes!).
208  */
209 static int
210 tzloadbody(char const * name, char *canonname, struct state * sp, bool doextend,
211                    union local_storage * lsp)
212 {
213         int                     i;
214         int                     fid;
215         int                     stored;
216         ssize_t         nread;
217         union input_buffer *up = &lsp->u.u;
218         int                     tzheadsize = sizeof(struct tzhead);
219
220         sp->goback = sp->goahead = false;
221
222         if (!name)
223         {
224                 name = TZDEFAULT;
225                 if (!name)
226                         return EINVAL;
227         }
228
229         if (name[0] == ':')
230                 ++name;
231
232         fid = pg_open_tzfile(name, canonname);
233         if (fid < 0)
234                 return ENOENT;                  /* pg_open_tzfile may not set errno */
235
236         nread = read(fid, up->buf, sizeof up->buf);
237         if (nread < tzheadsize)
238         {
239                 int                     err = nread < 0 ? errno : EINVAL;
240
241                 close(fid);
242                 return err;
243         }
244         if (close(fid) < 0)
245                 return errno;
246         for (stored = 4; stored <= 8; stored *= 2)
247         {
248                 int32           ttisstdcnt = detzcode(up->tzhead.tzh_ttisstdcnt);
249                 int32           ttisgmtcnt = detzcode(up->tzhead.tzh_ttisgmtcnt);
250                 int32           leapcnt = detzcode(up->tzhead.tzh_leapcnt);
251                 int32           timecnt = detzcode(up->tzhead.tzh_timecnt);
252                 int32           typecnt = detzcode(up->tzhead.tzh_typecnt);
253                 int32           charcnt = detzcode(up->tzhead.tzh_charcnt);
254                 char const *p = up->buf + tzheadsize;
255
256                 if (!(0 <= leapcnt && leapcnt < TZ_MAX_LEAPS
257                           && 0 < typecnt && typecnt < TZ_MAX_TYPES
258                           && 0 <= timecnt && timecnt < TZ_MAX_TIMES
259                           && 0 <= charcnt && charcnt < TZ_MAX_CHARS
260                           && (ttisstdcnt == typecnt || ttisstdcnt == 0)
261                           && (ttisgmtcnt == typecnt || ttisgmtcnt == 0)))
262                         return EINVAL;
263                 if (nread
264                         < (tzheadsize           /* struct tzhead */
265                            + timecnt * stored           /* ats */
266                            + timecnt            /* types */
267                            + typecnt * 6        /* ttinfos */
268                            + charcnt            /* chars */
269                            + leapcnt * (stored + 4) /* lsinfos */
270                            + ttisstdcnt         /* ttisstds */
271                            + ttisgmtcnt))       /* ttisgmts */
272                         return EINVAL;
273                 sp->leapcnt = leapcnt;
274                 sp->timecnt = timecnt;
275                 sp->typecnt = typecnt;
276                 sp->charcnt = charcnt;
277
278                 /*
279                  * Read transitions, discarding those out of pg_time_t range. But
280                  * pretend the last transition before time_t_min occurred at
281                  * time_t_min.
282                  */
283                 timecnt = 0;
284                 for (i = 0; i < sp->timecnt; ++i)
285                 {
286                         int64           at
287                         = stored == 4 ? detzcode(p) : detzcode64(p);
288
289                         sp->types[i] = at <= time_t_max;
290                         if (sp->types[i])
291                         {
292                                 pg_time_t       attime
293                                 = ((TYPE_SIGNED(pg_time_t) ? at < time_t_min : at < 0)
294                                    ? time_t_min : at);
295
296                                 if (timecnt && attime <= sp->ats[timecnt - 1])
297                                 {
298                                         if (attime < sp->ats[timecnt - 1])
299                                                 return EINVAL;
300                                         sp->types[i - 1] = 0;
301                                         timecnt--;
302                                 }
303                                 sp->ats[timecnt++] = attime;
304                         }
305                         p += stored;
306                 }
307
308                 timecnt = 0;
309                 for (i = 0; i < sp->timecnt; ++i)
310                 {
311                         unsigned char typ = *p++;
312
313                         if (sp->typecnt <= typ)
314                                 return EINVAL;
315                         if (sp->types[i])
316                                 sp->types[timecnt++] = typ;
317                 }
318                 sp->timecnt = timecnt;
319                 for (i = 0; i < sp->typecnt; ++i)
320                 {
321                         struct ttinfo *ttisp;
322                         unsigned char isdst,
323                                                 abbrind;
324
325                         ttisp = &sp->ttis[i];
326                         ttisp->tt_gmtoff = detzcode(p);
327                         p += 4;
328                         isdst = *p++;
329                         if (!(isdst < 2))
330                                 return EINVAL;
331                         ttisp->tt_isdst = isdst;
332                         abbrind = *p++;
333                         if (!(abbrind < sp->charcnt))
334                                 return EINVAL;
335                         ttisp->tt_abbrind = abbrind;
336                 }
337                 for (i = 0; i < sp->charcnt; ++i)
338                         sp->chars[i] = *p++;
339                 sp->chars[i] = '\0';    /* ensure '\0' at end */
340
341                 /* Read leap seconds, discarding those out of pg_time_t range.  */
342                 leapcnt = 0;
343                 for (i = 0; i < sp->leapcnt; ++i)
344                 {
345                         int64           tr = stored == 4 ? detzcode(p) : detzcode64(p);
346                         int32           corr = detzcode(p + stored);
347
348                         p += stored + 4;
349                         if (tr <= time_t_max)
350                         {
351                                 pg_time_t       trans
352                                 = ((TYPE_SIGNED(pg_time_t) ? tr < time_t_min : tr < 0)
353                                    ? time_t_min : tr);
354
355                                 if (leapcnt && trans <= sp->lsis[leapcnt - 1].ls_trans)
356                                 {
357                                         if (trans < sp->lsis[leapcnt - 1].ls_trans)
358                                                 return EINVAL;
359                                         leapcnt--;
360                                 }
361                                 sp->lsis[leapcnt].ls_trans = trans;
362                                 sp->lsis[leapcnt].ls_corr = corr;
363                                 leapcnt++;
364                         }
365                 }
366                 sp->leapcnt = leapcnt;
367
368                 for (i = 0; i < sp->typecnt; ++i)
369                 {
370                         struct ttinfo *ttisp;
371
372                         ttisp = &sp->ttis[i];
373                         if (ttisstdcnt == 0)
374                                 ttisp->tt_ttisstd = false;
375                         else
376                         {
377                                 if (*p != true && *p != false)
378                                         return EINVAL;
379                                 ttisp->tt_ttisstd = *p++;
380                         }
381                 }
382                 for (i = 0; i < sp->typecnt; ++i)
383                 {
384                         struct ttinfo *ttisp;
385
386                         ttisp = &sp->ttis[i];
387                         if (ttisgmtcnt == 0)
388                                 ttisp->tt_ttisgmt = false;
389                         else
390                         {
391                                 if (*p != true && *p != false)
392                                         return EINVAL;
393                                 ttisp->tt_ttisgmt = *p++;
394                         }
395                 }
396
397                 /*
398                  * If this is an old file, we're done.
399                  */
400                 if (up->tzhead.tzh_version[0] == '\0')
401                         break;
402                 nread -= p - up->buf;
403                 memmove(up->buf, p, nread);
404         }
405         if (doextend && nread > 2 &&
406                 up->buf[0] == '\n' && up->buf[nread - 1] == '\n' &&
407                 sp->typecnt + 2 <= TZ_MAX_TYPES)
408         {
409                 struct state *ts = &lsp->u.st;
410
411                 up->buf[nread - 1] = '\0';
412                 if (tzparse(&up->buf[1], ts, false)
413                         && ts->typecnt == 2)
414                 {
415                         /*
416                          * Attempt to reuse existing abbreviations. Without this,
417                          * America/Anchorage would stop working after 2037 when
418                          * TZ_MAX_CHARS is 50, as sp->charcnt equals 42 (for LMT CAT CAWT
419                          * CAPT AHST AHDT YST AKDT AKST) and ts->charcnt equals 10 (for
420                          * AKST AKDT).  Reusing means sp->charcnt can stay 42 in this
421                          * example.
422                          */
423                         int                     gotabbr = 0;
424                         int                     charcnt = sp->charcnt;
425
426                         for (i = 0; i < 2; i++)
427                         {
428                                 char       *tsabbr = ts->chars + ts->ttis[i].tt_abbrind;
429                                 int                     j;
430
431                                 for (j = 0; j < charcnt; j++)
432                                         if (strcmp(sp->chars + j, tsabbr) == 0)
433                                         {
434                                                 ts->ttis[i].tt_abbrind = j;
435                                                 gotabbr++;
436                                                 break;
437                                         }
438                                 if (!(j < charcnt))
439                                 {
440                                         int                     tsabbrlen = strlen(tsabbr);
441
442                                         if (j + tsabbrlen < TZ_MAX_CHARS)
443                                         {
444                                                 strcpy(sp->chars + j, tsabbr);
445                                                 charcnt = j + tsabbrlen + 1;
446                                                 ts->ttis[i].tt_abbrind = j;
447                                                 gotabbr++;
448                                         }
449                                 }
450                         }
451                         if (gotabbr == 2)
452                         {
453                                 sp->charcnt = charcnt;
454                                 for (i = 0; i < ts->timecnt; i++)
455                                         if (sp->ats[sp->timecnt - 1] < ts->ats[i])
456                                                 break;
457                                 while (i < ts->timecnt
458                                            && sp->timecnt < TZ_MAX_TIMES)
459                                 {
460                                         sp->ats[sp->timecnt] = ts->ats[i];
461                                         sp->types[sp->timecnt] = (sp->typecnt
462                                                                                           + ts->types[i]);
463                                         sp->timecnt++;
464                                         i++;
465                                 }
466                                 sp->ttis[sp->typecnt++] = ts->ttis[0];
467                                 sp->ttis[sp->typecnt++] = ts->ttis[1];
468                         }
469                 }
470         }
471         if (sp->timecnt > 1)
472         {
473                 for (i = 1; i < sp->timecnt; ++i)
474                         if (typesequiv(sp, sp->types[i], sp->types[0]) &&
475                                 differ_by_repeat(sp->ats[i], sp->ats[0]))
476                         {
477                                 sp->goback = true;
478                                 break;
479                         }
480                 for (i = sp->timecnt - 2; i >= 0; --i)
481                         if (typesequiv(sp, sp->types[sp->timecnt - 1],
482                                                    sp->types[i]) &&
483                                 differ_by_repeat(sp->ats[sp->timecnt - 1],
484                                                                  sp->ats[i]))
485                         {
486                                 sp->goahead = true;
487                                 break;
488                         }
489         }
490
491         /*
492          * If type 0 is is unused in transitions, it's the type to use for early
493          * times.
494          */
495         for (i = 0; i < sp->timecnt; ++i)
496                 if (sp->types[i] == 0)
497                         break;
498         i = i < sp->timecnt ? -1 : 0;
499
500         /*
501          * Absent the above, if there are transition times and the first
502          * transition is to a daylight time find the standard type less than and
503          * closest to the type of the first transition.
504          */
505         if (i < 0 && sp->timecnt > 0 && sp->ttis[sp->types[0]].tt_isdst)
506         {
507                 i = sp->types[0];
508                 while (--i >= 0)
509                         if (!sp->ttis[i].tt_isdst)
510                                 break;
511         }
512
513         /*
514          * If no result yet, find the first standard type. If there is none, punt
515          * to type zero.
516          */
517         if (i < 0)
518         {
519                 i = 0;
520                 while (sp->ttis[i].tt_isdst)
521                         if (++i >= sp->typecnt)
522                         {
523                                 i = 0;
524                                 break;
525                         }
526         }
527         sp->defaulttype = i;
528         return 0;
529 }
530
531 /* Load tz data from the file named NAME into *SP.  Read extended
532  * format if DOEXTEND.  Return 0 on success, an errno value on failure.
533  * PG: If "canonname" is not NULL, then on success the canonical spelling of
534  * given name is stored there (the buffer must be > TZ_STRLEN_MAX bytes!).
535  */
536 int
537 tzload(const char *name, char *canonname, struct state * sp, bool doextend)
538 {
539         union local_storage ls;
540
541         return tzloadbody(name, canonname, sp, doextend, &ls);
542 }
543
544 static bool
545 typesequiv(const struct state * sp, int a, int b)
546 {
547         bool            result;
548
549         if (sp == NULL ||
550                 a < 0 || a >= sp->typecnt ||
551                 b < 0 || b >= sp->typecnt)
552                 result = false;
553         else
554         {
555                 const struct ttinfo *ap = &sp->ttis[a];
556                 const struct ttinfo *bp = &sp->ttis[b];
557
558                 result = ap->tt_gmtoff == bp->tt_gmtoff &&
559                         ap->tt_isdst == bp->tt_isdst &&
560                         ap->tt_ttisstd == bp->tt_ttisstd &&
561                         ap->tt_ttisgmt == bp->tt_ttisgmt &&
562                         strcmp(&sp->chars[ap->tt_abbrind],
563                                    &sp->chars[bp->tt_abbrind]) == 0;
564         }
565         return result;
566 }
567
568 static const int mon_lengths[2][MONSPERYEAR] = {
569         {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31},
570         {31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}
571 };
572
573 static const int year_lengths[2] = {
574         DAYSPERNYEAR, DAYSPERLYEAR
575 };
576
577 /*
578  * Given a pointer into a time zone string, scan until a character that is not
579  * a valid character in a zone name is found. Return a pointer to that
580  * character.
581  */
582 static const char *
583 getzname(const char *strp)
584 {
585         char            c;
586
587         while ((c = *strp) != '\0' && !is_digit(c) && c != ',' && c != '-' &&
588                    c != '+')
589                 ++strp;
590         return strp;
591 }
592
593 /*
594  * Given a pointer into an extended time zone string, scan until the ending
595  * delimiter of the zone name is located. Return a pointer to the delimiter.
596  *
597  * As with getzname above, the legal character set is actually quite
598  * restricted, with other characters producing undefined results.
599  * We don't do any checking here; checking is done later in common-case code.
600  */
601 static const char *
602 getqzname(const char *strp, int delim)
603 {
604         int                     c;
605
606         while ((c = *strp) != '\0' && c != delim)
607                 ++strp;
608         return strp;
609 }
610
611 /*
612  * Given a pointer into a time zone string, extract a number from that string.
613  * Check that the number is within a specified range; if it is not, return
614  * NULL.
615  * Otherwise, return a pointer to the first character not part of the number.
616  */
617 static const char *
618 getnum(const char *strp, int *nump, int min, int max)
619 {
620         char            c;
621         int                     num;
622
623         if (strp == NULL || !is_digit(c = *strp))
624                 return NULL;
625         num = 0;
626         do
627         {
628                 num = num * 10 + (c - '0');
629                 if (num > max)
630                         return NULL;            /* illegal value */
631                 c = *++strp;
632         } while (is_digit(c));
633         if (num < min)
634                 return NULL;                    /* illegal value */
635         *nump = num;
636         return strp;
637 }
638
639 /*
640  * Given a pointer into a time zone string, extract a number of seconds,
641  * in hh[:mm[:ss]] form, from the string.
642  * If any error occurs, return NULL.
643  * Otherwise, return a pointer to the first character not part of the number
644  * of seconds.
645  */
646 static const char *
647 getsecs(const char *strp, int32 *secsp)
648 {
649         int                     num;
650
651         /*
652          * 'HOURSPERDAY * DAYSPERWEEK - 1' allows quasi-Posix rules like
653          * "M10.4.6/26", which does not conform to Posix, but which specifies the
654          * equivalent of "02:00 on the first Sunday on or after 23 Oct".
655          */
656         strp = getnum(strp, &num, 0, HOURSPERDAY * DAYSPERWEEK - 1);
657         if (strp == NULL)
658                 return NULL;
659         *secsp = num * (int32) SECSPERHOUR;
660         if (*strp == ':')
661         {
662                 ++strp;
663                 strp = getnum(strp, &num, 0, MINSPERHOUR - 1);
664                 if (strp == NULL)
665                         return NULL;
666                 *secsp += num * SECSPERMIN;
667                 if (*strp == ':')
668                 {
669                         ++strp;
670                         /* 'SECSPERMIN' allows for leap seconds.  */
671                         strp = getnum(strp, &num, 0, SECSPERMIN);
672                         if (strp == NULL)
673                                 return NULL;
674                         *secsp += num;
675                 }
676         }
677         return strp;
678 }
679
680 /*
681  * Given a pointer into a time zone string, extract an offset, in
682  * [+-]hh[:mm[:ss]] form, from the string.
683  * If any error occurs, return NULL.
684  * Otherwise, return a pointer to the first character not part of the time.
685  */
686 static const char *
687 getoffset(const char *strp, int32 *offsetp)
688 {
689         bool            neg = false;
690
691         if (*strp == '-')
692         {
693                 neg = true;
694                 ++strp;
695         }
696         else if (*strp == '+')
697                 ++strp;
698         strp = getsecs(strp, offsetp);
699         if (strp == NULL)
700                 return NULL;                    /* illegal time */
701         if (neg)
702                 *offsetp = -*offsetp;
703         return strp;
704 }
705
706 /*
707  * Given a pointer into a time zone string, extract a rule in the form
708  * date[/time]. See POSIX section 8 for the format of "date" and "time".
709  * If a valid rule is not found, return NULL.
710  * Otherwise, return a pointer to the first character not part of the rule.
711  */
712 static const char *
713 getrule(const char *strp, struct rule * rulep)
714 {
715         if (*strp == 'J')
716         {
717                 /*
718                  * Julian day.
719                  */
720                 rulep->r_type = JULIAN_DAY;
721                 ++strp;
722                 strp = getnum(strp, &rulep->r_day, 1, DAYSPERNYEAR);
723         }
724         else if (*strp == 'M')
725         {
726                 /*
727                  * Month, week, day.
728                  */
729                 rulep->r_type = MONTH_NTH_DAY_OF_WEEK;
730                 ++strp;
731                 strp = getnum(strp, &rulep->r_mon, 1, MONSPERYEAR);
732                 if (strp == NULL)
733                         return NULL;
734                 if (*strp++ != '.')
735                         return NULL;
736                 strp = getnum(strp, &rulep->r_week, 1, 5);
737                 if (strp == NULL)
738                         return NULL;
739                 if (*strp++ != '.')
740                         return NULL;
741                 strp = getnum(strp, &rulep->r_day, 0, DAYSPERWEEK - 1);
742         }
743         else if (is_digit(*strp))
744         {
745                 /*
746                  * Day of year.
747                  */
748                 rulep->r_type = DAY_OF_YEAR;
749                 strp = getnum(strp, &rulep->r_day, 0, DAYSPERLYEAR - 1);
750         }
751         else
752                 return NULL;                    /* invalid format */
753         if (strp == NULL)
754                 return NULL;
755         if (*strp == '/')
756         {
757                 /*
758                  * Time specified.
759                  */
760                 ++strp;
761                 strp = getoffset(strp, &rulep->r_time);
762         }
763         else
764                 rulep->r_time = 2 * SECSPERHOUR;                /* default = 2:00:00 */
765         return strp;
766 }
767
768 /*
769  * Given a year, a rule, and the offset from UT at the time that rule takes
770  * effect, calculate the year-relative time that rule takes effect.
771  */
772 static int32
773 transtime(int year, const struct rule * rulep,
774                   int32 offset)
775 {
776         bool            leapyear;
777         int32           value;
778         int                     i,
779                                 d,
780                                 m1,
781                                 yy0,
782                                 yy1,
783                                 yy2,
784                                 dow;
785
786         INITIALIZE(value);
787         leapyear = isleap(year);
788         switch (rulep->r_type)
789         {
790
791                 case JULIAN_DAY:
792
793                         /*
794                          * Jn - Julian day, 1 == January 1, 60 == March 1 even in leap
795                          * years. In non-leap years, or if the day number is 59 or less,
796                          * just add SECSPERDAY times the day number-1 to the time of
797                          * January 1, midnight, to get the day.
798                          */
799                         value = (rulep->r_day - 1) * SECSPERDAY;
800                         if (leapyear && rulep->r_day >= 60)
801                                 value += SECSPERDAY;
802                         break;
803
804                 case DAY_OF_YEAR:
805
806                         /*
807                          * n - day of year. Just add SECSPERDAY times the day number to
808                          * the time of January 1, midnight, to get the day.
809                          */
810                         value = rulep->r_day * SECSPERDAY;
811                         break;
812
813                 case MONTH_NTH_DAY_OF_WEEK:
814
815                         /*
816                          * Mm.n.d - nth "dth day" of month m.
817                          */
818
819                         /*
820                          * Use Zeller's Congruence to get day-of-week of first day of
821                          * month.
822                          */
823                         m1 = (rulep->r_mon + 9) % 12 + 1;
824                         yy0 = (rulep->r_mon <= 2) ? (year - 1) : year;
825                         yy1 = yy0 / 100;
826                         yy2 = yy0 % 100;
827                         dow = ((26 * m1 - 2) / 10 +
828                                    1 + yy2 + yy2 / 4 + yy1 / 4 - 2 * yy1) % 7;
829                         if (dow < 0)
830                                 dow += DAYSPERWEEK;
831
832                         /*
833                          * "dow" is the day-of-week of the first day of the month. Get the
834                          * day-of-month (zero-origin) of the first "dow" day of the month.
835                          */
836                         d = rulep->r_day - dow;
837                         if (d < 0)
838                                 d += DAYSPERWEEK;
839                         for (i = 1; i < rulep->r_week; ++i)
840                         {
841                                 if (d + DAYSPERWEEK >=
842                                         mon_lengths[(int) leapyear][rulep->r_mon - 1])
843                                         break;
844                                 d += DAYSPERWEEK;
845                         }
846
847                         /*
848                          * "d" is the day-of-month (zero-origin) of the day we want.
849                          */
850                         value = d * SECSPERDAY;
851                         for (i = 0; i < rulep->r_mon - 1; ++i)
852                                 value += mon_lengths[(int) leapyear][i] * SECSPERDAY;
853                         break;
854         }
855
856         /*
857          * "value" is the year-relative time of 00:00:00 UT on the day in
858          * question. To get the year-relative time of the specified local time on
859          * that day, add the transition time and the current offset from UT.
860          */
861         return value + rulep->r_time + offset;
862 }
863
864 /*
865  * Given a POSIX section 8-style TZ string, fill in the rule tables as
866  * appropriate.
867  * Returns true on success, false on failure.
868  */
869 bool
870 tzparse(const char *name, struct state * sp, bool lastditch)
871 {
872         const char *stdname;
873         const char *dstname = NULL;
874         size_t          stdlen;
875         size_t          dstlen;
876         size_t          charcnt;
877         int32           stdoffset;
878         int32           dstoffset;
879         char       *cp;
880         bool            load_ok;
881
882         stdname = name;
883         if (lastditch)
884         {
885                 /*
886                  * This is intentionally somewhat different from the IANA code.  We do
887                  * not want to invoke tzload() in the lastditch case: we can't assume
888                  * pg_open_tzfile() is sane yet, and we don't care about leap seconds
889                  * anyway.
890                  */
891                 stdlen = strlen(name);  /* length of standard zone name */
892                 name += stdlen;
893                 if (stdlen >= sizeof sp->chars)
894                         stdlen = (sizeof sp->chars) - 1;
895                 charcnt = stdlen + 1;
896                 stdoffset = 0;
897                 sp->goback = sp->goahead = false;               /* simulate failed tzload() */
898                 load_ok = false;
899         }
900         else
901         {
902                 if (*name == '<')
903                 {
904                         name++;
905                         stdname = name;
906                         name = getqzname(name, '>');
907                         if (*name != '>')
908                                 return false;
909                         stdlen = name - stdname;
910                         name++;
911                 }
912                 else
913                 {
914                         name = getzname(name);
915                         stdlen = name - stdname;
916                 }
917                 if (*name == '\0')              /* we allow empty STD abbrev, unlike IANA */
918                         return false;
919                 name = getoffset(name, &stdoffset);
920                 if (name == NULL)
921                         return false;
922                 charcnt = stdlen + 1;
923                 if (sizeof sp->chars < charcnt)
924                         return false;
925                 load_ok = tzload(TZDEFRULES, NULL, sp, false) == 0;
926         }
927         if (!load_ok)
928                 sp->leapcnt = 0;                /* so, we're off a little */
929         if (*name != '\0')
930         {
931                 if (*name == '<')
932                 {
933                         dstname = ++name;
934                         name = getqzname(name, '>');
935                         if (*name != '>')
936                                 return false;
937                         dstlen = name - dstname;
938                         name++;
939                 }
940                 else
941                 {
942                         dstname = name;
943                         name = getzname(name);
944                         dstlen = name - dstname;        /* length of DST zone name */
945                 }
946                 if (!dstlen)
947                         return false;
948                 charcnt += dstlen + 1;
949                 if (sizeof sp->chars < charcnt)
950                         return false;
951                 if (*name != '\0' && *name != ',' && *name != ';')
952                 {
953                         name = getoffset(name, &dstoffset);
954                         if (name == NULL)
955                                 return false;
956                 }
957                 else
958                         dstoffset = stdoffset - SECSPERHOUR;
959                 if (*name == '\0' && !load_ok)
960                         name = TZDEFRULESTRING;
961                 if (*name == ',' || *name == ';')
962                 {
963                         struct rule start;
964                         struct rule end;
965                         int                     year;
966                         int                     yearlim;
967                         int                     timecnt;
968                         pg_time_t       janfirst;
969
970                         ++name;
971                         if ((name = getrule(name, &start)) == NULL)
972                                 return false;
973                         if (*name++ != ',')
974                                 return false;
975                         if ((name = getrule(name, &end)) == NULL)
976                                 return false;
977                         if (*name != '\0')
978                                 return false;
979                         sp->typecnt = 2;        /* standard time and DST */
980
981                         /*
982                          * Two transitions per year, from EPOCH_YEAR forward.
983                          */
984                         init_ttinfo(&sp->ttis[0], -dstoffset, true, stdlen + 1);
985                         init_ttinfo(&sp->ttis[1], -stdoffset, false, 0);
986                         sp->defaulttype = 0;
987                         timecnt = 0;
988                         janfirst = 0;
989                         yearlim = EPOCH_YEAR + YEARSPERREPEAT;
990                         for (year = EPOCH_YEAR; year < yearlim; year++)
991                         {
992                                 int32
993                                                         starttime = transtime(year, &start, stdoffset),
994                                                         endtime = transtime(year, &end, dstoffset);
995                                 int32
996                                                         yearsecs = (year_lengths[isleap(year)]
997                                                                                 * SECSPERDAY);
998                                 bool            reversed = endtime < starttime;
999
1000                                 if (reversed)
1001                                 {
1002                                         int32           swap = starttime;
1003
1004                                         starttime = endtime;
1005                                         endtime = swap;
1006                                 }
1007                                 if (reversed
1008                                         || (starttime < endtime
1009                                                 && (endtime - starttime
1010                                                         < (yearsecs
1011                                                            + (stdoffset - dstoffset)))))
1012                                 {
1013                                         if (TZ_MAX_TIMES - 2 < timecnt)
1014                                                 break;
1015                                         yearlim = year + YEARSPERREPEAT + 1;
1016                                         sp->ats[timecnt] = janfirst;
1017                                         if (increment_overflow_time
1018                                                 (&sp->ats[timecnt], starttime))
1019                                                 break;
1020                                         sp->types[timecnt++] = reversed;
1021                                         sp->ats[timecnt] = janfirst;
1022                                         if (increment_overflow_time
1023                                                 (&sp->ats[timecnt], endtime))
1024                                                 break;
1025                                         sp->types[timecnt++] = !reversed;
1026                                 }
1027                                 if (increment_overflow_time(&janfirst, yearsecs))
1028                                         break;
1029                         }
1030                         sp->timecnt = timecnt;
1031                         if (!timecnt)
1032                                 sp->typecnt = 1;        /* Perpetual DST.  */
1033                 }
1034                 else
1035                 {
1036                         int32           theirstdoffset;
1037                         int32           theirdstoffset;
1038                         int32           theiroffset;
1039                         bool            isdst;
1040                         int                     i;
1041                         int                     j;
1042
1043                         if (*name != '\0')
1044                                 return false;
1045
1046                         /*
1047                          * Initial values of theirstdoffset and theirdstoffset.
1048                          */
1049                         theirstdoffset = 0;
1050                         for (i = 0; i < sp->timecnt; ++i)
1051                         {
1052                                 j = sp->types[i];
1053                                 if (!sp->ttis[j].tt_isdst)
1054                                 {
1055                                         theirstdoffset =
1056                                                 -sp->ttis[j].tt_gmtoff;
1057                                         break;
1058                                 }
1059                         }
1060                         theirdstoffset = 0;
1061                         for (i = 0; i < sp->timecnt; ++i)
1062                         {
1063                                 j = sp->types[i];
1064                                 if (sp->ttis[j].tt_isdst)
1065                                 {
1066                                         theirdstoffset =
1067                                                 -sp->ttis[j].tt_gmtoff;
1068                                         break;
1069                                 }
1070                         }
1071
1072                         /*
1073                          * Initially we're assumed to be in standard time.
1074                          */
1075                         isdst = false;
1076                         theiroffset = theirstdoffset;
1077
1078                         /*
1079                          * Now juggle transition times and types tracking offsets as you
1080                          * do.
1081                          */
1082                         for (i = 0; i < sp->timecnt; ++i)
1083                         {
1084                                 j = sp->types[i];
1085                                 sp->types[i] = sp->ttis[j].tt_isdst;
1086                                 if (sp->ttis[j].tt_ttisgmt)
1087                                 {
1088                                         /* No adjustment to transition time */
1089                                 }
1090                                 else
1091                                 {
1092                                         /*
1093                                          * If summer time is in effect, and the transition time
1094                                          * was not specified as standard time, add the summer time
1095                                          * offset to the transition time; otherwise, add the
1096                                          * standard time offset to the transition time.
1097                                          */
1098
1099                                         /*
1100                                          * Transitions from DST to DDST will effectively disappear
1101                                          * since POSIX provides for only one DST offset.
1102                                          */
1103                                         if (isdst && !sp->ttis[j].tt_ttisstd)
1104                                         {
1105                                                 sp->ats[i] += dstoffset -
1106                                                         theirdstoffset;
1107                                         }
1108                                         else
1109                                         {
1110                                                 sp->ats[i] += stdoffset -
1111                                                         theirstdoffset;
1112                                         }
1113                                 }
1114                                 theiroffset = -sp->ttis[j].tt_gmtoff;
1115                                 if (sp->ttis[j].tt_isdst)
1116                                         theirdstoffset = theiroffset;
1117                                 else
1118                                         theirstdoffset = theiroffset;
1119                         }
1120
1121                         /*
1122                          * Finally, fill in ttis.
1123                          */
1124                         init_ttinfo(&sp->ttis[0], -stdoffset, false, 0);
1125                         init_ttinfo(&sp->ttis[1], -dstoffset, true, stdlen + 1);
1126                         sp->typecnt = 2;
1127                         sp->defaulttype = 0;
1128                 }
1129         }
1130         else
1131         {
1132                 dstlen = 0;
1133                 sp->typecnt = 1;                /* only standard time */
1134                 sp->timecnt = 0;
1135                 init_ttinfo(&sp->ttis[0], -stdoffset, false, 0);
1136                 sp->defaulttype = 0;
1137         }
1138         sp->charcnt = charcnt;
1139         cp = sp->chars;
1140         memcpy(cp, stdname, stdlen);
1141         cp += stdlen;
1142         *cp++ = '\0';
1143         if (dstlen != 0)
1144         {
1145                 memcpy(cp, dstname, dstlen);
1146                 *(cp + dstlen) = '\0';
1147         }
1148         return true;
1149 }
1150
1151 static void
1152 gmtload(struct state * sp)
1153 {
1154         if (tzload(gmt, NULL, sp, true) != 0)
1155                 tzparse(gmt, sp, true);
1156 }
1157
1158
1159 /*
1160  * The easy way to behave "as if no library function calls" localtime
1161  * is to not call it, so we drop its guts into "localsub", which can be
1162  * freely called. (And no, the PANS doesn't require the above behavior,
1163  * but it *is* desirable.)
1164  */
1165 static struct pg_tm *
1166 localsub(struct state const * sp, pg_time_t const * timep,
1167                  struct pg_tm * tmp)
1168 {
1169         const struct ttinfo *ttisp;
1170         int                     i;
1171         struct pg_tm *result;
1172         const pg_time_t t = *timep;
1173
1174         if (sp == NULL)
1175                 return gmtsub(timep, 0, tmp);
1176         if ((sp->goback && t < sp->ats[0]) ||
1177                 (sp->goahead && t > sp->ats[sp->timecnt - 1]))
1178         {
1179                 pg_time_t       newt = t;
1180                 pg_time_t       seconds;
1181                 pg_time_t       years;
1182
1183                 if (t < sp->ats[0])
1184                         seconds = sp->ats[0] - t;
1185                 else
1186                         seconds = t - sp->ats[sp->timecnt - 1];
1187                 --seconds;
1188                 years = (seconds / SECSPERREPEAT + 1) * YEARSPERREPEAT;
1189                 seconds = years * AVGSECSPERYEAR;
1190                 if (t < sp->ats[0])
1191                         newt += seconds;
1192                 else
1193                         newt -= seconds;
1194                 if (newt < sp->ats[0] ||
1195                         newt > sp->ats[sp->timecnt - 1])
1196                         return NULL;            /* "cannot happen" */
1197                 result = localsub(sp, &newt, tmp);
1198                 if (result)
1199                 {
1200                         int64           newy;
1201
1202                         newy = result->tm_year;
1203                         if (t < sp->ats[0])
1204                                 newy -= years;
1205                         else
1206                                 newy += years;
1207                         if (!(INT_MIN <= newy && newy <= INT_MAX))
1208                                 return NULL;
1209                         result->tm_year = newy;
1210                 }
1211                 return result;
1212         }
1213         if (sp->timecnt == 0 || t < sp->ats[0])
1214         {
1215                 i = sp->defaulttype;
1216         }
1217         else
1218         {
1219                 int                     lo = 1;
1220                 int                     hi = sp->timecnt;
1221
1222                 while (lo < hi)
1223                 {
1224                         int                     mid = (lo + hi) >> 1;
1225
1226                         if (t < sp->ats[mid])
1227                                 hi = mid;
1228                         else
1229                                 lo = mid + 1;
1230                 }
1231                 i = (int) sp->types[lo - 1];
1232         }
1233         ttisp = &sp->ttis[i];
1234
1235         result = timesub(&t, ttisp->tt_gmtoff, sp, tmp);
1236         if (result)
1237         {
1238                 result->tm_isdst = ttisp->tt_isdst;
1239                 result->tm_zone = (char *) &sp->chars[ttisp->tt_abbrind];
1240         }
1241         return result;
1242 }
1243
1244
1245 struct pg_tm *
1246 pg_localtime(const pg_time_t *timep, const pg_tz *tz)
1247 {
1248         return localsub(&tz->state, timep, &tm);
1249 }
1250
1251
1252 /*
1253  * gmtsub is to gmtime as localsub is to localtime.
1254  *
1255  * Except we have a private "struct state" for GMT, so no sp is passed in.
1256  */
1257 static struct pg_tm *
1258 gmtsub(pg_time_t const * timep, int32 offset, struct pg_tm * tmp)
1259 {
1260         struct pg_tm *result;
1261
1262         /* GMT timezone state data is kept here */
1263         static struct state gmtmem;
1264         static bool gmt_is_set = false;
1265 #define gmtptr          (&gmtmem)
1266
1267         if (!gmt_is_set)
1268         {
1269                 gmt_is_set = true;
1270                 gmtload(gmtptr);
1271         }
1272         result = timesub(timep, offset, gmtptr, tmp);
1273
1274         /*
1275          * Could get fancy here and deliver something such as "UT+xxxx" or
1276          * "UT-xxxx" if offset is non-zero, but this is no time for a treasure
1277          * hunt.
1278          */
1279         if (offset != 0)
1280                 tmp->tm_zone = wildabbr;
1281         else
1282                 tmp->tm_zone = gmtptr->chars;
1283
1284         return result;
1285 }
1286
1287 struct pg_tm *
1288 pg_gmtime(const pg_time_t *timep)
1289 {
1290         return gmtsub(timep, 0, &tm);
1291 }
1292
1293 /*
1294  * Return the number of leap years through the end of the given year
1295  * where, to make the math easy, the answer for year zero is defined as zero.
1296  */
1297 static int
1298 leaps_thru_end_of(const int y)
1299 {
1300         return (y >= 0) ? (y / 4 - y / 100 + y / 400) :
1301                 -(leaps_thru_end_of(-(y + 1)) + 1);
1302 }
1303
1304 static struct pg_tm *
1305 timesub(const pg_time_t *timep, int32 offset,
1306                 const struct state * sp, struct pg_tm * tmp)
1307 {
1308         const struct lsinfo *lp;
1309         pg_time_t       tdays;
1310         int                     idays;                  /* unsigned would be so 2003 */
1311         int64           rem;
1312         int                     y;
1313         const int  *ip;
1314         int64           corr;
1315         bool            hit;
1316         int                     i;
1317
1318         corr = 0;
1319         hit = false;
1320         i = (sp == NULL) ? 0 : sp->leapcnt;
1321         while (--i >= 0)
1322         {
1323                 lp = &sp->lsis[i];
1324                 if (*timep >= lp->ls_trans)
1325                 {
1326                         if (*timep == lp->ls_trans)
1327                         {
1328                                 hit = ((i == 0 && lp->ls_corr > 0) ||
1329                                            lp->ls_corr > sp->lsis[i - 1].ls_corr);
1330                                 if (hit)
1331                                         while (i > 0 &&
1332                                                    sp->lsis[i].ls_trans ==
1333                                                    sp->lsis[i - 1].ls_trans + 1 &&
1334                                                    sp->lsis[i].ls_corr ==
1335                                                    sp->lsis[i - 1].ls_corr + 1)
1336                                         {
1337                                                 ++hit;
1338                                                 --i;
1339                                         }
1340                         }
1341                         corr = lp->ls_corr;
1342                         break;
1343                 }
1344         }
1345         y = EPOCH_YEAR;
1346         tdays = *timep / SECSPERDAY;
1347         rem = *timep % SECSPERDAY;
1348         while (tdays < 0 || tdays >= year_lengths[isleap(y)])
1349         {
1350                 int                     newy;
1351                 pg_time_t       tdelta;
1352                 int                     idelta;
1353                 int                     leapdays;
1354
1355                 tdelta = tdays / DAYSPERLYEAR;
1356                 if (!((!TYPE_SIGNED(pg_time_t) ||INT_MIN <= tdelta)
1357                           && tdelta <= INT_MAX))
1358                         goto out_of_range;
1359                 idelta = tdelta;
1360                 if (idelta == 0)
1361                         idelta = (tdays < 0) ? -1 : 1;
1362                 newy = y;
1363                 if (increment_overflow(&newy, idelta))
1364                         goto out_of_range;
1365                 leapdays = leaps_thru_end_of(newy - 1) -
1366                         leaps_thru_end_of(y - 1);
1367                 tdays -= ((pg_time_t) newy - y) * DAYSPERNYEAR;
1368                 tdays -= leapdays;
1369                 y = newy;
1370         }
1371
1372         /*
1373          * Given the range, we can now fearlessly cast...
1374          */
1375         idays = tdays;
1376         rem += offset - corr;
1377         while (rem < 0)
1378         {
1379                 rem += SECSPERDAY;
1380                 --idays;
1381         }
1382         while (rem >= SECSPERDAY)
1383         {
1384                 rem -= SECSPERDAY;
1385                 ++idays;
1386         }
1387         while (idays < 0)
1388         {
1389                 if (increment_overflow(&y, -1))
1390                         goto out_of_range;
1391                 idays += year_lengths[isleap(y)];
1392         }
1393         while (idays >= year_lengths[isleap(y)])
1394         {
1395                 idays -= year_lengths[isleap(y)];
1396                 if (increment_overflow(&y, 1))
1397                         goto out_of_range;
1398         }
1399         tmp->tm_year = y;
1400         if (increment_overflow(&tmp->tm_year, -TM_YEAR_BASE))
1401                 goto out_of_range;
1402         tmp->tm_yday = idays;
1403
1404         /*
1405          * The "extra" mods below avoid overflow problems.
1406          */
1407         tmp->tm_wday = EPOCH_WDAY +
1408                 ((y - EPOCH_YEAR) % DAYSPERWEEK) *
1409                 (DAYSPERNYEAR % DAYSPERWEEK) +
1410                 leaps_thru_end_of(y - 1) -
1411                 leaps_thru_end_of(EPOCH_YEAR - 1) +
1412                 idays;
1413         tmp->tm_wday %= DAYSPERWEEK;
1414         if (tmp->tm_wday < 0)
1415                 tmp->tm_wday += DAYSPERWEEK;
1416         tmp->tm_hour = (int) (rem / SECSPERHOUR);
1417         rem %= SECSPERHOUR;
1418         tmp->tm_min = (int) (rem / SECSPERMIN);
1419
1420         /*
1421          * A positive leap second requires a special representation. This uses
1422          * "... ??:59:60" et seq.
1423          */
1424         tmp->tm_sec = (int) (rem % SECSPERMIN) + hit;
1425         ip = mon_lengths[isleap(y)];
1426         for (tmp->tm_mon = 0; idays >= ip[tmp->tm_mon]; ++(tmp->tm_mon))
1427                 idays -= ip[tmp->tm_mon];
1428         tmp->tm_mday = (int) (idays + 1);
1429         tmp->tm_isdst = 0;
1430         tmp->tm_gmtoff = offset;
1431         return tmp;
1432
1433 out_of_range:
1434         errno = EOVERFLOW;
1435         return NULL;
1436 }
1437
1438 /*
1439  * Normalize logic courtesy Paul Eggert.
1440  */
1441
1442 static bool
1443 increment_overflow(int *ip, int j)
1444 {
1445         int const       i = *ip;
1446
1447         /*----------
1448          * If i >= 0 there can only be overflow if i + j > INT_MAX
1449          * or if j > INT_MAX - i; given i >= 0, INT_MAX - i cannot overflow.
1450          * If i < 0 there can only be overflow if i + j < INT_MIN
1451          * or if j < INT_MIN - i; given i < 0, INT_MIN - i cannot overflow.
1452          *----------
1453          */
1454         if ((i >= 0) ? (j > INT_MAX - i) : (j < INT_MIN - i))
1455                 return true;
1456         *ip += j;
1457         return false;
1458 }
1459
1460 static bool
1461 increment_overflow_time(pg_time_t *tp, int32 j)
1462 {
1463         /*----------
1464          * This is like
1465          * 'if (! (time_t_min <= *tp + j && *tp + j <= time_t_max)) ...',
1466          * except that it does the right thing even if *tp + j would overflow.
1467          *----------
1468          */
1469         if (!(j < 0
1470                   ? (TYPE_SIGNED(pg_time_t) ? time_t_min - j <= *tp : -1 - j < *tp)
1471                   : *tp <= time_t_max - j))
1472                 return true;
1473         *tp += j;
1474         return false;
1475 }
1476
1477 /*
1478  * Find the next DST transition time in the given zone after the given time
1479  *
1480  * *timep and *tz are input arguments, the other parameters are output values.
1481  *
1482  * When the function result is 1, *boundary is set to the pg_time_t
1483  * representation of the next DST transition time after *timep,
1484  * *before_gmtoff and *before_isdst are set to the GMT offset and isdst
1485  * state prevailing just before that boundary (in particular, the state
1486  * prevailing at *timep), and *after_gmtoff and *after_isdst are set to
1487  * the state prevailing just after that boundary.
1488  *
1489  * When the function result is 0, there is no known DST transition
1490  * after *timep, but *before_gmtoff and *before_isdst indicate the GMT
1491  * offset and isdst state prevailing at *timep.  (This would occur in
1492  * DST-less time zones, or if a zone has permanently ceased using DST.)
1493  *
1494  * A function result of -1 indicates failure (this case does not actually
1495  * occur in our current implementation).
1496  */
1497 int
1498 pg_next_dst_boundary(const pg_time_t *timep,
1499                                          long int *before_gmtoff,
1500                                          int *before_isdst,
1501                                          pg_time_t *boundary,
1502                                          long int *after_gmtoff,
1503                                          int *after_isdst,
1504                                          const pg_tz *tz)
1505 {
1506         const struct state *sp;
1507         const struct ttinfo *ttisp;
1508         int                     i;
1509         int                     j;
1510         const pg_time_t t = *timep;
1511
1512         sp = &tz->state;
1513         if (sp->timecnt == 0)
1514         {
1515                 /* non-DST zone, use lowest-numbered standard type */
1516                 i = 0;
1517                 while (sp->ttis[i].tt_isdst)
1518                         if (++i >= sp->typecnt)
1519                         {
1520                                 i = 0;
1521                                 break;
1522                         }
1523                 ttisp = &sp->ttis[i];
1524                 *before_gmtoff = ttisp->tt_gmtoff;
1525                 *before_isdst = ttisp->tt_isdst;
1526                 return 0;
1527         }
1528         if ((sp->goback && t < sp->ats[0]) ||
1529                 (sp->goahead && t > sp->ats[sp->timecnt - 1]))
1530         {
1531                 /* For values outside the transition table, extrapolate */
1532                 pg_time_t       newt = t;
1533                 pg_time_t       seconds;
1534                 pg_time_t       tcycles;
1535                 int64           icycles;
1536                 int                     result;
1537
1538                 if (t < sp->ats[0])
1539                         seconds = sp->ats[0] - t;
1540                 else
1541                         seconds = t - sp->ats[sp->timecnt - 1];
1542                 --seconds;
1543                 tcycles = seconds / YEARSPERREPEAT / AVGSECSPERYEAR;
1544                 ++tcycles;
1545                 icycles = tcycles;
1546                 if (tcycles - icycles >= 1 || icycles - tcycles >= 1)
1547                         return -1;
1548                 seconds = icycles;
1549                 seconds *= YEARSPERREPEAT;
1550                 seconds *= AVGSECSPERYEAR;
1551                 if (t < sp->ats[0])
1552                         newt += seconds;
1553                 else
1554                         newt -= seconds;
1555                 if (newt < sp->ats[0] ||
1556                         newt > sp->ats[sp->timecnt - 1])
1557                         return -1;                      /* "cannot happen" */
1558
1559                 result = pg_next_dst_boundary(&newt, before_gmtoff,
1560                                                                           before_isdst,
1561                                                                           boundary,
1562                                                                           after_gmtoff,
1563                                                                           after_isdst,
1564                                                                           tz);
1565                 if (t < sp->ats[0])
1566                         *boundary -= seconds;
1567                 else
1568                         *boundary += seconds;
1569                 return result;
1570         }
1571
1572         if (t >= sp->ats[sp->timecnt - 1])
1573         {
1574                 /* No known transition > t, so use last known segment's type */
1575                 i = sp->types[sp->timecnt - 1];
1576                 ttisp = &sp->ttis[i];
1577                 *before_gmtoff = ttisp->tt_gmtoff;
1578                 *before_isdst = ttisp->tt_isdst;
1579                 return 0;
1580         }
1581         if (t < sp->ats[0])
1582         {
1583                 /* For "before", use lowest-numbered standard type */
1584                 i = 0;
1585                 while (sp->ttis[i].tt_isdst)
1586                         if (++i >= sp->typecnt)
1587                         {
1588                                 i = 0;
1589                                 break;
1590                         }
1591                 ttisp = &sp->ttis[i];
1592                 *before_gmtoff = ttisp->tt_gmtoff;
1593                 *before_isdst = ttisp->tt_isdst;
1594                 *boundary = sp->ats[0];
1595                 /* And for "after", use the first segment's type */
1596                 i = sp->types[0];
1597                 ttisp = &sp->ttis[i];
1598                 *after_gmtoff = ttisp->tt_gmtoff;
1599                 *after_isdst = ttisp->tt_isdst;
1600                 return 1;
1601         }
1602         /* Else search to find the boundary following t */
1603         {
1604                 int                     lo = 1;
1605                 int                     hi = sp->timecnt - 1;
1606
1607                 while (lo < hi)
1608                 {
1609                         int                     mid = (lo + hi) >> 1;
1610
1611                         if (t < sp->ats[mid])
1612                                 hi = mid;
1613                         else
1614                                 lo = mid + 1;
1615                 }
1616                 i = lo;
1617         }
1618         j = sp->types[i - 1];
1619         ttisp = &sp->ttis[j];
1620         *before_gmtoff = ttisp->tt_gmtoff;
1621         *before_isdst = ttisp->tt_isdst;
1622         *boundary = sp->ats[i];
1623         j = sp->types[i];
1624         ttisp = &sp->ttis[j];
1625         *after_gmtoff = ttisp->tt_gmtoff;
1626         *after_isdst = ttisp->tt_isdst;
1627         return 1;
1628 }
1629
1630 /*
1631  * Identify a timezone abbreviation's meaning in the given zone
1632  *
1633  * Determine the GMT offset and DST flag associated with the abbreviation.
1634  * This is generally used only when the abbreviation has actually changed
1635  * meaning over time; therefore, we also take a UTC cutoff time, and return
1636  * the meaning in use at or most recently before that time, or the meaning
1637  * in first use after that time if the abbrev was never used before that.
1638  *
1639  * On success, returns true and sets *gmtoff and *isdst.  If the abbreviation
1640  * was never used at all in this zone, returns false.
1641  *
1642  * Note: abbrev is matched case-sensitively; it should be all-upper-case.
1643  */
1644 bool
1645 pg_interpret_timezone_abbrev(const char *abbrev,
1646                                                          const pg_time_t *timep,
1647                                                          long int *gmtoff,
1648                                                          int *isdst,
1649                                                          const pg_tz *tz)
1650 {
1651         const struct state *sp;
1652         const char *abbrs;
1653         const struct ttinfo *ttisp;
1654         int                     abbrind;
1655         int                     cutoff;
1656         int                     i;
1657         const pg_time_t t = *timep;
1658
1659         sp = &tz->state;
1660
1661         /*
1662          * Locate the abbreviation in the zone's abbreviation list.  We assume
1663          * there are not duplicates in the list.
1664          */
1665         abbrs = sp->chars;
1666         abbrind = 0;
1667         while (abbrind < sp->charcnt)
1668         {
1669                 if (strcmp(abbrev, abbrs + abbrind) == 0)
1670                         break;
1671                 while (abbrs[abbrind] != '\0')
1672                         abbrind++;
1673                 abbrind++;
1674         }
1675         if (abbrind >= sp->charcnt)
1676                 return false;                   /* not there! */
1677
1678         /*
1679          * Unlike pg_next_dst_boundary, we needn't sweat about extrapolation
1680          * (goback/goahead zones).  Finding the newest or oldest meaning of the
1681          * abbreviation should get us what we want, since extrapolation would just
1682          * be repeating the newest or oldest meanings.
1683          *
1684          * Use binary search to locate the first transition > cutoff time.
1685          */
1686         {
1687                 int                     lo = 0;
1688                 int                     hi = sp->timecnt;
1689
1690                 while (lo < hi)
1691                 {
1692                         int                     mid = (lo + hi) >> 1;
1693
1694                         if (t < sp->ats[mid])
1695                                 hi = mid;
1696                         else
1697                                 lo = mid + 1;
1698                 }
1699                 cutoff = lo;
1700         }
1701
1702         /*
1703          * Scan backwards to find the latest interval using the given abbrev
1704          * before the cutoff time.
1705          */
1706         for (i = cutoff - 1; i >= 0; i--)
1707         {
1708                 ttisp = &sp->ttis[sp->types[i]];
1709                 if (ttisp->tt_abbrind == abbrind)
1710                 {
1711                         *gmtoff = ttisp->tt_gmtoff;
1712                         *isdst = ttisp->tt_isdst;
1713                         return true;
1714                 }
1715         }
1716
1717         /*
1718          * Not there, so scan forwards to find the first one after.
1719          */
1720         for (i = cutoff; i < sp->timecnt; i++)
1721         {
1722                 ttisp = &sp->ttis[sp->types[i]];
1723                 if (ttisp->tt_abbrind == abbrind)
1724                 {
1725                         *gmtoff = ttisp->tt_gmtoff;
1726                         *isdst = ttisp->tt_isdst;
1727                         return true;
1728                 }
1729         }
1730
1731         return false;                           /* hm, not actually used in any interval? */
1732 }
1733
1734 /*
1735  * If the given timezone uses only one GMT offset, store that offset
1736  * into *gmtoff and return true, else return false.
1737  */
1738 bool
1739 pg_get_timezone_offset(const pg_tz *tz, long int *gmtoff)
1740 {
1741         /*
1742          * The zone could have more than one ttinfo, if it's historically used
1743          * more than one abbreviation.  We return true as long as they all have
1744          * the same gmtoff.
1745          */
1746         const struct state *sp;
1747         int                     i;
1748
1749         sp = &tz->state;
1750         for (i = 1; i < sp->typecnt; i++)
1751         {
1752                 if (sp->ttis[i].tt_gmtoff != sp->ttis[0].tt_gmtoff)
1753                         return false;
1754         }
1755         *gmtoff = sp->ttis[0].tt_gmtoff;
1756         return true;
1757 }
1758
1759 /*
1760  * Return the name of the current timezone
1761  */
1762 const char *
1763 pg_get_timezone_name(pg_tz *tz)
1764 {
1765         if (tz)
1766                 return tz->TZname;
1767         return NULL;
1768 }
1769
1770 /*
1771  * Check whether timezone is acceptable.
1772  *
1773  * What we are doing here is checking for leap-second-aware timekeeping.
1774  * We need to reject such TZ settings because they'll wreak havoc with our
1775  * date/time arithmetic.
1776  */
1777 bool
1778 pg_tz_acceptable(pg_tz *tz)
1779 {
1780         struct pg_tm *tt;
1781         pg_time_t       time2000;
1782
1783         /*
1784          * To detect leap-second timekeeping, run pg_localtime for what should be
1785          * GMT midnight, 2000-01-01.  Insist that the tm_sec value be zero; any
1786          * other result has to be due to leap seconds.
1787          */
1788         time2000 = (POSTGRES_EPOCH_JDATE - UNIX_EPOCH_JDATE) * SECS_PER_DAY;
1789         tt = pg_localtime(&time2000, tz);
1790         if (!tt || tt->tm_sec != 0)
1791                 return false;
1792
1793         return true;
1794 }