Force rereading TZDEFRULES after it was used to set DST rules only (bug #19253)
[platform/upstream/glibc.git] / time / tzfile.c
1 /* Copyright (C) 1991-2016 Free Software Foundation, Inc.
2    This file is part of the GNU C Library.
3
4    The GNU C Library is free software; you can redistribute it and/or
5    modify it under the terms of the GNU Lesser General Public
6    License as published by the Free Software Foundation; either
7    version 2.1 of the License, or (at your option) any later version.
8
9    The GNU C Library is distributed in the hope that it will be useful,
10    but WITHOUT ANY WARRANTY; without even the implied warranty of
11    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12    Lesser General Public License for more details.
13
14    You should have received a copy of the GNU Lesser General Public
15    License along with the GNU C Library; if not, see
16    <http://www.gnu.org/licenses/>.  */
17
18 #include <assert.h>
19 #include <limits.h>
20 #include <stdio.h>
21 #include <stdio_ext.h>
22 #include <stdlib.h>
23 #include <string.h>
24 #include <time.h>
25 #include <unistd.h>
26 #include <sys/stat.h>
27 #include <stdint.h>
28
29 #define NOID
30 #include <timezone/tzfile.h>
31
32 int __use_tzfile;
33 static dev_t tzfile_dev;
34 static ino64_t tzfile_ino;
35 static time_t tzfile_mtime;
36
37 struct ttinfo
38   {
39     long int offset;            /* Seconds east of GMT.  */
40     unsigned char isdst;        /* Used to set tm_isdst.  */
41     unsigned char idx;          /* Index into `zone_names'.  */
42     unsigned char isstd;        /* Transition times are in standard time.  */
43     unsigned char isgmt;        /* Transition times are in GMT.  */
44   };
45
46 struct leap
47   {
48     time_t transition;          /* Time the transition takes effect.  */
49     long int change;            /* Seconds of correction to apply.  */
50   };
51
52 static void compute_tzname_max (size_t) internal_function;
53
54 static size_t num_transitions;
55 libc_freeres_ptr (static time_t *transitions);
56 static unsigned char *type_idxs;
57 static size_t num_types;
58 static struct ttinfo *types;
59 static char *zone_names;
60 static long int rule_stdoff;
61 static long int rule_dstoff;
62 static size_t num_leaps;
63 static struct leap *leaps;
64 static char *tzspec;
65
66 #include <endian.h>
67 #include <byteswap.h>
68
69 /* Decode the four bytes at PTR as a signed integer in network byte order.  */
70 static inline int
71 __attribute ((always_inline))
72 decode (const void *ptr)
73 {
74   if (BYTE_ORDER == BIG_ENDIAN && sizeof (int) == 4)
75     return *(const int *) ptr;
76   if (sizeof (int) == 4)
77     return bswap_32 (*(const int *) ptr);
78
79   const unsigned char *p = ptr;
80   int result = *p & (1 << (CHAR_BIT - 1)) ? ~0 : 0;
81
82   result = (result << 8) | *p++;
83   result = (result << 8) | *p++;
84   result = (result << 8) | *p++;
85   result = (result << 8) | *p++;
86
87   return result;
88 }
89
90
91 static inline int64_t
92 __attribute ((always_inline))
93 decode64 (const void *ptr)
94 {
95   if ((BYTE_ORDER == BIG_ENDIAN))
96     return *(const int64_t *) ptr;
97
98   return bswap_64 (*(const int64_t *) ptr);
99 }
100
101
102 void
103 __tzfile_read (const char *file, size_t extra, char **extrap)
104 {
105   static const char default_tzdir[] = TZDIR;
106   size_t num_isstd, num_isgmt;
107   FILE *f;
108   struct tzhead tzhead;
109   size_t chars;
110   size_t i;
111   size_t total_size;
112   size_t types_idx;
113   size_t leaps_idx;
114   int was_using_tzfile = __use_tzfile;
115   int trans_width = 4;
116   size_t tzspec_len;
117   char *new = NULL;
118
119   if (sizeof (time_t) != 4 && sizeof (time_t) != 8)
120     abort ();
121
122   __use_tzfile = 0;
123
124   if (file == NULL)
125     /* No user specification; use the site-wide default.  */
126     file = TZDEFAULT;
127   else if (*file == '\0')
128     /* User specified the empty string; use UTC with no leap seconds.  */
129     goto ret_free_transitions;
130   else
131     {
132       /* We must not allow to read an arbitrary file in a setuid
133          program.  So we fail for any file which is not in the
134          directory hierachy starting at TZDIR
135          and which is not the system wide default TZDEFAULT.  */
136       if (__libc_enable_secure
137           && ((*file == '/'
138                && memcmp (file, TZDEFAULT, sizeof TZDEFAULT)
139                && memcmp (file, default_tzdir, sizeof (default_tzdir) - 1))
140               || strstr (file, "../") != NULL))
141         /* This test is certainly a bit too restrictive but it should
142            catch all critical cases.  */
143         goto ret_free_transitions;
144     }
145
146   if (*file != '/')
147     {
148       const char *tzdir;
149
150       tzdir = getenv ("TZDIR");
151       if (tzdir == NULL || *tzdir == '\0')
152         tzdir = default_tzdir;
153       if (__asprintf (&new, "%s/%s", tzdir, file) == -1)
154         goto ret_free_transitions;
155       file = new;
156     }
157
158   /* If we were already using tzfile, check whether the file changed.  */
159   struct stat64 st;
160   if (was_using_tzfile
161       && stat64 (file, &st) == 0
162       && tzfile_ino == st.st_ino && tzfile_dev == st.st_dev
163       && tzfile_mtime == st.st_mtime)
164     goto done;  /* Nothing to do.  */
165
166   /* Note the file is opened with cancellation in the I/O functions
167      disabled and if available FD_CLOEXEC set.  */
168   f = fopen (file, "rce");
169   if (f == NULL)
170     goto ret_free_transitions;
171
172   /* Get information about the file we are actually using.  */
173   if (fstat64 (__fileno (f), &st) != 0)
174     {
175       fclose (f);
176       goto ret_free_transitions;
177     }
178
179   free ((void *) transitions);
180   transitions = NULL;
181
182   /* Remember the inode and device number and modification time.  */
183   tzfile_dev = st.st_dev;
184   tzfile_ino = st.st_ino;
185   tzfile_mtime = st.st_mtime;
186
187   /* No threads reading this stream.  */
188   __fsetlocking (f, FSETLOCKING_BYCALLER);
189
190  read_again:
191   if (__builtin_expect (__fread_unlocked ((void *) &tzhead, sizeof (tzhead),
192                                           1, f) != 1, 0)
193       || memcmp (tzhead.tzh_magic, TZ_MAGIC, sizeof (tzhead.tzh_magic)) != 0)
194     goto lose;
195
196   num_transitions = (size_t) decode (tzhead.tzh_timecnt);
197   num_types = (size_t) decode (tzhead.tzh_typecnt);
198   chars = (size_t) decode (tzhead.tzh_charcnt);
199   num_leaps = (size_t) decode (tzhead.tzh_leapcnt);
200   num_isstd = (size_t) decode (tzhead.tzh_ttisstdcnt);
201   num_isgmt = (size_t) decode (tzhead.tzh_ttisgmtcnt);
202
203   if (__glibc_unlikely (num_isstd > num_types || num_isgmt > num_types))
204     goto lose;
205
206   /* For platforms with 64-bit time_t we use the new format if available.  */
207   if (sizeof (time_t) == 8 && trans_width == 4
208       && tzhead.tzh_version[0] != '\0')
209     {
210       /* We use the 8-byte format.  */
211       trans_width = 8;
212
213       /* Position the stream before the second header.  */
214       size_t to_skip = (num_transitions * (4 + 1)
215                         + num_types * 6
216                         + chars
217                         + num_leaps * 8
218                         + num_isstd
219                         + num_isgmt);
220       if (fseek (f, to_skip, SEEK_CUR) != 0)
221         goto lose;
222
223       goto read_again;
224     }
225
226   if (__builtin_expect (num_transitions
227                         > ((SIZE_MAX - (__alignof__ (struct ttinfo) - 1))
228                            / (sizeof (time_t) + 1)), 0))
229     goto lose;
230   total_size = num_transitions * (sizeof (time_t) + 1);
231   total_size = ((total_size + __alignof__ (struct ttinfo) - 1)
232                 & ~(__alignof__ (struct ttinfo) - 1));
233   types_idx = total_size;
234   if (__builtin_expect (num_types
235                         > (SIZE_MAX - total_size) / sizeof (struct ttinfo), 0))
236     goto lose;
237   total_size += num_types * sizeof (struct ttinfo);
238   if (__glibc_unlikely (chars > SIZE_MAX - total_size))
239     goto lose;
240   total_size += chars;
241   if (__builtin_expect (__alignof__ (struct leap) - 1
242                         > SIZE_MAX - total_size, 0))
243     goto lose;
244   total_size = ((total_size + __alignof__ (struct leap) - 1)
245                 & ~(__alignof__ (struct leap) - 1));
246   leaps_idx = total_size;
247   if (__builtin_expect (num_leaps
248                         > (SIZE_MAX - total_size) / sizeof (struct leap), 0))
249     goto lose;
250   total_size += num_leaps * sizeof (struct leap);
251   tzspec_len = 0;
252   if (sizeof (time_t) == 8 && trans_width == 8)
253     {
254       off_t rem = st.st_size - __ftello (f);
255       if (__builtin_expect (rem < 0
256                             || (size_t) rem < (num_transitions * (8 + 1)
257                                                + num_types * 6
258                                                + chars), 0))
259         goto lose;
260       tzspec_len = (size_t) rem - (num_transitions * (8 + 1)
261                                    + num_types * 6
262                                    + chars);
263       if (__builtin_expect (num_leaps > SIZE_MAX / 12
264                             || tzspec_len < num_leaps * 12, 0))
265         goto lose;
266       tzspec_len -= num_leaps * 12;
267       if (__glibc_unlikely (tzspec_len < num_isstd))
268         goto lose;
269       tzspec_len -= num_isstd;
270       if (__glibc_unlikely (tzspec_len == 0 || tzspec_len - 1 < num_isgmt))
271         goto lose;
272       tzspec_len -= num_isgmt + 1;
273       if (__glibc_unlikely (tzspec_len == 0
274                             || SIZE_MAX - total_size < tzspec_len))
275         goto lose;
276     }
277   if (__glibc_unlikely (SIZE_MAX - total_size - tzspec_len < extra))
278     goto lose;
279
280   /* Allocate enough memory including the extra block requested by the
281      caller.  */
282   transitions = (time_t *) malloc (total_size + tzspec_len + extra);
283   if (transitions == NULL)
284     goto lose;
285
286   type_idxs = (unsigned char *) transitions + (num_transitions
287                                                * sizeof (time_t));
288   types = (struct ttinfo *) ((char *) transitions + types_idx);
289   zone_names = (char *) types + num_types * sizeof (struct ttinfo);
290   leaps = (struct leap *) ((char *) transitions + leaps_idx);
291   if (sizeof (time_t) == 8 && trans_width == 8)
292     tzspec = (char *) leaps + num_leaps * sizeof (struct leap) + extra;
293   else
294     tzspec = NULL;
295   if (extra > 0)
296     *extrap = (char *) &leaps[num_leaps];
297
298   if (sizeof (time_t) == 4 || __builtin_expect (trans_width == 8, 1))
299     {
300       if (__builtin_expect (__fread_unlocked (transitions, trans_width + 1,
301                                               num_transitions, f)
302                             != num_transitions, 0))
303         goto lose;
304     }
305   else
306     {
307       if (__builtin_expect (__fread_unlocked (transitions, 4,
308                                               num_transitions, f)
309                             != num_transitions, 0)
310           || __builtin_expect (__fread_unlocked (type_idxs, 1, num_transitions,
311                                                  f) != num_transitions, 0))
312         goto lose;
313     }
314
315   /* Check for bogus indices in the data file, so we can hereafter
316      safely use type_idxs[T] as indices into `types' and never crash.  */
317   for (i = 0; i < num_transitions; ++i)
318     if (__glibc_unlikely (type_idxs[i] >= num_types))
319       goto lose;
320
321   if ((BYTE_ORDER != BIG_ENDIAN && (sizeof (time_t) == 4 || trans_width == 4))
322       || (BYTE_ORDER == BIG_ENDIAN && sizeof (time_t) == 8
323           && trans_width == 4))
324     {
325       /* Decode the transition times, stored as 4-byte integers in
326          network (big-endian) byte order.  We work from the end of
327          the array so as not to clobber the next element to be
328          processed when sizeof (time_t) > 4.  */
329       i = num_transitions;
330       while (i-- > 0)
331         transitions[i] = decode ((char *) transitions + i * 4);
332     }
333   else if (BYTE_ORDER != BIG_ENDIAN && sizeof (time_t) == 8)
334     {
335       /* Decode the transition times, stored as 8-byte integers in
336          network (big-endian) byte order.  */
337       for (i = 0; i < num_transitions; ++i)
338         transitions[i] = decode64 ((char *) transitions + i * 8);
339     }
340
341   for (i = 0; i < num_types; ++i)
342     {
343       unsigned char x[4];
344       int c;
345       if (__builtin_expect (__fread_unlocked (x, 1,
346                                               sizeof (x), f) != sizeof (x),
347                             0))
348         goto lose;
349       c = getc_unlocked (f);
350       if (__glibc_unlikely ((unsigned int) c > 1u))
351         goto lose;
352       types[i].isdst = c;
353       c = getc_unlocked (f);
354       if (__glibc_unlikely ((size_t) c > chars))
355         /* Bogus index in data file.  */
356         goto lose;
357       types[i].idx = c;
358       types[i].offset = (long int) decode (x);
359     }
360
361   if (__glibc_unlikely (__fread_unlocked (zone_names, 1, chars, f) != chars))
362     goto lose;
363
364   for (i = 0; i < num_leaps; ++i)
365     {
366       unsigned char x[8];
367       if (__builtin_expect (__fread_unlocked (x, 1, trans_width, f)
368                             != trans_width, 0))
369         goto lose;
370       if (sizeof (time_t) == 4 || trans_width == 4)
371         leaps[i].transition = (time_t) decode (x);
372       else
373         leaps[i].transition = (time_t) decode64 (x);
374
375       if (__glibc_unlikely (__fread_unlocked (x, 1, 4, f) != 4))
376         goto lose;
377       leaps[i].change = (long int) decode (x);
378     }
379
380   for (i = 0; i < num_isstd; ++i)
381     {
382       int c = getc_unlocked (f);
383       if (__glibc_unlikely (c == EOF))
384         goto lose;
385       types[i].isstd = c != 0;
386     }
387   while (i < num_types)
388     types[i++].isstd = 0;
389
390   for (i = 0; i < num_isgmt; ++i)
391     {
392       int c = getc_unlocked (f);
393       if (__glibc_unlikely (c == EOF))
394         goto lose;
395       types[i].isgmt = c != 0;
396     }
397   while (i < num_types)
398     types[i++].isgmt = 0;
399
400   /* Read the POSIX TZ-style information if possible.  */
401   if (sizeof (time_t) == 8 && tzspec != NULL)
402     {
403       /* Skip over the newline first.  */
404       if (getc_unlocked (f) != '\n'
405           || (__fread_unlocked (tzspec, 1, tzspec_len - 1, f)
406               != tzspec_len - 1))
407         tzspec = NULL;
408       else
409         tzspec[tzspec_len - 1] = '\0';
410     }
411   else if (sizeof (time_t) == 4 && tzhead.tzh_version[0] != '\0')
412     {
413       /* Get the TZ string.  */
414       if (__builtin_expect (__fread_unlocked ((void *) &tzhead,
415                                               sizeof (tzhead), 1, f) != 1, 0)
416           || (memcmp (tzhead.tzh_magic, TZ_MAGIC, sizeof (tzhead.tzh_magic))
417               != 0))
418         goto lose;
419
420       size_t num_transitions2 = (size_t) decode (tzhead.tzh_timecnt);
421       size_t num_types2 = (size_t) decode (tzhead.tzh_typecnt);
422       size_t chars2 = (size_t) decode (tzhead.tzh_charcnt);
423       size_t num_leaps2 = (size_t) decode (tzhead.tzh_leapcnt);
424       size_t num_isstd2 = (size_t) decode (tzhead.tzh_ttisstdcnt);
425       size_t num_isgmt2 = (size_t) decode (tzhead.tzh_ttisgmtcnt);
426
427       /* Position the stream before the second header.  */
428       size_t to_skip = (num_transitions2 * (8 + 1)
429                         + num_types2 * 6
430                         + chars2
431                         + num_leaps2 * 12
432                         + num_isstd2
433                         + num_isgmt2);
434       off_t off;
435       if (fseek (f, to_skip, SEEK_CUR) != 0
436           || (off = __ftello (f)) < 0
437           || st.st_size < off + 2)
438         goto lose;
439
440       tzspec_len = st.st_size - off - 1;
441       if (tzspec_len == 0)
442         goto lose;
443       char *tzstr = malloc (tzspec_len);
444       if (tzstr == NULL)
445         goto lose;
446       if (getc_unlocked (f) != '\n'
447           || (__fread_unlocked (tzstr, 1, tzspec_len - 1, f)
448               != tzspec_len - 1))
449         {
450           free (tzstr);
451           goto lose;
452         }
453       tzstr[tzspec_len - 1] = '\0';
454       tzspec = __tzstring (tzstr);
455       free (tzstr);
456     }
457
458   /* Don't use an empty TZ string.  */
459   if (tzspec != NULL && tzspec[0] == '\0')
460     tzspec = NULL;
461
462   fclose (f);
463
464   /* First "register" all timezone names.  */
465   for (i = 0; i < num_types; ++i)
466     (void) __tzstring (&zone_names[types[i].idx]);
467
468   /* Find the standard and daylight time offsets used by the rule file.
469      We choose the offsets in the types of each flavor that are
470      transitioned to earliest in time.  */
471   __tzname[0] = NULL;
472   __tzname[1] = NULL;
473   for (i = num_transitions; i > 0; )
474     {
475       int type = type_idxs[--i];
476       int dst = types[type].isdst;
477
478       if (__tzname[dst] == NULL)
479         {
480           int idx = types[type].idx;
481
482           __tzname[dst] = __tzstring (&zone_names[idx]);
483
484           if (__tzname[1 - dst] != NULL)
485             break;
486         }
487     }
488   if (__tzname[0] == NULL)
489     {
490       /* This should only happen if there are no transition rules.
491          In this case there should be only one single type.  */
492       assert (num_types == 1);
493       __tzname[0] = __tzstring (zone_names);
494     }
495   if (__tzname[1] == NULL)
496     __tzname[1] = __tzname[0];
497
498   compute_tzname_max (chars);
499
500   if (num_transitions == 0)
501     /* Use the first rule (which should also be the only one).  */
502     rule_stdoff = rule_dstoff = types[0].offset;
503   else
504     {
505       int stdoff_set = 0, dstoff_set = 0;
506       rule_stdoff = rule_dstoff = 0;
507       i = num_transitions - 1;
508       do
509         {
510           if (!stdoff_set && !types[type_idxs[i]].isdst)
511             {
512               stdoff_set = 1;
513               rule_stdoff = types[type_idxs[i]].offset;
514             }
515           else if (!dstoff_set && types[type_idxs[i]].isdst)
516             {
517               dstoff_set = 1;
518               rule_dstoff = types[type_idxs[i]].offset;
519             }
520           if (stdoff_set && dstoff_set)
521             break;
522         }
523       while (i-- > 0);
524
525       if (!dstoff_set)
526         rule_dstoff = rule_stdoff;
527     }
528
529   __daylight = rule_stdoff != rule_dstoff;
530   __timezone = -rule_stdoff;
531
532  done:
533   __use_tzfile = 1;
534   free (new);
535   return;
536
537  lose:
538   fclose (f);
539  ret_free_transitions:
540   free (new);
541   free ((void *) transitions);
542   transitions = NULL;
543 }
544 \f
545 /* The user specified a hand-made timezone, but not its DST rules.
546    We will use the names and offsets from the user, and the rules
547    from the TZDEFRULES file.  */
548
549 void
550 __tzfile_default (const char *std, const char *dst,
551                   long int stdoff, long int dstoff)
552 {
553   size_t stdlen = strlen (std) + 1;
554   size_t dstlen = strlen (dst) + 1;
555   size_t i;
556   int isdst;
557   char *cp;
558
559   __tzfile_read (TZDEFRULES, stdlen + dstlen, &cp);
560   if (!__use_tzfile)
561     return;
562
563   if (num_types < 2)
564     {
565       __use_tzfile = 0;
566       return;
567     }
568
569   /* Ignore the zone names read from the file and use the given ones
570      instead.  */
571   __mempcpy (__mempcpy (cp, std, stdlen), dst, dstlen);
572   zone_names = cp;
573
574   /* Now there are only two zones, regardless of what the file contained.  */
575   num_types = 2;
576
577   /* Now correct the transition times for the user-specified standard and
578      daylight offsets from GMT.  */
579   isdst = 0;
580   for (i = 0; i < num_transitions; ++i)
581     {
582       struct ttinfo *trans_type = &types[type_idxs[i]];
583
584       /* We will use only types 0 (standard) and 1 (daylight).
585          Fix up this transition to point to whichever matches
586          the flavor of its original type.  */
587       type_idxs[i] = trans_type->isdst;
588
589       if (trans_type->isgmt)
590         /* The transition time is in GMT.  No correction to apply.  */ ;
591       else if (isdst && !trans_type->isstd)
592         /* The type says this transition is in "local wall clock time", and
593            wall clock time as of the previous transition was DST.  Correct
594            for the difference between the rule's DST offset and the user's
595            DST offset.  */
596         transitions[i] += dstoff - rule_dstoff;
597       else
598         /* This transition is in "local wall clock time", and wall clock
599            time as of this iteration is non-DST.  Correct for the
600            difference between the rule's standard offset and the user's
601            standard offset.  */
602         transitions[i] += stdoff - rule_stdoff;
603
604       /* The DST state of "local wall clock time" for the next iteration is
605          as specified by this transition.  */
606       isdst = trans_type->isdst;
607     }
608
609   /* Now that we adjusted the transitions to the requested offsets,
610      reset the rule_stdoff and rule_dstoff values appropriately.  They
611      are used elsewhere.  */
612   rule_stdoff = stdoff;
613   rule_dstoff = dstoff;
614
615   /* Reset types 0 and 1 to describe the user's settings.  */
616   types[0].idx = 0;
617   types[0].offset = stdoff;
618   types[0].isdst = 0;
619   types[1].idx = stdlen;
620   types[1].offset = dstoff;
621   types[1].isdst = 1;
622
623   /* Reset the zone names to point to the user's names.  */
624   __tzname[0] = (char *) std;
625   __tzname[1] = (char *) dst;
626
627   /* Set the timezone.  */
628   __timezone = -types[0].offset;
629
630   compute_tzname_max (stdlen + dstlen);
631
632   /* Invalidate the tzfile attribute cache to force rereading
633      TZDEFRULES the next time it is used.  */
634   tzfile_dev = 0;
635   tzfile_ino = 0;
636   tzfile_mtime = 0;
637 }
638 \f
639 void
640 __tzfile_compute (time_t timer, int use_localtime,
641                   long int *leap_correct, int *leap_hit,
642                   struct tm *tp)
643 {
644   size_t i;
645
646   if (use_localtime)
647     {
648       __tzname[0] = NULL;
649       __tzname[1] = NULL;
650
651       if (__glibc_unlikely (num_transitions == 0 || timer < transitions[0]))
652         {
653           /* TIMER is before any transition (or there are no transitions).
654              Choose the first non-DST type
655              (or the first if they're all DST types).  */
656           i = 0;
657           while (i < num_types && types[i].isdst)
658             {
659               if (__tzname[1] == NULL)
660                 __tzname[1] = __tzstring (&zone_names[types[i].idx]);
661
662               ++i;
663             }
664
665           if (i == num_types)
666             i = 0;
667           __tzname[0] = __tzstring (&zone_names[types[i].idx]);
668           if (__tzname[1] == NULL)
669             {
670               size_t j = i;
671               while (j < num_types)
672                 if (types[j].isdst)
673                   {
674                     __tzname[1] = __tzstring (&zone_names[types[j].idx]);
675                     break;
676                   }
677                 else
678                   ++j;
679             }
680         }
681       else if (__glibc_unlikely (timer >= transitions[num_transitions - 1]))
682         {
683           if (__glibc_unlikely (tzspec == NULL))
684             {
685             use_last:
686               i = num_transitions;
687               goto found;
688             }
689
690           /* Parse the POSIX TZ-style string.  */
691           __tzset_parse_tz (tzspec);
692
693           /* Convert to broken down structure.  If this fails do not
694              use the string.  */
695           if (__glibc_unlikely (! __offtime (&timer, 0, tp)))
696             goto use_last;
697
698           /* Use the rules from the TZ string to compute the change.  */
699           __tz_compute (timer, tp, 1);
700
701           /* If tzspec comes from posixrules loaded by __tzfile_default,
702              override the STD and DST zone names with the ones user
703              requested in TZ envvar.  */
704           if (__glibc_unlikely (zone_names == (char *) &leaps[num_leaps]))
705             {
706               assert (num_types == 2);
707               __tzname[0] = __tzstring (zone_names);
708               __tzname[1] = __tzstring (&zone_names[strlen (zone_names) + 1]);
709             }
710
711           goto leap;
712         }
713       else
714         {
715           /* Find the first transition after TIMER, and
716              then pick the type of the transition before it.  */
717           size_t lo = 0;
718           size_t hi = num_transitions - 1;
719           /* Assume that DST is changing twice a year and guess initial
720              search spot from it.
721              Half of a gregorian year has on average 365.2425 * 86400 / 2
722              = 15778476 seconds.  */
723           i = (transitions[num_transitions - 1] - timer) / 15778476;
724           if (i < num_transitions)
725             {
726               i = num_transitions - 1 - i;
727               if (timer < transitions[i])
728                 {
729                   if (i < 10 || timer >= transitions[i - 10])
730                     {
731                       /* Linear search.  */
732                       while (timer < transitions[i - 1])
733                         --i;
734                       goto found;
735                     }
736                   hi = i - 10;
737                 }
738               else
739                 {
740                   if (i + 10 >= num_transitions || timer < transitions[i + 10])
741                     {
742                       /* Linear search.  */
743                       while (timer >= transitions[i])
744                         ++i;
745                       goto found;
746                     }
747                   lo = i + 10;
748                 }
749             }
750
751           /* Binary search.  */
752           /* assert (timer >= transitions[lo] && timer < transitions[hi]); */
753           while (lo + 1 < hi)
754             {
755               i = (lo + hi) / 2;
756               if (timer < transitions[i])
757                 hi = i;
758               else
759                 lo = i;
760             }
761           i = hi;
762
763         found:
764           /* assert (timer >= transitions[i - 1]
765              && (i == num_transitions || timer < transitions[i])); */
766           __tzname[types[type_idxs[i - 1]].isdst]
767             = __tzstring (&zone_names[types[type_idxs[i - 1]].idx]);
768           size_t j = i;
769           while (j < num_transitions)
770             {
771               int type = type_idxs[j];
772               int dst = types[type].isdst;
773               int idx = types[type].idx;
774
775               if (__tzname[dst] == NULL)
776                 {
777                   __tzname[dst] = __tzstring (&zone_names[idx]);
778
779                   if (__tzname[1 - dst] != NULL)
780                     break;
781                 }
782
783               ++j;
784             }
785
786           if (__glibc_unlikely (__tzname[0] == NULL))
787             __tzname[0] = __tzname[1];
788
789           i = type_idxs[i - 1];
790         }
791
792       struct ttinfo *info = &types[i];
793       __daylight = rule_stdoff != rule_dstoff;
794       __timezone = -rule_stdoff;
795
796       if (__tzname[0] == NULL)
797         {
798           /* This should only happen if there are no transition rules.
799              In this case there should be only one single type.  */
800           assert (num_types == 1);
801           __tzname[0] = __tzstring (zone_names);
802         }
803       if (__tzname[1] == NULL)
804         /* There is no daylight saving time.  */
805         __tzname[1] = __tzname[0];
806       tp->tm_isdst = info->isdst;
807       assert (strcmp (&zone_names[info->idx], __tzname[tp->tm_isdst]) == 0);
808       tp->tm_zone = __tzname[tp->tm_isdst];
809       tp->tm_gmtoff = info->offset;
810     }
811
812  leap:
813   *leap_correct = 0L;
814   *leap_hit = 0;
815
816   /* Find the last leap second correction transition time before TIMER.  */
817   i = num_leaps;
818   do
819     if (i-- == 0)
820       return;
821   while (timer < leaps[i].transition);
822
823   /* Apply its correction.  */
824   *leap_correct = leaps[i].change;
825
826   if (timer == leaps[i].transition && /* Exactly at the transition time.  */
827       ((i == 0 && leaps[i].change > 0) ||
828        leaps[i].change > leaps[i - 1].change))
829     {
830       *leap_hit = 1;
831       while (i > 0
832              && leaps[i].transition == leaps[i - 1].transition + 1
833              && leaps[i].change == leaps[i - 1].change + 1)
834         {
835           ++*leap_hit;
836           --i;
837         }
838     }
839 }
840 \f
841 static void
842 internal_function
843 compute_tzname_max (size_t chars)
844 {
845   const char *p;
846
847   p = zone_names;
848   do
849     {
850       const char *start = p;
851       while (*p != '\0')
852         ++p;
853       if ((size_t) (p - start) > __tzname_cur_max)
854         __tzname_cur_max = p - start;
855     }
856   while (++p < &zone_names[chars]);
857 }