+ /* Ignore the zone names read from the file. */
+ free (zone_names);
+
+ /* Use the names the user specified. */
+ stdlen = strlen (std) + 1;
+ dstlen = strlen (dst) + 1;
+ zone_names = malloc (stdlen + dstlen);
+ if (zone_names == NULL)
+ {
+ __use_tzfile = 0;
+ return;
+ }
+ memcpy (zone_names, std, stdlen);
+ memcpy (&zone_names[stdlen], dst, dstlen);
+
+ /* Find the standard and daylight time offsets used by the rule file.
+ We choose the offsets in the types of each flavor that are
+ transitioned to earliest in time. */
+ rule_stdoff = rule_dstoff = 0;
+ for (i = 0; i < num_transitions; ++i)
+ {
+ if (!rule_stdoff && !types[type_idxs[i]].isdst)
+ rule_stdoff = types[type_idxs[i]].offset;
+ if (!rule_dstoff && types[type_idxs[i]].isdst)
+ rule_dstoff = types[type_idxs[i]].offset;
+ if (rule_stdoff && rule_dstoff)
+ break;
+ }
+
+ /* Now correct the transition times for the user-specified standard and
+ daylight offsets from GMT. */
+ isdst = 0;
+ rule_offset = rule_offset;
+ for (i = 0; i < num_transitions; ++i)
+ {
+ struct ttinfo *trans_type = &types[type_idxs[i]];
+
+ /* We will use only types 0 (standard) and 1 (daylight).
+ Fix up this transition to point to whichever matches
+ the flavor of its original type. */
+ type_idxs[i] = trans_type->isdst;
+
+ if (trans_type->isgmt)
+ /* The transition time is in GMT. No correction to apply. */ ;
+ else if (isdst && !trans_type->isstd)
+ /* The type says this transition is in "local wall clock time", and
+ wall clock time as of the previous transition was DST. Correct
+ for the difference between the rule's DST offset and the user's
+ DST offset. */
+ transitions[i] += dstoff - rule_dstoff;
+ else
+ /* This transition is in "local wall clock time", and wall clock
+ time as of this iteration is non-DST. Correct for the
+ difference between the rule's standard offset and the user's
+ standard offset. */
+ transitions[i] += stdoff - rule_stdoff;
+
+ /* The DST state of "local wall clock time" for the next iteration is
+ as specified by this transition. */
+ isdst = trans_type->isdst;
+ }
+
+ /* Reset types 0 and 1 to describe the user's settings. */
+ types[0].idx = 0;
+ types[0].offset = stdoff;
+ types[0].isdst = 0;
+ types[1].idx = stdlen;
+ types[1].offset = dstoff;
+ types[1].isdst = 1;
+
+ compute_tzname_max (stdlen + dstlen);
+}
+\f