]> granicus.if.org Git - postgresql/blob - src/timezone/localtime.c
Fix typos in comments.
[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 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 *lsp = malloc(sizeof *lsp);
540
541         if (!lsp)
542                 return errno;
543         else
544         {
545                 int                     err = tzloadbody(name, canonname, sp, doextend, lsp);
546
547                 free(lsp);
548                 return err;
549         }
550 }
551
552 static bool
553 typesequiv(const struct state * sp, int a, int b)
554 {
555         bool            result;
556
557         if (sp == NULL ||
558                 a < 0 || a >= sp->typecnt ||
559                 b < 0 || b >= sp->typecnt)
560                 result = false;
561         else
562         {
563                 const struct ttinfo *ap = &sp->ttis[a];
564                 const struct ttinfo *bp = &sp->ttis[b];
565
566                 result = ap->tt_gmtoff == bp->tt_gmtoff &&
567                         ap->tt_isdst == bp->tt_isdst &&
568                         ap->tt_ttisstd == bp->tt_ttisstd &&
569                         ap->tt_ttisgmt == bp->tt_ttisgmt &&
570                         strcmp(&sp->chars[ap->tt_abbrind],
571                                    &sp->chars[bp->tt_abbrind]) == 0;
572         }
573         return result;
574 }
575
576 static const int mon_lengths[2][MONSPERYEAR] = {
577         {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31},
578         {31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}
579 };
580
581 static const int year_lengths[2] = {
582         DAYSPERNYEAR, DAYSPERLYEAR
583 };
584
585 /*
586  * Given a pointer into a time zone string, scan until a character that is not
587  * a valid character in a zone name is found. Return a pointer to that
588  * character.
589  */
590 static const char *
591 getzname(const char *strp)
592 {
593         char            c;
594
595         while ((c = *strp) != '\0' && !is_digit(c) && c != ',' && c != '-' &&
596                    c != '+')
597                 ++strp;
598         return strp;
599 }
600
601 /*
602  * Given a pointer into an extended time zone string, scan until the ending
603  * delimiter of the zone name is located. Return a pointer to the delimiter.
604  *
605  * As with getzname above, the legal character set is actually quite
606  * restricted, with other characters producing undefined results.
607  * We don't do any checking here; checking is done later in common-case code.
608  */
609 static const char *
610 getqzname(const char *strp, int delim)
611 {
612         int                     c;
613
614         while ((c = *strp) != '\0' && c != delim)
615                 ++strp;
616         return strp;
617 }
618
619 /*
620  * Given a pointer into a time zone string, extract a number from that string.
621  * Check that the number is within a specified range; if it is not, return
622  * NULL.
623  * Otherwise, return a pointer to the first character not part of the number.
624  */
625 static const char *
626 getnum(const char *strp, int *nump, int min, int max)
627 {
628         char            c;
629         int                     num;
630
631         if (strp == NULL || !is_digit(c = *strp))
632                 return NULL;
633         num = 0;
634         do
635         {
636                 num = num * 10 + (c - '0');
637                 if (num > max)
638                         return NULL;            /* illegal value */
639                 c = *++strp;
640         } while (is_digit(c));
641         if (num < min)
642                 return NULL;                    /* illegal value */
643         *nump = num;
644         return strp;
645 }
646
647 /*
648  * Given a pointer into a time zone string, extract a number of seconds,
649  * in hh[:mm[:ss]] form, from the string.
650  * If any error occurs, return NULL.
651  * Otherwise, return a pointer to the first character not part of the number
652  * of seconds.
653  */
654 static const char *
655 getsecs(const char *strp, int32 *secsp)
656 {
657         int                     num;
658
659         /*
660          * 'HOURSPERDAY * DAYSPERWEEK - 1' allows quasi-Posix rules like
661          * "M10.4.6/26", which does not conform to Posix, but which specifies the
662          * equivalent of "02:00 on the first Sunday on or after 23 Oct".
663          */
664         strp = getnum(strp, &num, 0, HOURSPERDAY * DAYSPERWEEK - 1);
665         if (strp == NULL)
666                 return NULL;
667         *secsp = num * (int32) SECSPERHOUR;
668         if (*strp == ':')
669         {
670                 ++strp;
671                 strp = getnum(strp, &num, 0, MINSPERHOUR - 1);
672                 if (strp == NULL)
673                         return NULL;
674                 *secsp += num * SECSPERMIN;
675                 if (*strp == ':')
676                 {
677                         ++strp;
678                         /* 'SECSPERMIN' allows for leap seconds.  */
679                         strp = getnum(strp, &num, 0, SECSPERMIN);
680                         if (strp == NULL)
681                                 return NULL;
682                         *secsp += num;
683                 }
684         }
685         return strp;
686 }
687
688 /*
689  * Given a pointer into a time zone string, extract an offset, in
690  * [+-]hh[:mm[:ss]] form, from the string.
691  * If any error occurs, return NULL.
692  * Otherwise, return a pointer to the first character not part of the time.
693  */
694 static const char *
695 getoffset(const char *strp, int32 *offsetp)
696 {
697         bool            neg = false;
698
699         if (*strp == '-')
700         {
701                 neg = true;
702                 ++strp;
703         }
704         else if (*strp == '+')
705                 ++strp;
706         strp = getsecs(strp, offsetp);
707         if (strp == NULL)
708                 return NULL;                    /* illegal time */
709         if (neg)
710                 *offsetp = -*offsetp;
711         return strp;
712 }
713
714 /*
715  * Given a pointer into a time zone string, extract a rule in the form
716  * date[/time]. See POSIX section 8 for the format of "date" and "time".
717  * If a valid rule is not found, return NULL.
718  * Otherwise, return a pointer to the first character not part of the rule.
719  */
720 static const char *
721 getrule(const char *strp, struct rule * rulep)
722 {
723         if (*strp == 'J')
724         {
725                 /*
726                  * Julian day.
727                  */
728                 rulep->r_type = JULIAN_DAY;
729                 ++strp;
730                 strp = getnum(strp, &rulep->r_day, 1, DAYSPERNYEAR);
731         }
732         else if (*strp == 'M')
733         {
734                 /*
735                  * Month, week, day.
736                  */
737                 rulep->r_type = MONTH_NTH_DAY_OF_WEEK;
738                 ++strp;
739                 strp = getnum(strp, &rulep->r_mon, 1, MONSPERYEAR);
740                 if (strp == NULL)
741                         return NULL;
742                 if (*strp++ != '.')
743                         return NULL;
744                 strp = getnum(strp, &rulep->r_week, 1, 5);
745                 if (strp == NULL)
746                         return NULL;
747                 if (*strp++ != '.')
748                         return NULL;
749                 strp = getnum(strp, &rulep->r_day, 0, DAYSPERWEEK - 1);
750         }
751         else if (is_digit(*strp))
752         {
753                 /*
754                  * Day of year.
755                  */
756                 rulep->r_type = DAY_OF_YEAR;
757                 strp = getnum(strp, &rulep->r_day, 0, DAYSPERLYEAR - 1);
758         }
759         else
760                 return NULL;                    /* invalid format */
761         if (strp == NULL)
762                 return NULL;
763         if (*strp == '/')
764         {
765                 /*
766                  * Time specified.
767                  */
768                 ++strp;
769                 strp = getoffset(strp, &rulep->r_time);
770         }
771         else
772                 rulep->r_time = 2 * SECSPERHOUR;                /* default = 2:00:00 */
773         return strp;
774 }
775
776 /*
777  * Given a year, a rule, and the offset from UT at the time that rule takes
778  * effect, calculate the year-relative time that rule takes effect.
779  */
780 static int32
781 transtime(int year, const struct rule * rulep,
782                   int32 offset)
783 {
784         bool            leapyear;
785         int32           value;
786         int                     i,
787                                 d,
788                                 m1,
789                                 yy0,
790                                 yy1,
791                                 yy2,
792                                 dow;
793
794         INITIALIZE(value);
795         leapyear = isleap(year);
796         switch (rulep->r_type)
797         {
798
799                 case JULIAN_DAY:
800
801                         /*
802                          * Jn - Julian day, 1 == January 1, 60 == March 1 even in leap
803                          * years. In non-leap years, or if the day number is 59 or less,
804                          * just add SECSPERDAY times the day number-1 to the time of
805                          * January 1, midnight, to get the day.
806                          */
807                         value = (rulep->r_day - 1) * SECSPERDAY;
808                         if (leapyear && rulep->r_day >= 60)
809                                 value += SECSPERDAY;
810                         break;
811
812                 case DAY_OF_YEAR:
813
814                         /*
815                          * n - day of year. Just add SECSPERDAY times the day number to
816                          * the time of January 1, midnight, to get the day.
817                          */
818                         value = rulep->r_day * SECSPERDAY;
819                         break;
820
821                 case MONTH_NTH_DAY_OF_WEEK:
822
823                         /*
824                          * Mm.n.d - nth "dth day" of month m.
825                          */
826
827                         /*
828                          * Use Zeller's Congruence to get day-of-week of first day of
829                          * month.
830                          */
831                         m1 = (rulep->r_mon + 9) % 12 + 1;
832                         yy0 = (rulep->r_mon <= 2) ? (year - 1) : year;
833                         yy1 = yy0 / 100;
834                         yy2 = yy0 % 100;
835                         dow = ((26 * m1 - 2) / 10 +
836                                    1 + yy2 + yy2 / 4 + yy1 / 4 - 2 * yy1) % 7;
837                         if (dow < 0)
838                                 dow += DAYSPERWEEK;
839
840                         /*
841                          * "dow" is the day-of-week of the first day of the month. Get the
842                          * day-of-month (zero-origin) of the first "dow" day of the month.
843                          */
844                         d = rulep->r_day - dow;
845                         if (d < 0)
846                                 d += DAYSPERWEEK;
847                         for (i = 1; i < rulep->r_week; ++i)
848                         {
849                                 if (d + DAYSPERWEEK >=
850                                         mon_lengths[(int) leapyear][rulep->r_mon - 1])
851                                         break;
852                                 d += DAYSPERWEEK;
853                         }
854
855                         /*
856                          * "d" is the day-of-month (zero-origin) of the day we want.
857                          */
858                         value = d * SECSPERDAY;
859                         for (i = 0; i < rulep->r_mon - 1; ++i)
860                                 value += mon_lengths[(int) leapyear][i] * SECSPERDAY;
861                         break;
862         }
863
864         /*
865          * "value" is the year-relative time of 00:00:00 UT on the day in
866          * question. To get the year-relative time of the specified local time on
867          * that day, add the transition time and the current offset from UT.
868          */
869         return value + rulep->r_time + offset;
870 }
871
872 /*
873  * Given a POSIX section 8-style TZ string, fill in the rule tables as
874  * appropriate.
875  * Returns true on success, false on failure.
876  */
877 bool
878 tzparse(const char *name, struct state * sp, bool lastditch)
879 {
880         const char *stdname;
881         const char *dstname = NULL;
882         size_t          stdlen;
883         size_t          dstlen;
884         size_t          charcnt;
885         int32           stdoffset;
886         int32           dstoffset;
887         char       *cp;
888         bool            load_ok;
889
890         stdname = name;
891         if (lastditch)
892         {
893                 /*
894                  * This is intentionally somewhat different from the IANA code.  We do
895                  * not want to invoke tzload() in the lastditch case: we can't assume
896                  * pg_open_tzfile() is sane yet, and we don't care about leap seconds
897                  * anyway.
898                  */
899                 stdlen = strlen(name);  /* length of standard zone name */
900                 name += stdlen;
901                 if (stdlen >= sizeof sp->chars)
902                         stdlen = (sizeof sp->chars) - 1;
903                 charcnt = stdlen + 1;
904                 stdoffset = 0;
905                 sp->goback = sp->goahead = false;               /* simulate failed tzload() */
906                 load_ok = false;
907         }
908         else
909         {
910                 if (*name == '<')
911                 {
912                         name++;
913                         stdname = name;
914                         name = getqzname(name, '>');
915                         if (*name != '>')
916                                 return false;
917                         stdlen = name - stdname;
918                         name++;
919                 }
920                 else
921                 {
922                         name = getzname(name);
923                         stdlen = name - stdname;
924                 }
925                 if (*name == '\0')              /* we allow empty STD abbrev, unlike IANA */
926                         return false;
927                 name = getoffset(name, &stdoffset);
928                 if (name == NULL)
929                         return false;
930                 charcnt = stdlen + 1;
931                 if (sizeof sp->chars < charcnt)
932                         return false;
933                 load_ok = tzload(TZDEFRULES, NULL, sp, false) == 0;
934         }
935         if (!load_ok)
936                 sp->leapcnt = 0;                /* so, we're off a little */
937         if (*name != '\0')
938         {
939                 if (*name == '<')
940                 {
941                         dstname = ++name;
942                         name = getqzname(name, '>');
943                         if (*name != '>')
944                                 return false;
945                         dstlen = name - dstname;
946                         name++;
947                 }
948                 else
949                 {
950                         dstname = name;
951                         name = getzname(name);
952                         dstlen = name - dstname;        /* length of DST zone name */
953                 }
954                 if (!dstlen)
955                         return false;
956                 charcnt += dstlen + 1;
957                 if (sizeof sp->chars < charcnt)
958                         return false;
959                 if (*name != '\0' && *name != ',' && *name != ';')
960                 {
961                         name = getoffset(name, &dstoffset);
962                         if (name == NULL)
963                                 return false;
964                 }
965                 else
966                         dstoffset = stdoffset - SECSPERHOUR;
967                 if (*name == '\0' && !load_ok)
968                         name = TZDEFRULESTRING;
969                 if (*name == ',' || *name == ';')
970                 {
971                         struct rule start;
972                         struct rule end;
973                         int                     year;
974                         int                     yearlim;
975                         int                     timecnt;
976                         pg_time_t       janfirst;
977
978                         ++name;
979                         if ((name = getrule(name, &start)) == NULL)
980                                 return false;
981                         if (*name++ != ',')
982                                 return false;
983                         if ((name = getrule(name, &end)) == NULL)
984                                 return false;
985                         if (*name != '\0')
986                                 return false;
987                         sp->typecnt = 2;        /* standard time and DST */
988
989                         /*
990                          * Two transitions per year, from EPOCH_YEAR forward.
991                          */
992                         init_ttinfo(&sp->ttis[0], -dstoffset, true, stdlen + 1);
993                         init_ttinfo(&sp->ttis[1], -stdoffset, false, 0);
994                         sp->defaulttype = 0;
995                         timecnt = 0;
996                         janfirst = 0;
997                         yearlim = EPOCH_YEAR + YEARSPERREPEAT;
998                         for (year = EPOCH_YEAR; year < yearlim; year++)
999                         {
1000                                 int32
1001                                                         starttime = transtime(year, &start, stdoffset),
1002                                                         endtime = transtime(year, &end, dstoffset);
1003                                 int32
1004                                                         yearsecs = (year_lengths[isleap(year)]
1005                                                                                 * SECSPERDAY);
1006                                 bool            reversed = endtime < starttime;
1007
1008                                 if (reversed)
1009                                 {
1010                                         int32           swap = starttime;
1011
1012                                         starttime = endtime;
1013                                         endtime = swap;
1014                                 }
1015                                 if (reversed
1016                                         || (starttime < endtime
1017                                                 && (endtime - starttime
1018                                                         < (yearsecs
1019                                                            + (stdoffset - dstoffset)))))
1020                                 {
1021                                         if (TZ_MAX_TIMES - 2 < timecnt)
1022                                                 break;
1023                                         yearlim = year + YEARSPERREPEAT + 1;
1024                                         sp->ats[timecnt] = janfirst;
1025                                         if (increment_overflow_time
1026                                                 (&sp->ats[timecnt], starttime))
1027                                                 break;
1028                                         sp->types[timecnt++] = reversed;
1029                                         sp->ats[timecnt] = janfirst;
1030                                         if (increment_overflow_time
1031                                                 (&sp->ats[timecnt], endtime))
1032                                                 break;
1033                                         sp->types[timecnt++] = !reversed;
1034                                 }
1035                                 if (increment_overflow_time(&janfirst, yearsecs))
1036                                         break;
1037                         }
1038                         sp->timecnt = timecnt;
1039                         if (!timecnt)
1040                                 sp->typecnt = 1;        /* Perpetual DST.  */
1041                 }
1042                 else
1043                 {
1044                         int32           theirstdoffset;
1045                         int32           theirdstoffset;
1046                         int32           theiroffset;
1047                         bool            isdst;
1048                         int                     i;
1049                         int                     j;
1050
1051                         if (*name != '\0')
1052                                 return false;
1053
1054                         /*
1055                          * Initial values of theirstdoffset and theirdstoffset.
1056                          */
1057                         theirstdoffset = 0;
1058                         for (i = 0; i < sp->timecnt; ++i)
1059                         {
1060                                 j = sp->types[i];
1061                                 if (!sp->ttis[j].tt_isdst)
1062                                 {
1063                                         theirstdoffset =
1064                                                 -sp->ttis[j].tt_gmtoff;
1065                                         break;
1066                                 }
1067                         }
1068                         theirdstoffset = 0;
1069                         for (i = 0; i < sp->timecnt; ++i)
1070                         {
1071                                 j = sp->types[i];
1072                                 if (sp->ttis[j].tt_isdst)
1073                                 {
1074                                         theirdstoffset =
1075                                                 -sp->ttis[j].tt_gmtoff;
1076                                         break;
1077                                 }
1078                         }
1079
1080                         /*
1081                          * Initially we're assumed to be in standard time.
1082                          */
1083                         isdst = false;
1084                         theiroffset = theirstdoffset;
1085
1086                         /*
1087                          * Now juggle transition times and types tracking offsets as you
1088                          * do.
1089                          */
1090                         for (i = 0; i < sp->timecnt; ++i)
1091                         {
1092                                 j = sp->types[i];
1093                                 sp->types[i] = sp->ttis[j].tt_isdst;
1094                                 if (sp->ttis[j].tt_ttisgmt)
1095                                 {
1096                                         /* No adjustment to transition time */
1097                                 }
1098                                 else
1099                                 {
1100                                         /*
1101                                          * If summer time is in effect, and the transition time
1102                                          * was not specified as standard time, add the summer time
1103                                          * offset to the transition time; otherwise, add the
1104                                          * standard time offset to the transition time.
1105                                          */
1106
1107                                         /*
1108                                          * Transitions from DST to DDST will effectively disappear
1109                                          * since POSIX provides for only one DST offset.
1110                                          */
1111                                         if (isdst && !sp->ttis[j].tt_ttisstd)
1112                                         {
1113                                                 sp->ats[i] += dstoffset -
1114                                                         theirdstoffset;
1115                                         }
1116                                         else
1117                                         {
1118                                                 sp->ats[i] += stdoffset -
1119                                                         theirstdoffset;
1120                                         }
1121                                 }
1122                                 theiroffset = -sp->ttis[j].tt_gmtoff;
1123                                 if (sp->ttis[j].tt_isdst)
1124                                         theirdstoffset = theiroffset;
1125                                 else
1126                                         theirstdoffset = theiroffset;
1127                         }
1128
1129                         /*
1130                          * Finally, fill in ttis.
1131                          */
1132                         init_ttinfo(&sp->ttis[0], -stdoffset, false, 0);
1133                         init_ttinfo(&sp->ttis[1], -dstoffset, true, stdlen + 1);
1134                         sp->typecnt = 2;
1135                         sp->defaulttype = 0;
1136                 }
1137         }
1138         else
1139         {
1140                 dstlen = 0;
1141                 sp->typecnt = 1;                /* only standard time */
1142                 sp->timecnt = 0;
1143                 init_ttinfo(&sp->ttis[0], -stdoffset, false, 0);
1144                 sp->defaulttype = 0;
1145         }
1146         sp->charcnt = charcnt;
1147         cp = sp->chars;
1148         memcpy(cp, stdname, stdlen);
1149         cp += stdlen;
1150         *cp++ = '\0';
1151         if (dstlen != 0)
1152         {
1153                 memcpy(cp, dstname, dstlen);
1154                 *(cp + dstlen) = '\0';
1155         }
1156         return true;
1157 }
1158
1159 static void
1160 gmtload(struct state * sp)
1161 {
1162         if (tzload(gmt, NULL, sp, true) != 0)
1163                 tzparse(gmt, sp, true);
1164 }
1165
1166
1167 /*
1168  * The easy way to behave "as if no library function calls" localtime
1169  * is to not call it, so we drop its guts into "localsub", which can be
1170  * freely called. (And no, the PANS doesn't require the above behavior,
1171  * but it *is* desirable.)
1172  */
1173 static struct pg_tm *
1174 localsub(struct state const * sp, pg_time_t const * timep,
1175                  struct pg_tm * tmp)
1176 {
1177         const struct ttinfo *ttisp;
1178         int                     i;
1179         struct pg_tm *result;
1180         const pg_time_t t = *timep;
1181
1182         if (sp == NULL)
1183                 return gmtsub(timep, 0, tmp);
1184         if ((sp->goback && t < sp->ats[0]) ||
1185                 (sp->goahead && t > sp->ats[sp->timecnt - 1]))
1186         {
1187                 pg_time_t       newt = t;
1188                 pg_time_t       seconds;
1189                 pg_time_t       years;
1190
1191                 if (t < sp->ats[0])
1192                         seconds = sp->ats[0] - t;
1193                 else
1194                         seconds = t - sp->ats[sp->timecnt - 1];
1195                 --seconds;
1196                 years = (seconds / SECSPERREPEAT + 1) * YEARSPERREPEAT;
1197                 seconds = years * AVGSECSPERYEAR;
1198                 if (t < sp->ats[0])
1199                         newt += seconds;
1200                 else
1201                         newt -= seconds;
1202                 if (newt < sp->ats[0] ||
1203                         newt > sp->ats[sp->timecnt - 1])
1204                         return NULL;            /* "cannot happen" */
1205                 result = localsub(sp, &newt, tmp);
1206                 if (result)
1207                 {
1208                         int64           newy;
1209
1210                         newy = result->tm_year;
1211                         if (t < sp->ats[0])
1212                                 newy -= years;
1213                         else
1214                                 newy += years;
1215                         if (!(INT_MIN <= newy && newy <= INT_MAX))
1216                                 return NULL;
1217                         result->tm_year = newy;
1218                 }
1219                 return result;
1220         }
1221         if (sp->timecnt == 0 || t < sp->ats[0])
1222         {
1223                 i = sp->defaulttype;
1224         }
1225         else
1226         {
1227                 int                     lo = 1;
1228                 int                     hi = sp->timecnt;
1229
1230                 while (lo < hi)
1231                 {
1232                         int                     mid = (lo + hi) >> 1;
1233
1234                         if (t < sp->ats[mid])
1235                                 hi = mid;
1236                         else
1237                                 lo = mid + 1;
1238                 }
1239                 i = (int) sp->types[lo - 1];
1240         }
1241         ttisp = &sp->ttis[i];
1242
1243         result = timesub(&t, ttisp->tt_gmtoff, sp, tmp);
1244         if (result)
1245         {
1246                 result->tm_isdst = ttisp->tt_isdst;
1247                 result->tm_zone = (char *) &sp->chars[ttisp->tt_abbrind];
1248         }
1249         return result;
1250 }
1251
1252
1253 struct pg_tm *
1254 pg_localtime(const pg_time_t *timep, const pg_tz *tz)
1255 {
1256         return localsub(&tz->state, timep, &tm);
1257 }
1258
1259
1260 /*
1261  * gmtsub is to gmtime as localsub is to localtime.
1262  *
1263  * Except we have a private "struct state" for GMT, so no sp is passed in.
1264  */
1265 static struct pg_tm *
1266 gmtsub(pg_time_t const * timep, int32 offset, struct pg_tm * tmp)
1267 {
1268         struct pg_tm *result;
1269
1270         /* GMT timezone state data is kept here */
1271         static struct state gmtmem;
1272         static bool gmt_is_set = false;
1273 #define gmtptr          (&gmtmem)
1274
1275         if (!gmt_is_set)
1276         {
1277                 gmt_is_set = true;
1278                 gmtload(gmtptr);
1279         }
1280         result = timesub(timep, offset, gmtptr, tmp);
1281
1282         /*
1283          * Could get fancy here and deliver something such as "+xx" or "-xx" if
1284          * offset is non-zero, but this is no time for a treasure hunt.
1285          */
1286         if (offset != 0)
1287                 tmp->tm_zone = wildabbr;
1288         else
1289                 tmp->tm_zone = gmtptr->chars;
1290
1291         return result;
1292 }
1293
1294 struct pg_tm *
1295 pg_gmtime(const pg_time_t *timep)
1296 {
1297         return gmtsub(timep, 0, &tm);
1298 }
1299
1300 /*
1301  * Return the number of leap years through the end of the given year
1302  * where, to make the math easy, the answer for year zero is defined as zero.
1303  */
1304 static int
1305 leaps_thru_end_of(const int y)
1306 {
1307         return (y >= 0) ? (y / 4 - y / 100 + y / 400) :
1308                 -(leaps_thru_end_of(-(y + 1)) + 1);
1309 }
1310
1311 static struct pg_tm *
1312 timesub(const pg_time_t *timep, int32 offset,
1313                 const struct state * sp, struct pg_tm * tmp)
1314 {
1315         const struct lsinfo *lp;
1316         pg_time_t       tdays;
1317         int                     idays;                  /* unsigned would be so 2003 */
1318         int64           rem;
1319         int                     y;
1320         const int  *ip;
1321         int64           corr;
1322         bool            hit;
1323         int                     i;
1324
1325         corr = 0;
1326         hit = false;
1327         i = (sp == NULL) ? 0 : sp->leapcnt;
1328         while (--i >= 0)
1329         {
1330                 lp = &sp->lsis[i];
1331                 if (*timep >= lp->ls_trans)
1332                 {
1333                         if (*timep == lp->ls_trans)
1334                         {
1335                                 hit = ((i == 0 && lp->ls_corr > 0) ||
1336                                            lp->ls_corr > sp->lsis[i - 1].ls_corr);
1337                                 if (hit)
1338                                         while (i > 0 &&
1339                                                    sp->lsis[i].ls_trans ==
1340                                                    sp->lsis[i - 1].ls_trans + 1 &&
1341                                                    sp->lsis[i].ls_corr ==
1342                                                    sp->lsis[i - 1].ls_corr + 1)
1343                                         {
1344                                                 ++hit;
1345                                                 --i;
1346                                         }
1347                         }
1348                         corr = lp->ls_corr;
1349                         break;
1350                 }
1351         }
1352         y = EPOCH_YEAR;
1353         tdays = *timep / SECSPERDAY;
1354         rem = *timep % SECSPERDAY;
1355         while (tdays < 0 || tdays >= year_lengths[isleap(y)])
1356         {
1357                 int                     newy;
1358                 pg_time_t       tdelta;
1359                 int                     idelta;
1360                 int                     leapdays;
1361
1362                 tdelta = tdays / DAYSPERLYEAR;
1363                 if (!((!TYPE_SIGNED(pg_time_t) ||INT_MIN <= tdelta)
1364                           && tdelta <= INT_MAX))
1365                         goto out_of_range;
1366                 idelta = tdelta;
1367                 if (idelta == 0)
1368                         idelta = (tdays < 0) ? -1 : 1;
1369                 newy = y;
1370                 if (increment_overflow(&newy, idelta))
1371                         goto out_of_range;
1372                 leapdays = leaps_thru_end_of(newy - 1) -
1373                         leaps_thru_end_of(y - 1);
1374                 tdays -= ((pg_time_t) newy - y) * DAYSPERNYEAR;
1375                 tdays -= leapdays;
1376                 y = newy;
1377         }
1378
1379         /*
1380          * Given the range, we can now fearlessly cast...
1381          */
1382         idays = tdays;
1383         rem += offset - corr;
1384         while (rem < 0)
1385         {
1386                 rem += SECSPERDAY;
1387                 --idays;
1388         }
1389         while (rem >= SECSPERDAY)
1390         {
1391                 rem -= SECSPERDAY;
1392                 ++idays;
1393         }
1394         while (idays < 0)
1395         {
1396                 if (increment_overflow(&y, -1))
1397                         goto out_of_range;
1398                 idays += year_lengths[isleap(y)];
1399         }
1400         while (idays >= year_lengths[isleap(y)])
1401         {
1402                 idays -= year_lengths[isleap(y)];
1403                 if (increment_overflow(&y, 1))
1404                         goto out_of_range;
1405         }
1406         tmp->tm_year = y;
1407         if (increment_overflow(&tmp->tm_year, -TM_YEAR_BASE))
1408                 goto out_of_range;
1409         tmp->tm_yday = idays;
1410
1411         /*
1412          * The "extra" mods below avoid overflow problems.
1413          */
1414         tmp->tm_wday = EPOCH_WDAY +
1415                 ((y - EPOCH_YEAR) % DAYSPERWEEK) *
1416                 (DAYSPERNYEAR % DAYSPERWEEK) +
1417                 leaps_thru_end_of(y - 1) -
1418                 leaps_thru_end_of(EPOCH_YEAR - 1) +
1419                 idays;
1420         tmp->tm_wday %= DAYSPERWEEK;
1421         if (tmp->tm_wday < 0)
1422                 tmp->tm_wday += DAYSPERWEEK;
1423         tmp->tm_hour = (int) (rem / SECSPERHOUR);
1424         rem %= SECSPERHOUR;
1425         tmp->tm_min = (int) (rem / SECSPERMIN);
1426
1427         /*
1428          * A positive leap second requires a special representation. This uses
1429          * "... ??:59:60" et seq.
1430          */
1431         tmp->tm_sec = (int) (rem % SECSPERMIN) + hit;
1432         ip = mon_lengths[isleap(y)];
1433         for (tmp->tm_mon = 0; idays >= ip[tmp->tm_mon]; ++(tmp->tm_mon))
1434                 idays -= ip[tmp->tm_mon];
1435         tmp->tm_mday = (int) (idays + 1);
1436         tmp->tm_isdst = 0;
1437         tmp->tm_gmtoff = offset;
1438         return tmp;
1439
1440 out_of_range:
1441         errno = EOVERFLOW;
1442         return NULL;
1443 }
1444
1445 /*
1446  * Normalize logic courtesy Paul Eggert.
1447  */
1448
1449 static bool
1450 increment_overflow(int *ip, int j)
1451 {
1452         int const       i = *ip;
1453
1454         /*----------
1455          * If i >= 0 there can only be overflow if i + j > INT_MAX
1456          * or if j > INT_MAX - i; given i >= 0, INT_MAX - i cannot overflow.
1457          * If i < 0 there can only be overflow if i + j < INT_MIN
1458          * or if j < INT_MIN - i; given i < 0, INT_MIN - i cannot overflow.
1459          *----------
1460          */
1461         if ((i >= 0) ? (j > INT_MAX - i) : (j < INT_MIN - i))
1462                 return true;
1463         *ip += j;
1464         return false;
1465 }
1466
1467 static bool
1468 increment_overflow_time(pg_time_t *tp, int32 j)
1469 {
1470         /*----------
1471          * This is like
1472          * 'if (! (time_t_min <= *tp + j && *tp + j <= time_t_max)) ...',
1473          * except that it does the right thing even if *tp + j would overflow.
1474          *----------
1475          */
1476         if (!(j < 0
1477                   ? (TYPE_SIGNED(pg_time_t) ? time_t_min - j <= *tp : -1 - j < *tp)
1478                   : *tp <= time_t_max - j))
1479                 return true;
1480         *tp += j;
1481         return false;
1482 }
1483
1484 /*
1485  * Find the next DST transition time in the given zone after the given time
1486  *
1487  * *timep and *tz are input arguments, the other parameters are output values.
1488  *
1489  * When the function result is 1, *boundary is set to the pg_time_t
1490  * representation of the next DST transition time after *timep,
1491  * *before_gmtoff and *before_isdst are set to the GMT offset and isdst
1492  * state prevailing just before that boundary (in particular, the state
1493  * prevailing at *timep), and *after_gmtoff and *after_isdst are set to
1494  * the state prevailing just after that boundary.
1495  *
1496  * When the function result is 0, there is no known DST transition
1497  * after *timep, but *before_gmtoff and *before_isdst indicate the GMT
1498  * offset and isdst state prevailing at *timep.  (This would occur in
1499  * DST-less time zones, or if a zone has permanently ceased using DST.)
1500  *
1501  * A function result of -1 indicates failure (this case does not actually
1502  * occur in our current implementation).
1503  */
1504 int
1505 pg_next_dst_boundary(const pg_time_t *timep,
1506                                          long int *before_gmtoff,
1507                                          int *before_isdst,
1508                                          pg_time_t *boundary,
1509                                          long int *after_gmtoff,
1510                                          int *after_isdst,
1511                                          const pg_tz *tz)
1512 {
1513         const struct state *sp;
1514         const struct ttinfo *ttisp;
1515         int                     i;
1516         int                     j;
1517         const pg_time_t t = *timep;
1518
1519         sp = &tz->state;
1520         if (sp->timecnt == 0)
1521         {
1522                 /* non-DST zone, use lowest-numbered standard type */
1523                 i = 0;
1524                 while (sp->ttis[i].tt_isdst)
1525                         if (++i >= sp->typecnt)
1526                         {
1527                                 i = 0;
1528                                 break;
1529                         }
1530                 ttisp = &sp->ttis[i];
1531                 *before_gmtoff = ttisp->tt_gmtoff;
1532                 *before_isdst = ttisp->tt_isdst;
1533                 return 0;
1534         }
1535         if ((sp->goback && t < sp->ats[0]) ||
1536                 (sp->goahead && t > sp->ats[sp->timecnt - 1]))
1537         {
1538                 /* For values outside the transition table, extrapolate */
1539                 pg_time_t       newt = t;
1540                 pg_time_t       seconds;
1541                 pg_time_t       tcycles;
1542                 int64           icycles;
1543                 int                     result;
1544
1545                 if (t < sp->ats[0])
1546                         seconds = sp->ats[0] - t;
1547                 else
1548                         seconds = t - sp->ats[sp->timecnt - 1];
1549                 --seconds;
1550                 tcycles = seconds / YEARSPERREPEAT / AVGSECSPERYEAR;
1551                 ++tcycles;
1552                 icycles = tcycles;
1553                 if (tcycles - icycles >= 1 || icycles - tcycles >= 1)
1554                         return -1;
1555                 seconds = icycles;
1556                 seconds *= YEARSPERREPEAT;
1557                 seconds *= AVGSECSPERYEAR;
1558                 if (t < sp->ats[0])
1559                         newt += seconds;
1560                 else
1561                         newt -= seconds;
1562                 if (newt < sp->ats[0] ||
1563                         newt > sp->ats[sp->timecnt - 1])
1564                         return -1;                      /* "cannot happen" */
1565
1566                 result = pg_next_dst_boundary(&newt, before_gmtoff,
1567                                                                           before_isdst,
1568                                                                           boundary,
1569                                                                           after_gmtoff,
1570                                                                           after_isdst,
1571                                                                           tz);
1572                 if (t < sp->ats[0])
1573                         *boundary -= seconds;
1574                 else
1575                         *boundary += seconds;
1576                 return result;
1577         }
1578
1579         if (t >= sp->ats[sp->timecnt - 1])
1580         {
1581                 /* No known transition > t, so use last known segment's type */
1582                 i = sp->types[sp->timecnt - 1];
1583                 ttisp = &sp->ttis[i];
1584                 *before_gmtoff = ttisp->tt_gmtoff;
1585                 *before_isdst = ttisp->tt_isdst;
1586                 return 0;
1587         }
1588         if (t < sp->ats[0])
1589         {
1590                 /* For "before", use lowest-numbered standard type */
1591                 i = 0;
1592                 while (sp->ttis[i].tt_isdst)
1593                         if (++i >= sp->typecnt)
1594                         {
1595                                 i = 0;
1596                                 break;
1597                         }
1598                 ttisp = &sp->ttis[i];
1599                 *before_gmtoff = ttisp->tt_gmtoff;
1600                 *before_isdst = ttisp->tt_isdst;
1601                 *boundary = sp->ats[0];
1602                 /* And for "after", use the first segment's type */
1603                 i = sp->types[0];
1604                 ttisp = &sp->ttis[i];
1605                 *after_gmtoff = ttisp->tt_gmtoff;
1606                 *after_isdst = ttisp->tt_isdst;
1607                 return 1;
1608         }
1609         /* Else search to find the boundary following t */
1610         {
1611                 int                     lo = 1;
1612                 int                     hi = sp->timecnt - 1;
1613
1614                 while (lo < hi)
1615                 {
1616                         int                     mid = (lo + hi) >> 1;
1617
1618                         if (t < sp->ats[mid])
1619                                 hi = mid;
1620                         else
1621                                 lo = mid + 1;
1622                 }
1623                 i = lo;
1624         }
1625         j = sp->types[i - 1];
1626         ttisp = &sp->ttis[j];
1627         *before_gmtoff = ttisp->tt_gmtoff;
1628         *before_isdst = ttisp->tt_isdst;
1629         *boundary = sp->ats[i];
1630         j = sp->types[i];
1631         ttisp = &sp->ttis[j];
1632         *after_gmtoff = ttisp->tt_gmtoff;
1633         *after_isdst = ttisp->tt_isdst;
1634         return 1;
1635 }
1636
1637 /*
1638  * Identify a timezone abbreviation's meaning in the given zone
1639  *
1640  * Determine the GMT offset and DST flag associated with the abbreviation.
1641  * This is generally used only when the abbreviation has actually changed
1642  * meaning over time; therefore, we also take a UTC cutoff time, and return
1643  * the meaning in use at or most recently before that time, or the meaning
1644  * in first use after that time if the abbrev was never used before that.
1645  *
1646  * On success, returns true and sets *gmtoff and *isdst.  If the abbreviation
1647  * was never used at all in this zone, returns false.
1648  *
1649  * Note: abbrev is matched case-sensitively; it should be all-upper-case.
1650  */
1651 bool
1652 pg_interpret_timezone_abbrev(const char *abbrev,
1653                                                          const pg_time_t *timep,
1654                                                          long int *gmtoff,
1655                                                          int *isdst,
1656                                                          const pg_tz *tz)
1657 {
1658         const struct state *sp;
1659         const char *abbrs;
1660         const struct ttinfo *ttisp;
1661         int                     abbrind;
1662         int                     cutoff;
1663         int                     i;
1664         const pg_time_t t = *timep;
1665
1666         sp = &tz->state;
1667
1668         /*
1669          * Locate the abbreviation in the zone's abbreviation list.  We assume
1670          * there are not duplicates in the list.
1671          */
1672         abbrs = sp->chars;
1673         abbrind = 0;
1674         while (abbrind < sp->charcnt)
1675         {
1676                 if (strcmp(abbrev, abbrs + abbrind) == 0)
1677                         break;
1678                 while (abbrs[abbrind] != '\0')
1679                         abbrind++;
1680                 abbrind++;
1681         }
1682         if (abbrind >= sp->charcnt)
1683                 return false;                   /* not there! */
1684
1685         /*
1686          * Unlike pg_next_dst_boundary, we needn't sweat about extrapolation
1687          * (goback/goahead zones).  Finding the newest or oldest meaning of the
1688          * abbreviation should get us what we want, since extrapolation would just
1689          * be repeating the newest or oldest meanings.
1690          *
1691          * Use binary search to locate the first transition > cutoff time.
1692          */
1693         {
1694                 int                     lo = 0;
1695                 int                     hi = sp->timecnt;
1696
1697                 while (lo < hi)
1698                 {
1699                         int                     mid = (lo + hi) >> 1;
1700
1701                         if (t < sp->ats[mid])
1702                                 hi = mid;
1703                         else
1704                                 lo = mid + 1;
1705                 }
1706                 cutoff = lo;
1707         }
1708
1709         /*
1710          * Scan backwards to find the latest interval using the given abbrev
1711          * before the cutoff time.
1712          */
1713         for (i = cutoff - 1; i >= 0; i--)
1714         {
1715                 ttisp = &sp->ttis[sp->types[i]];
1716                 if (ttisp->tt_abbrind == abbrind)
1717                 {
1718                         *gmtoff = ttisp->tt_gmtoff;
1719                         *isdst = ttisp->tt_isdst;
1720                         return true;
1721                 }
1722         }
1723
1724         /*
1725          * Not there, so scan forwards to find the first one after.
1726          */
1727         for (i = cutoff; i < sp->timecnt; i++)
1728         {
1729                 ttisp = &sp->ttis[sp->types[i]];
1730                 if (ttisp->tt_abbrind == abbrind)
1731                 {
1732                         *gmtoff = ttisp->tt_gmtoff;
1733                         *isdst = ttisp->tt_isdst;
1734                         return true;
1735                 }
1736         }
1737
1738         return false;                           /* hm, not actually used in any interval? */
1739 }
1740
1741 /*
1742  * If the given timezone uses only one GMT offset, store that offset
1743  * into *gmtoff and return true, else return false.
1744  */
1745 bool
1746 pg_get_timezone_offset(const pg_tz *tz, long int *gmtoff)
1747 {
1748         /*
1749          * The zone could have more than one ttinfo, if it's historically used
1750          * more than one abbreviation.  We return true as long as they all have
1751          * the same gmtoff.
1752          */
1753         const struct state *sp;
1754         int                     i;
1755
1756         sp = &tz->state;
1757         for (i = 1; i < sp->typecnt; i++)
1758         {
1759                 if (sp->ttis[i].tt_gmtoff != sp->ttis[0].tt_gmtoff)
1760                         return false;
1761         }
1762         *gmtoff = sp->ttis[0].tt_gmtoff;
1763         return true;
1764 }
1765
1766 /*
1767  * Return the name of the current timezone
1768  */
1769 const char *
1770 pg_get_timezone_name(pg_tz *tz)
1771 {
1772         if (tz)
1773                 return tz->TZname;
1774         return NULL;
1775 }
1776
1777 /*
1778  * Check whether timezone is acceptable.
1779  *
1780  * What we are doing here is checking for leap-second-aware timekeeping.
1781  * We need to reject such TZ settings because they'll wreak havoc with our
1782  * date/time arithmetic.
1783  */
1784 bool
1785 pg_tz_acceptable(pg_tz *tz)
1786 {
1787         struct pg_tm *tt;
1788         pg_time_t       time2000;
1789
1790         /*
1791          * To detect leap-second timekeeping, run pg_localtime for what should be
1792          * GMT midnight, 2000-01-01.  Insist that the tm_sec value be zero; any
1793          * other result has to be due to leap seconds.
1794          */
1795         time2000 = (POSTGRES_EPOCH_JDATE - UNIX_EPOCH_JDATE) * SECS_PER_DAY;
1796         tt = pg_localtime(&time2000, tz);
1797         if (!tt || tt->tm_sec != 0)
1798                 return false;
1799
1800         return true;
1801 }