Rebase for tzdata 2016i
[platform/upstream/tzdata.git] / zic.c
1 /*
2 ** This file is in the public domain, so clarified as of
3 ** 2006-07-17 by Arthur David Olson.
4 */
5
6 #include "version.h"
7 #include "private.h"
8 #include "locale.h"
9 #include "tzfile.h"
10
11 #include <stdarg.h>
12
13 #define ZIC_VERSION_PRE_2013 '2'
14 #define ZIC_VERSION     '3'
15
16 typedef int_fast64_t    zic_t;
17 #define ZIC_MIN INT_FAST64_MIN
18 #define ZIC_MAX INT_FAST64_MAX
19 #define SCNdZIC SCNdFAST64
20
21 #ifndef ZIC_MAX_ABBR_LEN_WO_WARN
22 #define ZIC_MAX_ABBR_LEN_WO_WARN        6
23 #endif /* !defined ZIC_MAX_ABBR_LEN_WO_WARN */
24
25 #ifdef HAVE_DIRECT_H
26 # include <direct.h>
27 # include <io.h>
28 # undef mkdir
29 # define mkdir(name, mode) _mkdir(name)
30 #endif
31
32 #if HAVE_SYS_STAT_H
33 #include <sys/stat.h>
34 #endif
35 #ifdef S_IRUSR
36 #define MKDIR_UMASK (S_IRUSR|S_IWUSR|S_IXUSR|S_IRGRP|S_IXGRP|S_IROTH|S_IXOTH)
37 #else
38 #define MKDIR_UMASK 0755
39 #endif
40
41 struct rule {
42         const char *    r_filename;
43         int             r_linenum;
44         const char *    r_name;
45
46         zic_t           r_loyear;       /* for example, 1986 */
47         zic_t           r_hiyear;       /* for example, 1986 */
48         const char *    r_yrtype;
49         bool            r_lowasnum;
50         bool            r_hiwasnum;
51
52         int             r_month;        /* 0..11 */
53
54         int             r_dycode;       /* see below */
55         int             r_dayofmonth;
56         int             r_wday;
57
58         zic_t           r_tod;          /* time from midnight */
59         bool            r_todisstd;     /* above is standard time if 1 */
60                                         /* or wall clock time if 0 */
61         bool            r_todisgmt;     /* above is GMT if 1 */
62                                         /* or local time if 0 */
63         zic_t           r_stdoff;       /* offset from standard time */
64         const char *    r_abbrvar;      /* variable part of abbreviation */
65
66         int             r_todo;         /* a rule to do (used in outzone) */
67         zic_t           r_temp;         /* used in outzone */
68 };
69
70 /*
71 **      r_dycode                r_dayofmonth    r_wday
72 */
73
74 #define DC_DOM          0       /* 1..31 */     /* unused */
75 #define DC_DOWGEQ       1       /* 1..31 */     /* 0..6 (Sun..Sat) */
76 #define DC_DOWLEQ       2       /* 1..31 */     /* 0..6 (Sun..Sat) */
77
78 struct zone {
79         const char *    z_filename;
80         int             z_linenum;
81
82         const char *    z_name;
83         zic_t           z_gmtoff;
84         const char *    z_rule;
85         const char *    z_format;
86         char            z_format_specifier;
87
88         zic_t           z_stdoff;
89
90         struct rule *   z_rules;
91         int             z_nrules;
92
93         struct rule     z_untilrule;
94         zic_t           z_untiltime;
95 };
96
97 #if !HAVE_POSIX_DECLS
98 extern int      getopt(int argc, char * const argv[],
99                         const char * options);
100 extern int      link(const char * fromname, const char * toname);
101 extern char *   optarg;
102 extern int      optind;
103 #endif
104
105 #if ! HAVE_LINK
106 # define link(from, to) (errno = ENOTSUP, -1)
107 #endif
108 #if ! HAVE_SYMLINK
109 # define symlink(from, to) (errno = ENOTSUP, -1)
110 #endif
111
112 static void     addtt(zic_t starttime, int type);
113 static int      addtype(zic_t, char const *, bool, bool, bool);
114 static void     leapadd(zic_t, bool, int, int);
115 static void     adjleap(void);
116 static void     associate(void);
117 static void     dolink(const char * fromfield, const char * tofield);
118 static char **  getfields(char * buf);
119 static zic_t    gethms(const char * string, const char * errstring,
120                        bool);
121 static void     infile(const char * filename);
122 static void     inleap(char ** fields, int nfields);
123 static void     inlink(char ** fields, int nfields);
124 static void     inrule(char ** fields, int nfields);
125 static bool     inzcont(char ** fields, int nfields);
126 static bool     inzone(char ** fields, int nfields);
127 static bool     inzsub(char **, int, bool);
128 static int      itsdir(const char * name);
129 static bool     is_alpha(char a);
130 static char     lowerit(char);
131 static bool     mkdirs(char *);
132 static void     newabbr(const char * abbr);
133 static zic_t    oadd(zic_t t1, zic_t t2);
134 static void     outzone(const struct zone * zp, int ntzones);
135 static zic_t    rpytime(const struct rule * rp, zic_t wantedy);
136 static void     rulesub(struct rule * rp,
137                         const char * loyearp, const char * hiyearp,
138                         const char * typep, const char * monthp,
139                         const char * dayp, const char * timep);
140 static zic_t    tadd(zic_t t1, zic_t t2);
141 static bool     yearistype(int year, const char * type);
142
143 /* Bound on length of what %z can expand to.  */
144 enum { PERCENT_Z_LEN_BOUND = sizeof "+995959" - 1 };
145
146 /* If true, work around a bug in Qt 5.6.1 and earlier, which mishandles
147    tzdata binary files whose POSIX-TZ-style strings contain '<'; see
148    QTBUG-53071 <https://bugreports.qt.io/browse/QTBUG-53071>.  This
149    workaround will no longer be needed when Qt 5.6.1 and earlier are
150    obsolete, say in the year 2021.  */
151 enum { WORK_AROUND_QTBUG_53071 = true };
152
153 static int              charcnt;
154 static bool             errors;
155 static bool             warnings;
156 static const char *     filename;
157 static int              leapcnt;
158 static bool             leapseen;
159 static zic_t            leapminyear;
160 static zic_t            leapmaxyear;
161 static int              linenum;
162 static int              max_abbrvar_len = PERCENT_Z_LEN_BOUND;
163 static int              max_format_len;
164 static zic_t            max_year;
165 static zic_t            min_year;
166 static bool             noise;
167 static const char *     rfilename;
168 static int              rlinenum;
169 static const char *     progname;
170 static int              timecnt;
171 static int              timecnt_alloc;
172 static int              typecnt;
173
174 /*
175 ** Line codes.
176 */
177
178 #define LC_RULE         0
179 #define LC_ZONE         1
180 #define LC_LINK         2
181 #define LC_LEAP         3
182
183 /*
184 ** Which fields are which on a Zone line.
185 */
186
187 #define ZF_NAME         1
188 #define ZF_GMTOFF       2
189 #define ZF_RULE         3
190 #define ZF_FORMAT       4
191 #define ZF_TILYEAR      5
192 #define ZF_TILMONTH     6
193 #define ZF_TILDAY       7
194 #define ZF_TILTIME      8
195 #define ZONE_MINFIELDS  5
196 #define ZONE_MAXFIELDS  9
197
198 /*
199 ** Which fields are which on a Zone continuation line.
200 */
201
202 #define ZFC_GMTOFF      0
203 #define ZFC_RULE        1
204 #define ZFC_FORMAT      2
205 #define ZFC_TILYEAR     3
206 #define ZFC_TILMONTH    4
207 #define ZFC_TILDAY      5
208 #define ZFC_TILTIME     6
209 #define ZONEC_MINFIELDS 3
210 #define ZONEC_MAXFIELDS 7
211
212 /*
213 ** Which files are which on a Rule line.
214 */
215
216 #define RF_NAME         1
217 #define RF_LOYEAR       2
218 #define RF_HIYEAR       3
219 #define RF_COMMAND      4
220 #define RF_MONTH        5
221 #define RF_DAY          6
222 #define RF_TOD          7
223 #define RF_STDOFF       8
224 #define RF_ABBRVAR      9
225 #define RULE_FIELDS     10
226
227 /*
228 ** Which fields are which on a Link line.
229 */
230
231 #define LF_FROM         1
232 #define LF_TO           2
233 #define LINK_FIELDS     3
234
235 /*
236 ** Which fields are which on a Leap line.
237 */
238
239 #define LP_YEAR         1
240 #define LP_MONTH        2
241 #define LP_DAY          3
242 #define LP_TIME         4
243 #define LP_CORR         5
244 #define LP_ROLL         6
245 #define LEAP_FIELDS     7
246
247 /*
248 ** Year synonyms.
249 */
250
251 #define YR_MINIMUM      0
252 #define YR_MAXIMUM      1
253 #define YR_ONLY         2
254
255 static struct rule *    rules;
256 static int              nrules; /* number of rules */
257 static int              nrules_alloc;
258
259 static struct zone *    zones;
260 static int              nzones; /* number of zones */
261 static int              nzones_alloc;
262
263 struct link {
264         const char *    l_filename;
265         int             l_linenum;
266         const char *    l_from;
267         const char *    l_to;
268 };
269
270 static struct link *    links;
271 static int              nlinks;
272 static int              nlinks_alloc;
273
274 struct lookup {
275         const char *    l_word;
276         const int       l_value;
277 };
278
279 static struct lookup const *    byword(const char * string,
280                                         const struct lookup * lp);
281
282 static struct lookup const      line_codes[] = {
283         { "Rule",       LC_RULE },
284         { "Zone",       LC_ZONE },
285         { "Link",       LC_LINK },
286         { "Leap",       LC_LEAP },
287         { NULL,         0}
288 };
289
290 static struct lookup const      mon_names[] = {
291         { "January",    TM_JANUARY },
292         { "February",   TM_FEBRUARY },
293         { "March",      TM_MARCH },
294         { "April",      TM_APRIL },
295         { "May",        TM_MAY },
296         { "June",       TM_JUNE },
297         { "July",       TM_JULY },
298         { "August",     TM_AUGUST },
299         { "September",  TM_SEPTEMBER },
300         { "October",    TM_OCTOBER },
301         { "November",   TM_NOVEMBER },
302         { "December",   TM_DECEMBER },
303         { NULL,         0 }
304 };
305
306 static struct lookup const      wday_names[] = {
307         { "Sunday",     TM_SUNDAY },
308         { "Monday",     TM_MONDAY },
309         { "Tuesday",    TM_TUESDAY },
310         { "Wednesday",  TM_WEDNESDAY },
311         { "Thursday",   TM_THURSDAY },
312         { "Friday",     TM_FRIDAY },
313         { "Saturday",   TM_SATURDAY },
314         { NULL,         0 }
315 };
316
317 static struct lookup const      lasts[] = {
318         { "last-Sunday",        TM_SUNDAY },
319         { "last-Monday",        TM_MONDAY },
320         { "last-Tuesday",       TM_TUESDAY },
321         { "last-Wednesday",     TM_WEDNESDAY },
322         { "last-Thursday",      TM_THURSDAY },
323         { "last-Friday",        TM_FRIDAY },
324         { "last-Saturday",      TM_SATURDAY },
325         { NULL,                 0 }
326 };
327
328 static struct lookup const      begin_years[] = {
329         { "minimum",    YR_MINIMUM },
330         { "maximum",    YR_MAXIMUM },
331         { NULL,         0 }
332 };
333
334 static struct lookup const      end_years[] = {
335         { "minimum",    YR_MINIMUM },
336         { "maximum",    YR_MAXIMUM },
337         { "only",       YR_ONLY },
338         { NULL,         0 }
339 };
340
341 static struct lookup const      leap_types[] = {
342         { "Rolling",    true },
343         { "Stationary", false },
344         { NULL,         0 }
345 };
346
347 static const int        len_months[2][MONSPERYEAR] = {
348         { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 },
349         { 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }
350 };
351
352 static const int        len_years[2] = {
353         DAYSPERNYEAR, DAYSPERLYEAR
354 };
355
356 static struct attype {
357         zic_t           at;
358         unsigned char   type;
359 } *                     attypes;
360 static zic_t            gmtoffs[TZ_MAX_TYPES];
361 static char             isdsts[TZ_MAX_TYPES];
362 static unsigned char    abbrinds[TZ_MAX_TYPES];
363 static bool             ttisstds[TZ_MAX_TYPES];
364 static bool             ttisgmts[TZ_MAX_TYPES];
365 static char             chars[TZ_MAX_CHARS];
366 static zic_t            trans[TZ_MAX_LEAPS];
367 static zic_t            corr[TZ_MAX_LEAPS];
368 static char             roll[TZ_MAX_LEAPS];
369
370 /*
371 ** Memory allocation.
372 */
373
374 static _Noreturn void
375 memory_exhausted(const char *msg)
376 {
377         fprintf(stderr, _("%s: Memory exhausted: %s\n"), progname, msg);
378         exit(EXIT_FAILURE);
379 }
380
381 static ATTRIBUTE_PURE size_t
382 size_product(size_t nitems, size_t itemsize)
383 {
384         if (SIZE_MAX / itemsize < nitems)
385                 memory_exhausted(_("size overflow"));
386         return nitems * itemsize;
387 }
388
389 #if !HAVE_STRDUP
390 static char *
391 strdup(char const *str)
392 {
393   char *result = malloc(strlen(str) + 1);
394   return result ? strcpy(result, str) : result;
395 }
396 #endif
397
398 static ATTRIBUTE_PURE void *
399 memcheck(void *ptr)
400 {
401         if (ptr == NULL)
402                 memory_exhausted(strerror(errno));
403         return ptr;
404 }
405
406 static void *
407 emalloc(size_t size)
408 {
409   return memcheck(malloc(size));
410 }
411
412 static void *
413 erealloc(void *ptr, size_t size)
414 {
415   return memcheck(realloc(ptr, size));
416 }
417
418 static char *
419 ecpyalloc (char const *str)
420 {
421   return memcheck(strdup(str));
422 }
423
424 static void *
425 growalloc(void *ptr, size_t itemsize, int nitems, int *nitems_alloc)
426 {
427         if (nitems < *nitems_alloc)
428                 return ptr;
429         else {
430                 int nitems_max = INT_MAX - WORK_AROUND_QTBUG_53071;
431                 int amax = nitems_max < SIZE_MAX ? nitems_max : SIZE_MAX;
432                 if ((amax - 1) / 3 * 2 < *nitems_alloc)
433                         memory_exhausted(_("int overflow"));
434                 *nitems_alloc = *nitems_alloc + (*nitems_alloc >> 1) + 1;
435                 return erealloc(ptr, size_product(*nitems_alloc, itemsize));
436         }
437 }
438
439 /*
440 ** Error handling.
441 */
442
443 static void
444 eats(const char *const name, const int num, const char *const rname,
445      const int rnum)
446 {
447         filename = name;
448         linenum = num;
449         rfilename = rname;
450         rlinenum = rnum;
451 }
452
453 static void
454 eat(const char *const name, const int num)
455 {
456         eats(name, num, NULL, -1);
457 }
458
459 static void ATTRIBUTE_FORMAT((printf, 1, 0))
460 verror(const char *const string, va_list args)
461 {
462         /*
463         ** Match the format of "cc" to allow sh users to
464         **      zic ... 2>&1 | error -t "*" -v
465         ** on BSD systems.
466         */
467         if (filename)
468           fprintf(stderr, _("\"%s\", line %d: "), filename, linenum);
469         vfprintf(stderr, string, args);
470         if (rfilename != NULL)
471                 fprintf(stderr, _(" (rule from \"%s\", line %d)"),
472                         rfilename, rlinenum);
473         fprintf(stderr, "\n");
474 }
475
476 static void ATTRIBUTE_FORMAT((printf, 1, 2))
477 error(const char *const string, ...)
478 {
479         va_list args;
480         va_start(args, string);
481         verror(string, args);
482         va_end(args);
483         errors = true;
484 }
485
486 static void ATTRIBUTE_FORMAT((printf, 1, 2))
487 warning(const char *const string, ...)
488 {
489         va_list args;
490         fprintf(stderr, _("warning: "));
491         va_start(args, string);
492         verror(string, args);
493         va_end(args);
494         warnings = true;
495 }
496
497 static void
498 close_file(FILE *stream, char const *name)
499 {
500   char const *e = (ferror(stream) ? _("I/O error")
501                    : fclose(stream) != 0 ? strerror(errno) : NULL);
502   if (e) {
503     fprintf(stderr, "%s: ", progname);
504     if (name)
505       fprintf(stderr, "%s: ", name);
506     fprintf(stderr, "%s\n", e);
507     exit(EXIT_FAILURE);
508   }
509 }
510
511 static _Noreturn void
512 usage(FILE *stream, int status)
513 {
514   fprintf(stream,
515           _("%s: usage is %s [ --version ] [ --help ] [ -v ] \\\n"
516             "\t[ -l localtime ] [ -p posixrules ] [ -d directory ] \\\n"
517             "\t[ -L leapseconds ] [ filename ... ]\n\n"
518             "Report bugs to %s.\n"),
519           progname, progname, REPORT_BUGS_TO);
520   if (status == EXIT_SUCCESS)
521     close_file(stream, NULL);
522   exit(status);
523 }
524
525 static const char *     psxrules;
526 static const char *     lcltime;
527 static const char *     directory;
528 static const char *     leapsec;
529 static const char *     yitcommand;
530
531 int
532 main(int argc, char **argv)
533 {
534         register int    i;
535         register int    j;
536         register int    c;
537
538 #ifdef S_IWGRP
539         umask(umask(S_IWGRP | S_IWOTH) | (S_IWGRP | S_IWOTH));
540 #endif
541 #if HAVE_GETTEXT
542         setlocale(LC_ALL, "");
543 #ifdef TZ_DOMAINDIR
544         bindtextdomain(TZ_DOMAIN, TZ_DOMAINDIR);
545 #endif /* defined TEXTDOMAINDIR */
546         textdomain(TZ_DOMAIN);
547 #endif /* HAVE_GETTEXT */
548         progname = argv[0];
549         if (TYPE_BIT(zic_t) < 64) {
550                 fprintf(stderr, "%s: %s\n", progname,
551                         _("wild compilation-time specification of zic_t"));
552                 return EXIT_FAILURE;
553         }
554         for (i = 1; i < argc; ++i)
555                 if (strcmp(argv[i], "--version") == 0) {
556                         printf("zic %s%s\n", PKGVERSION, TZVERSION);
557                         close_file(stdout, NULL);
558                         return EXIT_SUCCESS;
559                 } else if (strcmp(argv[i], "--help") == 0) {
560                         usage(stdout, EXIT_SUCCESS);
561                 }
562         while ((c = getopt(argc, argv, "d:l:p:L:vsy:")) != EOF && c != -1)
563                 switch (c) {
564                         default:
565                                 usage(stderr, EXIT_FAILURE);
566                         case 'd':
567                                 if (directory == NULL)
568                                         directory = optarg;
569                                 else {
570                                         fprintf(stderr,
571 _("%s: More than one -d option specified\n"),
572                                                 progname);
573                                         return EXIT_FAILURE;
574                                 }
575                                 break;
576                         case 'l':
577                                 if (lcltime == NULL)
578                                         lcltime = optarg;
579                                 else {
580                                         fprintf(stderr,
581 _("%s: More than one -l option specified\n"),
582                                                 progname);
583                                         return EXIT_FAILURE;
584                                 }
585                                 break;
586                         case 'p':
587                                 if (psxrules == NULL)
588                                         psxrules = optarg;
589                                 else {
590                                         fprintf(stderr,
591 _("%s: More than one -p option specified\n"),
592                                                 progname);
593                                         return EXIT_FAILURE;
594                                 }
595                                 break;
596                         case 'y':
597                                 if (yitcommand == NULL)
598                                         yitcommand = optarg;
599                                 else {
600                                         fprintf(stderr,
601 _("%s: More than one -y option specified\n"),
602                                                 progname);
603                                         return EXIT_FAILURE;
604                                 }
605                                 break;
606                         case 'L':
607                                 if (leapsec == NULL)
608                                         leapsec = optarg;
609                                 else {
610                                         fprintf(stderr,
611 _("%s: More than one -L option specified\n"),
612                                                 progname);
613                                         return EXIT_FAILURE;
614                                 }
615                                 break;
616                         case 'v':
617                                 noise = true;
618                                 break;
619                         case 's':
620                                 warning(_("-s ignored"));
621                                 break;
622                 }
623         if (optind == argc - 1 && strcmp(argv[optind], "=") == 0)
624                 usage(stderr, EXIT_FAILURE);    /* usage message by request */
625         if (directory == NULL)
626                 directory = TZDIR;
627         if (yitcommand == NULL)
628                 yitcommand = "yearistype";
629
630         if (optind < argc && leapsec != NULL) {
631                 infile(leapsec);
632                 adjleap();
633         }
634
635         for (i = optind; i < argc; ++i)
636                 infile(argv[i]);
637         if (errors)
638                 return EXIT_FAILURE;
639         associate();
640         for (i = 0; i < nzones; i = j) {
641                 /*
642                 ** Find the next non-continuation zone entry.
643                 */
644                 for (j = i + 1; j < nzones && zones[j].z_name == NULL; ++j)
645                         continue;
646                 outzone(&zones[i], j - i);
647         }
648         /*
649         ** Make links.
650         */
651         for (i = 0; i < nlinks; ++i) {
652                 eat(links[i].l_filename, links[i].l_linenum);
653                 dolink(links[i].l_from, links[i].l_to);
654                 if (noise)
655                         for (j = 0; j < nlinks; ++j)
656                                 if (strcmp(links[i].l_to,
657                                         links[j].l_from) == 0)
658                                                 warning(_("link to link"));
659         }
660         if (lcltime != NULL) {
661                 eat(_("command line"), 1);
662                 dolink(lcltime, TZDEFAULT);
663         }
664         if (psxrules != NULL) {
665                 eat(_("command line"), 1);
666                 dolink(psxrules, TZDEFRULES);
667         }
668         if (warnings && (ferror(stderr) || fclose(stderr) != 0))
669           return EXIT_FAILURE;
670         return errors ? EXIT_FAILURE : EXIT_SUCCESS;
671 }
672
673 static bool
674 componentcheck(char const *name, char const *component,
675                char const *component_end)
676 {
677         enum { component_len_max = 14 };
678         size_t component_len = component_end - component;
679         if (component_len == 0) {
680           if (!*name)
681             error (_("empty file name"));
682           else
683             error (_(component == name
684                      ? "file name '%s' begins with '/'"
685                      : *component_end
686                      ? "file name '%s' contains '//'"
687                      : "file name '%s' ends with '/'"),
688                    name);
689           return false;
690         }
691         if (0 < component_len && component_len <= 2
692             && component[0] == '.' && component_end[-1] == '.') {
693           error(_("file name '%s' contains '%.*s' component"),
694                 name, (int) component_len, component);
695           return false;
696         }
697         if (noise) {
698           if (0 < component_len && component[0] == '-')
699             warning(_("file name '%s' component contains leading '-'"),
700                     name);
701           if (component_len_max < component_len)
702             warning(_("file name '%s' contains overlength component"
703                       " '%.*s...'"),
704                     name, component_len_max, component);
705         }
706         return true;
707 }
708
709 static bool
710 namecheck(const char *name)
711 {
712         register char const *cp;
713
714         /* Benign characters in a portable file name.  */
715         static char const benign[] =
716           "-/_"
717           "abcdefghijklmnopqrstuvwxyz"
718           "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
719
720         /* Non-control chars in the POSIX portable character set,
721            excluding the benign characters.  */
722         static char const printable_and_not_benign[] =
723           " !\"#$%&'()*+,.0123456789:;<=>?@[\\]^`{|}~";
724
725         register char const *component = name;
726         for (cp = name; *cp; cp++) {
727                 unsigned char c = *cp;
728                 if (noise && !strchr(benign, c)) {
729                         warning((strchr(printable_and_not_benign, c)
730                                  ? _("file name '%s' contains byte '%c'")
731                                  : _("file name '%s' contains byte '\\%o'")),
732                                 name, c);
733                 }
734                 if (c == '/') {
735                         if (!componentcheck(name, component, cp))
736                           return false;
737                         component = cp + 1;
738                 }
739         }
740         return componentcheck(name, component, cp);
741 }
742
743 static char *
744 relname(char const *dir, char const *base)
745 {
746   if (*base == '/')
747     return ecpyalloc(base);
748   else {
749     size_t dir_len = strlen(dir);
750     bool needs_slash = dir_len && dir[dir_len - 1] != '/';
751     char *result = emalloc(dir_len + needs_slash + strlen(base) + 1);
752     result[dir_len] = '/';
753     strcpy(result + dir_len + needs_slash, base);
754     return memcpy(result, dir, dir_len);
755   }
756 }
757
758 static void
759 dolink(char const *fromfield, char const *tofield)
760 {
761         register char * fromname;
762         register char * toname;
763         register int fromisdir;
764
765         fromname = relname(directory, fromfield);
766         toname = relname(directory, tofield);
767         /*
768         ** We get to be careful here since
769         ** there's a fair chance of root running us.
770         */
771         fromisdir = itsdir(fromname);
772         if (fromisdir) {
773                 char const *e = strerror(fromisdir < 0 ? errno : EPERM);
774                 fprintf(stderr, _("%s: link from %s failed: %s"),
775                         progname, fromname, e);
776                 exit(EXIT_FAILURE);
777         }
778         if (link(fromname, toname) != 0) {
779           int link_errno = errno;
780           bool retry_if_link_supported = false;
781
782           if (link_errno == ENOENT || link_errno == ENOTSUP) {
783             if (! mkdirs(toname))
784               exit(EXIT_FAILURE);
785             retry_if_link_supported = true;
786           }
787           if ((link_errno == EEXIST || link_errno == ENOTSUP)
788               && itsdir(toname) == 0
789               && (remove(toname) == 0 || errno == ENOENT))
790             retry_if_link_supported = true;
791           if (retry_if_link_supported && link_errno != ENOTSUP)
792             link_errno = link(fromname, toname) == 0 ? 0 : errno;
793           if (link_errno != 0) {
794             const char *s = fromfield;
795             const char *t;
796             char *p;
797             size_t dotdots = 0;
798             char *symlinkcontents;
799             int symlink_result;
800
801             do
802               t = s;
803             while ((s = strchr(s, '/'))
804                    && strncmp(fromfield, tofield, ++s - fromfield) == 0);
805
806             for (s = tofield + (t - fromfield); *s; s++)
807               dotdots += *s == '/';
808             symlinkcontents = emalloc(3 * dotdots + strlen(t) + 1);
809             for (p = symlinkcontents; dotdots-- != 0; p += 3)
810               memcpy(p, "../", 3);
811             strcpy(p, t);
812             symlink_result = symlink(symlinkcontents, toname);
813             free(symlinkcontents);
814             if (symlink_result == 0) {
815               if (link_errno != ENOTSUP)
816                 warning(_("symbolic link used because hard link failed: %s"),
817                         strerror (link_errno));
818             } else {
819                         FILE *fp, *tp;
820                         int c;
821                         fp = fopen(fromname, "rb");
822                         if (!fp) {
823                                 const char *e = strerror(errno);
824                                 fprintf(stderr,
825                                                _("%s: Can't read %s: %s\n"),
826                                                progname, fromname, e);
827                                 exit(EXIT_FAILURE);
828                         }
829                         tp = fopen(toname, "wb");
830                         if (!tp) {
831                                 const char *e = strerror(errno);
832                                 fprintf(stderr,
833                                                _("%s: Can't create %s: %s\n"),
834                                                progname, toname, e);
835                                 exit(EXIT_FAILURE);
836                         }
837                         while ((c = getc(fp)) != EOF)
838                                 putc(c, tp);
839                         close_file(fp, fromname);
840                         close_file(tp, toname);
841                         if (link_errno != ENOTSUP)
842                           warning(_("copy used because hard link failed: %s"),
843                                   strerror (link_errno));
844             }
845           }
846         }
847         free(fromname);
848         free(toname);
849 }
850
851 #define TIME_T_BITS_IN_FILE     64
852
853 static zic_t const min_time = MINVAL (zic_t, TIME_T_BITS_IN_FILE);
854 static zic_t const max_time = MAXVAL (zic_t, TIME_T_BITS_IN_FILE);
855
856 /* Estimated time of the Big Bang, in seconds since the POSIX epoch.
857    rounded downward to the negation of a power of two that is
858    comfortably outside the error bounds.
859
860    For the time of the Big Bang, see:
861
862    Ade PAR, Aghanim N, Armitage-Caplan C et al.  Planck 2013 results.
863    I. Overview of products and scientific results.
864    arXiv:1303.5062 2013-03-20 20:10:01 UTC
865    <http://arxiv.org/pdf/1303.5062v1> [PDF]
866
867    Page 36, Table 9, row Age/Gyr, column Planck+WP+highL+BAO 68% limits
868    gives the value 13.798 plus-or-minus 0.037 billion years.
869    Multiplying this by 1000000000 and then by 31557600 (the number of
870    seconds in an astronomical year) gives a value that is comfortably
871    less than 2**59, so BIG_BANG is - 2**59.
872
873    BIG_BANG is approximate, and may change in future versions.
874    Please do not rely on its exact value.  */
875
876 #ifndef BIG_BANG
877 #define BIG_BANG (- (1LL << 59))
878 #endif
879
880 /* If true, work around GNOME bug 730332
881    <https://bugzilla.gnome.org/show_bug.cgi?id=730332>
882    by refusing to output time stamps before BIG_BANG.
883    Such time stamps are physically suspect anyway.
884
885    The GNOME bug is scheduled to be fixed in GNOME 3.22, and if so
886    this workaround will no longer be needed when GNOME 3.21 and
887    earlier are obsolete, say in the year 2021.  */
888 enum { WORK_AROUND_GNOME_BUG_730332 = true };
889
890 static const zic_t early_time = (WORK_AROUND_GNOME_BUG_730332
891                                  ? BIG_BANG
892                                  : MINVAL(zic_t, TIME_T_BITS_IN_FILE));
893
894 /* Return 1 if NAME is a directory, 0 if it's something else, -1 if trouble.  */
895 static int
896 itsdir(char const *name)
897 {
898         struct stat st;
899         int res = stat(name, &st);
900 #ifdef S_ISDIR
901         if (res == 0)
902                 return S_ISDIR(st.st_mode) != 0;
903 #endif
904         if (res == 0 || errno == EOVERFLOW) {
905                 char *nameslashdot = relname(name, ".");
906                 bool dir = stat(nameslashdot, &st) == 0 || errno == EOVERFLOW;
907                 free(nameslashdot);
908                 return dir;
909         }
910         return -1;
911 }
912
913 /*
914 ** Associate sets of rules with zones.
915 */
916
917 /*
918 ** Sort by rule name.
919 */
920
921 static int
922 rcomp(const void *cp1, const void *cp2)
923 {
924         return strcmp(((const struct rule *) cp1)->r_name,
925                 ((const struct rule *) cp2)->r_name);
926 }
927
928 static void
929 associate(void)
930 {
931         register struct zone *  zp;
932         register struct rule *  rp;
933         register int            base, out;
934         register int            i, j;
935
936         if (nrules != 0) {
937                 qsort(rules, nrules, sizeof *rules, rcomp);
938                 for (i = 0; i < nrules - 1; ++i) {
939                         if (strcmp(rules[i].r_name,
940                                 rules[i + 1].r_name) != 0)
941                                         continue;
942                         if (strcmp(rules[i].r_filename,
943                                 rules[i + 1].r_filename) == 0)
944                                         continue;
945                         eat(rules[i].r_filename, rules[i].r_linenum);
946                         warning(_("same rule name in multiple files"));
947                         eat(rules[i + 1].r_filename, rules[i + 1].r_linenum);
948                         warning(_("same rule name in multiple files"));
949                         for (j = i + 2; j < nrules; ++j) {
950                                 if (strcmp(rules[i].r_name,
951                                         rules[j].r_name) != 0)
952                                                 break;
953                                 if (strcmp(rules[i].r_filename,
954                                         rules[j].r_filename) == 0)
955                                                 continue;
956                                 if (strcmp(rules[i + 1].r_filename,
957                                         rules[j].r_filename) == 0)
958                                                 continue;
959                                 break;
960                         }
961                         i = j - 1;
962                 }
963         }
964         for (i = 0; i < nzones; ++i) {
965                 zp = &zones[i];
966                 zp->z_rules = NULL;
967                 zp->z_nrules = 0;
968         }
969         for (base = 0; base < nrules; base = out) {
970                 rp = &rules[base];
971                 for (out = base + 1; out < nrules; ++out)
972                         if (strcmp(rp->r_name, rules[out].r_name) != 0)
973                                 break;
974                 for (i = 0; i < nzones; ++i) {
975                         zp = &zones[i];
976                         if (strcmp(zp->z_rule, rp->r_name) != 0)
977                                 continue;
978                         zp->z_rules = rp;
979                         zp->z_nrules = out - base;
980                 }
981         }
982         for (i = 0; i < nzones; ++i) {
983                 zp = &zones[i];
984                 if (zp->z_nrules == 0) {
985                         /*
986                         ** Maybe we have a local standard time offset.
987                         */
988                         eat(zp->z_filename, zp->z_linenum);
989                         zp->z_stdoff = gethms(zp->z_rule, _("unruly zone"),
990                                 true);
991                         /*
992                         ** Note, though, that if there's no rule,
993                         ** a '%s' in the format is a bad thing.
994                         */
995                         if (zp->z_format_specifier == 's')
996                                 error("%s", _("%s in ruleless zone"));
997                 }
998         }
999         if (errors)
1000                 exit(EXIT_FAILURE);
1001 }
1002
1003 static void
1004 infile(const char *name)
1005 {
1006         register FILE *                 fp;
1007         register char **                fields;
1008         register char *                 cp;
1009         register const struct lookup *  lp;
1010         register int                    nfields;
1011         register bool                   wantcont;
1012         register int                    num;
1013         char                            buf[BUFSIZ];
1014
1015         if (strcmp(name, "-") == 0) {
1016                 name = _("standard input");
1017                 fp = stdin;
1018         } else if ((fp = fopen(name, "r")) == NULL) {
1019                 const char *e = strerror(errno);
1020
1021                 fprintf(stderr, _("%s: Can't open %s: %s\n"),
1022                         progname, name, e);
1023                 exit(EXIT_FAILURE);
1024         }
1025         wantcont = false;
1026         for (num = 1; ; ++num) {
1027                 eat(name, num);
1028                 if (fgets(buf, sizeof buf, fp) != buf)
1029                         break;
1030                 cp = strchr(buf, '\n');
1031                 if (cp == NULL) {
1032                         error(_("line too long"));
1033                         exit(EXIT_FAILURE);
1034                 }
1035                 *cp = '\0';
1036                 fields = getfields(buf);
1037                 nfields = 0;
1038                 while (fields[nfields] != NULL) {
1039                         static char     nada;
1040
1041                         if (strcmp(fields[nfields], "-") == 0)
1042                                 fields[nfields] = &nada;
1043                         ++nfields;
1044                 }
1045                 if (nfields == 0) {
1046                         /* nothing to do */
1047                 } else if (wantcont) {
1048                         wantcont = inzcont(fields, nfields);
1049                 } else {
1050                         lp = byword(fields[0], line_codes);
1051                         if (lp == NULL)
1052                                 error(_("input line of unknown type"));
1053                         else switch ((int) (lp->l_value)) {
1054                                 case LC_RULE:
1055                                         inrule(fields, nfields);
1056                                         wantcont = false;
1057                                         break;
1058                                 case LC_ZONE:
1059                                         wantcont = inzone(fields, nfields);
1060                                         break;
1061                                 case LC_LINK:
1062                                         inlink(fields, nfields);
1063                                         wantcont = false;
1064                                         break;
1065                                 case LC_LEAP:
1066                                         if (name != leapsec)
1067                                           warning(_("%s: Leap line in non leap"
1068                                                     " seconds file %s"),
1069                                                   progname, name);
1070                                         else    inleap(fields, nfields);
1071                                         wantcont = false;
1072                                         break;
1073                                 default:        /* "cannot happen" */
1074                                         fprintf(stderr,
1075 _("%s: panic: Invalid l_value %d\n"),
1076                                                 progname, lp->l_value);
1077                                         exit(EXIT_FAILURE);
1078                         }
1079                 }
1080                 free(fields);
1081         }
1082         close_file(fp, filename);
1083         if (wantcont)
1084                 error(_("expected continuation line not found"));
1085 }
1086
1087 /*
1088 ** Convert a string of one of the forms
1089 **      h       -h      hh:mm   -hh:mm  hh:mm:ss        -hh:mm:ss
1090 ** into a number of seconds.
1091 ** A null string maps to zero.
1092 ** Call error with errstring and return zero on errors.
1093 */
1094
1095 static zic_t
1096 gethms(char const *string, char const *errstring, bool signable)
1097 {
1098         zic_t   hh;
1099         int     mm, ss, sign;
1100         char xs;
1101
1102         if (string == NULL || *string == '\0')
1103                 return 0;
1104         if (!signable)
1105                 sign = 1;
1106         else if (*string == '-') {
1107                 sign = -1;
1108                 ++string;
1109         } else  sign = 1;
1110         if (sscanf(string, "%"SCNdZIC"%c", &hh, &xs) == 1)
1111                 mm = ss = 0;
1112         else if (sscanf(string, "%"SCNdZIC":%d%c", &hh, &mm, &xs) == 2)
1113                 ss = 0;
1114         else if (sscanf(string, "%"SCNdZIC":%d:%d%c", &hh, &mm, &ss, &xs)
1115                  != 3) {
1116                         error("%s", errstring);
1117                         return 0;
1118         }
1119         if (hh < 0 ||
1120                 mm < 0 || mm >= MINSPERHOUR ||
1121                 ss < 0 || ss > SECSPERMIN) {
1122                         error("%s", errstring);
1123                         return 0;
1124         }
1125         if (ZIC_MAX / SECSPERHOUR < hh) {
1126                 error(_("time overflow"));
1127                 return 0;
1128         }
1129         if (noise && (hh > HOURSPERDAY ||
1130                 (hh == HOURSPERDAY && (mm != 0 || ss != 0))))
1131 warning(_("values over 24 hours not handled by pre-2007 versions of zic"));
1132         return oadd(sign * hh * SECSPERHOUR,
1133                     sign * (mm * SECSPERMIN + ss));
1134 }
1135
1136 static void
1137 inrule(char **fields, int nfields)
1138 {
1139         static struct rule      r;
1140
1141         if (nfields != RULE_FIELDS) {
1142                 error(_("wrong number of fields on Rule line"));
1143                 return;
1144         }
1145         if (*fields[RF_NAME] == '\0') {
1146                 error(_("nameless rule"));
1147                 return;
1148         }
1149         r.r_filename = filename;
1150         r.r_linenum = linenum;
1151         r.r_stdoff = gethms(fields[RF_STDOFF], _("invalid saved time"), true);
1152         rulesub(&r, fields[RF_LOYEAR], fields[RF_HIYEAR], fields[RF_COMMAND],
1153                 fields[RF_MONTH], fields[RF_DAY], fields[RF_TOD]);
1154         r.r_name = ecpyalloc(fields[RF_NAME]);
1155         r.r_abbrvar = ecpyalloc(fields[RF_ABBRVAR]);
1156         if (max_abbrvar_len < strlen(r.r_abbrvar))
1157                 max_abbrvar_len = strlen(r.r_abbrvar);
1158         rules = growalloc(rules, sizeof *rules, nrules, &nrules_alloc);
1159         rules[nrules++] = r;
1160 }
1161
1162 static bool
1163 inzone(char **fields, int nfields)
1164 {
1165         register int    i;
1166
1167         if (nfields < ZONE_MINFIELDS || nfields > ZONE_MAXFIELDS) {
1168                 error(_("wrong number of fields on Zone line"));
1169                 return false;
1170         }
1171         if (strcmp(fields[ZF_NAME], TZDEFAULT) == 0 && lcltime != NULL) {
1172                 error(
1173 _("\"Zone %s\" line and -l option are mutually exclusive"),
1174                         TZDEFAULT);
1175                 return false;
1176         }
1177         if (strcmp(fields[ZF_NAME], TZDEFRULES) == 0 && psxrules != NULL) {
1178                 error(
1179 _("\"Zone %s\" line and -p option are mutually exclusive"),
1180                         TZDEFRULES);
1181                 return false;
1182         }
1183         for (i = 0; i < nzones; ++i)
1184                 if (zones[i].z_name != NULL &&
1185                         strcmp(zones[i].z_name, fields[ZF_NAME]) == 0) {
1186                                 error(
1187 _("duplicate zone name %s (file \"%s\", line %d)"),
1188                                         fields[ZF_NAME],
1189                                         zones[i].z_filename,
1190                                         zones[i].z_linenum);
1191                                 return false;
1192                 }
1193         return inzsub(fields, nfields, false);
1194 }
1195
1196 static bool
1197 inzcont(char **fields, int nfields)
1198 {
1199         if (nfields < ZONEC_MINFIELDS || nfields > ZONEC_MAXFIELDS) {
1200                 error(_("wrong number of fields on Zone continuation line"));
1201                 return false;
1202         }
1203         return inzsub(fields, nfields, true);
1204 }
1205
1206 static bool
1207 inzsub(char **fields, int nfields, bool iscont)
1208 {
1209         register char *         cp;
1210         char *                  cp1;
1211         static struct zone      z;
1212         register int            i_gmtoff, i_rule, i_format;
1213         register int            i_untilyear, i_untilmonth;
1214         register int            i_untilday, i_untiltime;
1215         register bool           hasuntil;
1216
1217         if (iscont) {
1218                 i_gmtoff = ZFC_GMTOFF;
1219                 i_rule = ZFC_RULE;
1220                 i_format = ZFC_FORMAT;
1221                 i_untilyear = ZFC_TILYEAR;
1222                 i_untilmonth = ZFC_TILMONTH;
1223                 i_untilday = ZFC_TILDAY;
1224                 i_untiltime = ZFC_TILTIME;
1225                 z.z_name = NULL;
1226         } else if (!namecheck(fields[ZF_NAME]))
1227                 return false;
1228         else {
1229                 i_gmtoff = ZF_GMTOFF;
1230                 i_rule = ZF_RULE;
1231                 i_format = ZF_FORMAT;
1232                 i_untilyear = ZF_TILYEAR;
1233                 i_untilmonth = ZF_TILMONTH;
1234                 i_untilday = ZF_TILDAY;
1235                 i_untiltime = ZF_TILTIME;
1236                 z.z_name = ecpyalloc(fields[ZF_NAME]);
1237         }
1238         z.z_filename = filename;
1239         z.z_linenum = linenum;
1240         z.z_gmtoff = gethms(fields[i_gmtoff], _("invalid UT offset"), true);
1241         if ((cp = strchr(fields[i_format], '%')) != 0) {
1242                 if ((*++cp != 's' && *cp != 'z') || strchr(cp, '%')
1243                     || strchr(fields[i_format], '/')) {
1244                         error(_("invalid abbreviation format"));
1245                         return false;
1246                 }
1247         }
1248         z.z_rule = ecpyalloc(fields[i_rule]);
1249         z.z_format = cp1 = ecpyalloc(fields[i_format]);
1250         z.z_format_specifier = cp ? *cp : '\0';
1251         if (z.z_format_specifier == 'z') {
1252           if (noise)
1253             warning(_("format '%s' not handled by pre-2015 versions of zic"),
1254                     z.z_format);
1255           cp1[cp - fields[i_format]] = 's';
1256         }
1257         if (max_format_len < strlen(z.z_format))
1258                 max_format_len = strlen(z.z_format);
1259         hasuntil = nfields > i_untilyear;
1260         if (hasuntil) {
1261                 z.z_untilrule.r_filename = filename;
1262                 z.z_untilrule.r_linenum = linenum;
1263                 rulesub(&z.z_untilrule,
1264                         fields[i_untilyear],
1265                         "only",
1266                         "",
1267                         (nfields > i_untilmonth) ?
1268                         fields[i_untilmonth] : "Jan",
1269                         (nfields > i_untilday) ? fields[i_untilday] : "1",
1270                         (nfields > i_untiltime) ? fields[i_untiltime] : "0");
1271                 z.z_untiltime = rpytime(&z.z_untilrule,
1272                         z.z_untilrule.r_loyear);
1273                 if (iscont && nzones > 0 &&
1274                         z.z_untiltime > min_time &&
1275                         z.z_untiltime < max_time &&
1276                         zones[nzones - 1].z_untiltime > min_time &&
1277                         zones[nzones - 1].z_untiltime < max_time &&
1278                         zones[nzones - 1].z_untiltime >= z.z_untiltime) {
1279                                 error(_(
1280 "Zone continuation line end time is not after end time of previous line"
1281                                         ));
1282                                 return false;
1283                 }
1284         }
1285         zones = growalloc(zones, sizeof *zones, nzones, &nzones_alloc);
1286         zones[nzones++] = z;
1287         /*
1288         ** If there was an UNTIL field on this line,
1289         ** there's more information about the zone on the next line.
1290         */
1291         return hasuntil;
1292 }
1293
1294 static void
1295 inleap(char **fields, int nfields)
1296 {
1297         register const char *           cp;
1298         register const struct lookup *  lp;
1299         register int                    i, j;
1300         zic_t                           year;
1301         int                             month, day;
1302         zic_t                           dayoff, tod;
1303         zic_t                           t;
1304         char xs;
1305
1306         if (nfields != LEAP_FIELDS) {
1307                 error(_("wrong number of fields on Leap line"));
1308                 return;
1309         }
1310         dayoff = 0;
1311         cp = fields[LP_YEAR];
1312         if (sscanf(cp, "%"SCNdZIC"%c", &year, &xs) != 1) {
1313                 /*
1314                 ** Leapin' Lizards!
1315                 */
1316                 error(_("invalid leaping year"));
1317                 return;
1318         }
1319         if (!leapseen || leapmaxyear < year)
1320                 leapmaxyear = year;
1321         if (!leapseen || leapminyear > year)
1322                 leapminyear = year;
1323         leapseen = true;
1324         j = EPOCH_YEAR;
1325         while (j != year) {
1326                 if (year > j) {
1327                         i = len_years[isleap(j)];
1328                         ++j;
1329                 } else {
1330                         --j;
1331                         i = -len_years[isleap(j)];
1332                 }
1333                 dayoff = oadd(dayoff, i);
1334         }
1335         if ((lp = byword(fields[LP_MONTH], mon_names)) == NULL) {
1336                 error(_("invalid month name"));
1337                 return;
1338         }
1339         month = lp->l_value;
1340         j = TM_JANUARY;
1341         while (j != month) {
1342                 i = len_months[isleap(year)][j];
1343                 dayoff = oadd(dayoff, i);
1344                 ++j;
1345         }
1346         cp = fields[LP_DAY];
1347         if (sscanf(cp, "%d%c", &day, &xs) != 1 ||
1348                 day <= 0 || day > len_months[isleap(year)][month]) {
1349                         error(_("invalid day of month"));
1350                         return;
1351         }
1352         dayoff = oadd(dayoff, day - 1);
1353         if (dayoff < min_time / SECSPERDAY) {
1354                 error(_("time too small"));
1355                 return;
1356         }
1357         if (dayoff > max_time / SECSPERDAY) {
1358                 error(_("time too large"));
1359                 return;
1360         }
1361         t = dayoff * SECSPERDAY;
1362         tod = gethms(fields[LP_TIME], _("invalid time of day"), false);
1363         cp = fields[LP_CORR];
1364         {
1365                 register bool   positive;
1366                 int             count;
1367
1368                 if (strcmp(cp, "") == 0) { /* infile() turns "-" into "" */
1369                         positive = false;
1370                         count = 1;
1371                 } else if (strcmp(cp, "--") == 0) {
1372                         positive = false;
1373                         count = 2;
1374                 } else if (strcmp(cp, "+") == 0) {
1375                         positive = true;
1376                         count = 1;
1377                 } else if (strcmp(cp, "++") == 0) {
1378                         positive = true;
1379                         count = 2;
1380                 } else {
1381                         error(_("illegal CORRECTION field on Leap line"));
1382                         return;
1383                 }
1384                 if ((lp = byword(fields[LP_ROLL], leap_types)) == NULL) {
1385                         error(_(
1386                                 "illegal Rolling/Stationary field on Leap line"
1387                                 ));
1388                         return;
1389                 }
1390                 t = tadd(t, tod);
1391                 if (t < early_time) {
1392                         error(_("leap second precedes Big Bang"));
1393                         return;
1394                 }
1395                 leapadd(t, positive, lp->l_value, count);
1396         }
1397 }
1398
1399 static void
1400 inlink(char **fields, int nfields)
1401 {
1402         struct link     l;
1403
1404         if (nfields != LINK_FIELDS) {
1405                 error(_("wrong number of fields on Link line"));
1406                 return;
1407         }
1408         if (*fields[LF_FROM] == '\0') {
1409                 error(_("blank FROM field on Link line"));
1410                 return;
1411         }
1412         if (! namecheck(fields[LF_TO]))
1413           return;
1414         l.l_filename = filename;
1415         l.l_linenum = linenum;
1416         l.l_from = ecpyalloc(fields[LF_FROM]);
1417         l.l_to = ecpyalloc(fields[LF_TO]);
1418         links = growalloc(links, sizeof *links, nlinks, &nlinks_alloc);
1419         links[nlinks++] = l;
1420 }
1421
1422 static void
1423 rulesub(struct rule *rp, const char *loyearp, const char *hiyearp,
1424         const char *typep, const char *monthp, const char *dayp,
1425         const char *timep)
1426 {
1427         register const struct lookup *  lp;
1428         register const char *           cp;
1429         register char *                 dp;
1430         register char *                 ep;
1431         char xs;
1432
1433         if ((lp = byword(monthp, mon_names)) == NULL) {
1434                 error(_("invalid month name"));
1435                 return;
1436         }
1437         rp->r_month = lp->l_value;
1438         rp->r_todisstd = false;
1439         rp->r_todisgmt = false;
1440         dp = ecpyalloc(timep);
1441         if (*dp != '\0') {
1442                 ep = dp + strlen(dp) - 1;
1443                 switch (lowerit(*ep)) {
1444                         case 's':       /* Standard */
1445                                 rp->r_todisstd = true;
1446                                 rp->r_todisgmt = false;
1447                                 *ep = '\0';
1448                                 break;
1449                         case 'w':       /* Wall */
1450                                 rp->r_todisstd = false;
1451                                 rp->r_todisgmt = false;
1452                                 *ep = '\0';
1453                                 break;
1454                         case 'g':       /* Greenwich */
1455                         case 'u':       /* Universal */
1456                         case 'z':       /* Zulu */
1457                                 rp->r_todisstd = true;
1458                                 rp->r_todisgmt = true;
1459                                 *ep = '\0';
1460                                 break;
1461                 }
1462         }
1463         rp->r_tod = gethms(dp, _("invalid time of day"), false);
1464         free(dp);
1465         /*
1466         ** Year work.
1467         */
1468         cp = loyearp;
1469         lp = byword(cp, begin_years);
1470         rp->r_lowasnum = lp == NULL;
1471         if (!rp->r_lowasnum) switch ((int) lp->l_value) {
1472                 case YR_MINIMUM:
1473                         rp->r_loyear = ZIC_MIN;
1474                         break;
1475                 case YR_MAXIMUM:
1476                         rp->r_loyear = ZIC_MAX;
1477                         break;
1478                 default:        /* "cannot happen" */
1479                         fprintf(stderr,
1480                                 _("%s: panic: Invalid l_value %d\n"),
1481                                 progname, lp->l_value);
1482                         exit(EXIT_FAILURE);
1483         } else if (sscanf(cp, "%"SCNdZIC"%c", &rp->r_loyear, &xs) != 1) {
1484                 error(_("invalid starting year"));
1485                 return;
1486         }
1487         cp = hiyearp;
1488         lp = byword(cp, end_years);
1489         rp->r_hiwasnum = lp == NULL;
1490         if (!rp->r_hiwasnum) switch ((int) lp->l_value) {
1491                 case YR_MINIMUM:
1492                         rp->r_hiyear = ZIC_MIN;
1493                         break;
1494                 case YR_MAXIMUM:
1495                         rp->r_hiyear = ZIC_MAX;
1496                         break;
1497                 case YR_ONLY:
1498                         rp->r_hiyear = rp->r_loyear;
1499                         break;
1500                 default:        /* "cannot happen" */
1501                         fprintf(stderr,
1502                                 _("%s: panic: Invalid l_value %d\n"),
1503                                 progname, lp->l_value);
1504                         exit(EXIT_FAILURE);
1505         } else if (sscanf(cp, "%"SCNdZIC"%c", &rp->r_hiyear, &xs) != 1) {
1506                 error(_("invalid ending year"));
1507                 return;
1508         }
1509         if (rp->r_loyear > rp->r_hiyear) {
1510                 error(_("starting year greater than ending year"));
1511                 return;
1512         }
1513         if (*typep == '\0')
1514                 rp->r_yrtype = NULL;
1515         else {
1516                 if (rp->r_loyear == rp->r_hiyear) {
1517                         error(_("typed single year"));
1518                         return;
1519                 }
1520                 rp->r_yrtype = ecpyalloc(typep);
1521         }
1522         /*
1523         ** Day work.
1524         ** Accept things such as:
1525         **      1
1526         **      last-Sunday
1527         **      Sun<=20
1528         **      Sun>=7
1529         */
1530         dp = ecpyalloc(dayp);
1531         if ((lp = byword(dp, lasts)) != NULL) {
1532                 rp->r_dycode = DC_DOWLEQ;
1533                 rp->r_wday = lp->l_value;
1534                 rp->r_dayofmonth = len_months[1][rp->r_month];
1535         } else {
1536                 if ((ep = strchr(dp, '<')) != 0)
1537                         rp->r_dycode = DC_DOWLEQ;
1538                 else if ((ep = strchr(dp, '>')) != 0)
1539                         rp->r_dycode = DC_DOWGEQ;
1540                 else {
1541                         ep = dp;
1542                         rp->r_dycode = DC_DOM;
1543                 }
1544                 if (rp->r_dycode != DC_DOM) {
1545                         *ep++ = 0;
1546                         if (*ep++ != '=') {
1547                                 error(_("invalid day of month"));
1548                                 free(dp);
1549                                 return;
1550                         }
1551                         if ((lp = byword(dp, wday_names)) == NULL) {
1552                                 error(_("invalid weekday name"));
1553                                 free(dp);
1554                                 return;
1555                         }
1556                         rp->r_wday = lp->l_value;
1557                 }
1558                 if (sscanf(ep, "%d%c", &rp->r_dayofmonth, &xs) != 1 ||
1559                         rp->r_dayofmonth <= 0 ||
1560                         (rp->r_dayofmonth > len_months[1][rp->r_month])) {
1561                                 error(_("invalid day of month"));
1562                                 free(dp);
1563                                 return;
1564                 }
1565         }
1566         free(dp);
1567 }
1568
1569 static void
1570 convert(const int_fast32_t val, char *const buf)
1571 {
1572         register int    i;
1573         register int    shift;
1574         unsigned char *const b = (unsigned char *) buf;
1575
1576         for (i = 0, shift = 24; i < 4; ++i, shift -= 8)
1577                 b[i] = val >> shift;
1578 }
1579
1580 static void
1581 convert64(const zic_t val, char *const buf)
1582 {
1583         register int    i;
1584         register int    shift;
1585         unsigned char *const b = (unsigned char *) buf;
1586
1587         for (i = 0, shift = 56; i < 8; ++i, shift -= 8)
1588                 b[i] = val >> shift;
1589 }
1590
1591 static void
1592 puttzcode(const int_fast32_t val, FILE *const fp)
1593 {
1594         char    buf[4];
1595
1596         convert(val, buf);
1597         fwrite(buf, sizeof buf, 1, fp);
1598 }
1599
1600 static void
1601 puttzcode64(const zic_t val, FILE *const fp)
1602 {
1603         char    buf[8];
1604
1605         convert64(val, buf);
1606         fwrite(buf, sizeof buf, 1, fp);
1607 }
1608
1609 static int
1610 atcomp(const void *avp, const void *bvp)
1611 {
1612         const zic_t     a = ((const struct attype *) avp)->at;
1613         const zic_t     b = ((const struct attype *) bvp)->at;
1614
1615         return (a < b) ? -1 : (a > b);
1616 }
1617
1618 static bool
1619 is32(const zic_t x)
1620 {
1621         return INT32_MIN <= x && x <= INT32_MAX;
1622 }
1623
1624 static void
1625 writezone(const char *const name, const char *const string, char version)
1626 {
1627         register FILE *                 fp;
1628         register int                    i, j;
1629         register int                    leapcnt32, leapi32;
1630         register int                    timecnt32, timei32;
1631         register int                    pass;
1632         char *                          fullname;
1633         static const struct tzhead      tzh0;
1634         static struct tzhead            tzh;
1635         zic_t one = 1;
1636         zic_t y2038_boundary = one << 31;
1637         int nats = timecnt + WORK_AROUND_QTBUG_53071;
1638         zic_t *ats = emalloc(size_product(nats, sizeof *ats + 1));
1639         void *typesptr = ats + nats;
1640         unsigned char *types = typesptr;
1641
1642         /*
1643         ** Sort.
1644         */
1645         if (timecnt > 1)
1646                 qsort(attypes, timecnt, sizeof *attypes, atcomp);
1647         /*
1648         ** Optimize.
1649         */
1650         {
1651                 int     fromi;
1652                 int     toi;
1653
1654                 toi = 0;
1655                 fromi = 0;
1656                 while (fromi < timecnt && attypes[fromi].at < early_time)
1657                         ++fromi;
1658                 for ( ; fromi < timecnt; ++fromi) {
1659                         if (toi > 1 && ((attypes[fromi].at +
1660                                 gmtoffs[attypes[toi - 1].type]) <=
1661                                 (attypes[toi - 1].at +
1662                                 gmtoffs[attypes[toi - 2].type]))) {
1663                                         attypes[toi - 1].type =
1664                                                 attypes[fromi].type;
1665                                         continue;
1666                         }
1667                         if (toi == 0 ||
1668                                 attypes[toi - 1].type != attypes[fromi].type)
1669                                         attypes[toi++] = attypes[fromi];
1670                 }
1671                 timecnt = toi;
1672         }
1673         if (noise && timecnt > 1200)
1674                 warning(_("pre-2014 clients may mishandle"
1675                           " more than 1200 transition times"));
1676         /*
1677         ** Transfer.
1678         */
1679         for (i = 0; i < timecnt; ++i) {
1680                 ats[i] = attypes[i].at;
1681                 types[i] = attypes[i].type;
1682         }
1683
1684         /* Work around QTBUG-53071 for time stamps less than y2038_boundary - 1,
1685            by inserting a no-op transition at time y2038_boundary - 1.
1686            This works only for timestamps before the boundary, which
1687            should be good enough in practice as QTBUG-53071 should be
1688            long-dead by 2038.  */
1689         if (WORK_AROUND_QTBUG_53071 && timecnt != 0
1690             && ats[timecnt - 1] < y2038_boundary - 1 && strchr(string, '<')) {
1691           ats[timecnt] = y2038_boundary - 1;
1692           types[timecnt] = types[timecnt - 1];
1693           timecnt++;
1694         }
1695
1696         /*
1697         ** Correct for leap seconds.
1698         */
1699         for (i = 0; i < timecnt; ++i) {
1700                 j = leapcnt;
1701                 while (--j >= 0)
1702                         if (ats[i] > trans[j] - corr[j]) {
1703                                 ats[i] = tadd(ats[i], corr[j]);
1704                                 break;
1705                         }
1706         }
1707         /*
1708         ** Figure out 32-bit-limited starts and counts.
1709         */
1710         timecnt32 = timecnt;
1711         timei32 = 0;
1712         leapcnt32 = leapcnt;
1713         leapi32 = 0;
1714         while (timecnt32 > 0 && !is32(ats[timecnt32 - 1]))
1715                 --timecnt32;
1716         while (timecnt32 > 0 && !is32(ats[timei32])) {
1717                 --timecnt32;
1718                 ++timei32;
1719         }
1720         /*
1721         ** Output an INT32_MIN "transition" if appropriate; see below.
1722         */
1723         if (timei32 > 0 && ats[timei32] > INT32_MIN) {
1724                 --timei32;
1725                 ++timecnt32;
1726         }
1727         while (leapcnt32 > 0 && !is32(trans[leapcnt32 - 1]))
1728                 --leapcnt32;
1729         while (leapcnt32 > 0 && !is32(trans[leapi32])) {
1730                 --leapcnt32;
1731                 ++leapi32;
1732         }
1733         fullname = relname(directory, name);
1734         /*
1735         ** Remove old file, if any, to snap links.
1736         */
1737         if (itsdir(fullname) == 0 && remove(fullname) != 0 && errno != ENOENT) {
1738                 const char *e = strerror(errno);
1739
1740                 fprintf(stderr, _("%s: Can't remove %s: %s\n"),
1741                         progname, fullname, e);
1742                 exit(EXIT_FAILURE);
1743         }
1744         if ((fp = fopen(fullname, "wb")) == NULL) {
1745                 if (! mkdirs(fullname))
1746                         exit(EXIT_FAILURE);
1747                 if ((fp = fopen(fullname, "wb")) == NULL) {
1748                         const char *e = strerror(errno);
1749
1750                         fprintf(stderr, _("%s: Can't create %s: %s\n"),
1751                                 progname, fullname, e);
1752                         exit(EXIT_FAILURE);
1753                 }
1754         }
1755         for (pass = 1; pass <= 2; ++pass) {
1756                 register int    thistimei, thistimecnt;
1757                 register int    thisleapi, thisleapcnt;
1758                 register int    thistimelim, thisleaplim;
1759                 int             writetype[TZ_MAX_TYPES];
1760                 int             typemap[TZ_MAX_TYPES];
1761                 register int    thistypecnt;
1762                 char            thischars[TZ_MAX_CHARS];
1763                 char            thischarcnt;
1764                 int             indmap[TZ_MAX_CHARS];
1765
1766                 if (pass == 1) {
1767                         thistimei = timei32;
1768                         thistimecnt = timecnt32;
1769                         thisleapi = leapi32;
1770                         thisleapcnt = leapcnt32;
1771                 } else {
1772                         thistimei = 0;
1773                         thistimecnt = timecnt;
1774                         thisleapi = 0;
1775                         thisleapcnt = leapcnt;
1776                 }
1777                 thistimelim = thistimei + thistimecnt;
1778                 thisleaplim = thisleapi + thisleapcnt;
1779                 for (i = 0; i < typecnt; ++i)
1780                         writetype[i] = thistimecnt == timecnt;
1781                 if (thistimecnt == 0) {
1782                         /*
1783                         ** No transition times fall in the current
1784                         ** (32- or 64-bit) window.
1785                         */
1786                         if (typecnt != 0)
1787                                 writetype[typecnt - 1] = true;
1788                 } else {
1789                         for (i = thistimei - 1; i < thistimelim; ++i)
1790                                 if (i >= 0)
1791                                         writetype[types[i]] = true;
1792                         /*
1793                         ** For America/Godthab and Antarctica/Palmer
1794                         */
1795                         if (thistimei == 0)
1796                                 writetype[0] = true;
1797                 }
1798 #ifndef LEAVE_SOME_PRE_2011_SYSTEMS_IN_THE_LURCH
1799                 /*
1800                 ** For some pre-2011 systems: if the last-to-be-written
1801                 ** standard (or daylight) type has an offset different from the
1802                 ** most recently used offset,
1803                 ** append an (unused) copy of the most recently used type
1804                 ** (to help get global "altzone" and "timezone" variables
1805                 ** set correctly).
1806                 */
1807                 {
1808                         register int    mrudst, mrustd, hidst, histd, type;
1809
1810                         hidst = histd = mrudst = mrustd = -1;
1811                         for (i = thistimei; i < thistimelim; ++i)
1812                                 if (isdsts[types[i]])
1813                                         mrudst = types[i];
1814                                 else    mrustd = types[i];
1815                         for (i = 0; i < typecnt; ++i)
1816                                 if (writetype[i]) {
1817                                         if (isdsts[i])
1818                                                 hidst = i;
1819                                         else    histd = i;
1820                                 }
1821                         if (hidst >= 0 && mrudst >= 0 && hidst != mrudst &&
1822                                 gmtoffs[hidst] != gmtoffs[mrudst]) {
1823                                         isdsts[mrudst] = -1;
1824                                         type = addtype(gmtoffs[mrudst],
1825                                                 &chars[abbrinds[mrudst]],
1826                                                 true,
1827                                                 ttisstds[mrudst],
1828                                                 ttisgmts[mrudst]);
1829                                         isdsts[mrudst] = 1;
1830                                         writetype[type] = true;
1831                         }
1832                         if (histd >= 0 && mrustd >= 0 && histd != mrustd &&
1833                                 gmtoffs[histd] != gmtoffs[mrustd]) {
1834                                         isdsts[mrustd] = -1;
1835                                         type = addtype(gmtoffs[mrustd],
1836                                                 &chars[abbrinds[mrustd]],
1837                                                 false,
1838                                                 ttisstds[mrustd],
1839                                                 ttisgmts[mrustd]);
1840                                         isdsts[mrustd] = 0;
1841                                         writetype[type] = true;
1842                         }
1843                 }
1844 #endif /* !defined LEAVE_SOME_PRE_2011_SYSTEMS_IN_THE_LURCH */
1845                 thistypecnt = 0;
1846                 for (i = 0; i < typecnt; ++i)
1847                         typemap[i] = writetype[i] ?  thistypecnt++ : -1;
1848                 for (i = 0; i < sizeof indmap / sizeof indmap[0]; ++i)
1849                         indmap[i] = -1;
1850                 thischarcnt = 0;
1851                 for (i = 0; i < typecnt; ++i) {
1852                         register char * thisabbr;
1853
1854                         if (!writetype[i])
1855                                 continue;
1856                         if (indmap[abbrinds[i]] >= 0)
1857                                 continue;
1858                         thisabbr = &chars[abbrinds[i]];
1859                         for (j = 0; j < thischarcnt; ++j)
1860                                 if (strcmp(&thischars[j], thisabbr) == 0)
1861                                         break;
1862                         if (j == thischarcnt) {
1863                                 strcpy(&thischars[(int) thischarcnt],
1864                                         thisabbr);
1865                                 thischarcnt += strlen(thisabbr) + 1;
1866                         }
1867                         indmap[abbrinds[i]] = j;
1868                 }
1869 #define DO(field)       fwrite(tzh.field, sizeof tzh.field, 1, fp)
1870                 tzh = tzh0;
1871                 strncpy(tzh.tzh_magic, TZ_MAGIC, sizeof tzh.tzh_magic);
1872                 tzh.tzh_version[0] = version;
1873                 convert(thistypecnt, tzh.tzh_ttisgmtcnt);
1874                 convert(thistypecnt, tzh.tzh_ttisstdcnt);
1875                 convert(thisleapcnt, tzh.tzh_leapcnt);
1876                 convert(thistimecnt, tzh.tzh_timecnt);
1877                 convert(thistypecnt, tzh.tzh_typecnt);
1878                 convert(thischarcnt, tzh.tzh_charcnt);
1879                 DO(tzh_magic);
1880                 DO(tzh_version);
1881                 DO(tzh_reserved);
1882                 DO(tzh_ttisgmtcnt);
1883                 DO(tzh_ttisstdcnt);
1884                 DO(tzh_leapcnt);
1885                 DO(tzh_timecnt);
1886                 DO(tzh_typecnt);
1887                 DO(tzh_charcnt);
1888 #undef DO
1889                 for (i = thistimei; i < thistimelim; ++i)
1890                         if (pass == 1)
1891                                 /*
1892                                 ** Output an INT32_MIN "transition"
1893                                 ** if appropriate; see above.
1894                                 */
1895                                 puttzcode(((ats[i] < INT32_MIN) ?
1896                                         INT32_MIN : ats[i]), fp);
1897                         else    puttzcode64(ats[i], fp);
1898                 for (i = thistimei; i < thistimelim; ++i) {
1899                         unsigned char   uc;
1900
1901                         uc = typemap[types[i]];
1902                         fwrite(&uc, sizeof uc, 1, fp);
1903                 }
1904                 for (i = 0; i < typecnt; ++i)
1905                         if (writetype[i]) {
1906                                 puttzcode(gmtoffs[i], fp);
1907                                 putc(isdsts[i], fp);
1908                                 putc((unsigned char) indmap[abbrinds[i]], fp);
1909                         }
1910                 if (thischarcnt != 0)
1911                         fwrite(thischars, sizeof thischars[0],
1912                                       thischarcnt, fp);
1913                 for (i = thisleapi; i < thisleaplim; ++i) {
1914                         register zic_t  todo;
1915
1916                         if (roll[i]) {
1917                                 if (timecnt == 0 || trans[i] < ats[0]) {
1918                                         j = 0;
1919                                         while (isdsts[j])
1920                                                 if (++j >= typecnt) {
1921                                                         j = 0;
1922                                                         break;
1923                                                 }
1924                                 } else {
1925                                         j = 1;
1926                                         while (j < timecnt &&
1927                                                 trans[i] >= ats[j])
1928                                                         ++j;
1929                                         j = types[j - 1];
1930                                 }
1931                                 todo = tadd(trans[i], -gmtoffs[j]);
1932                         } else  todo = trans[i];
1933                         if (pass == 1)
1934                                 puttzcode(todo, fp);
1935                         else    puttzcode64(todo, fp);
1936                         puttzcode(corr[i], fp);
1937                 }
1938                 for (i = 0; i < typecnt; ++i)
1939                         if (writetype[i])
1940                                 putc(ttisstds[i], fp);
1941                 for (i = 0; i < typecnt; ++i)
1942                         if (writetype[i])
1943                                 putc(ttisgmts[i], fp);
1944         }
1945         fprintf(fp, "\n%s\n", string);
1946         close_file(fp, fullname);
1947         free(ats);
1948         free(fullname);
1949 }
1950
1951 static char const *
1952 abbroffset(char *buf, zic_t offset)
1953 {
1954   char sign = '+';
1955   int seconds, minutes;
1956
1957   if (offset < 0) {
1958     offset = -offset;
1959     sign = '-';
1960   }
1961
1962   seconds = offset % SECSPERMIN;
1963   offset /= SECSPERMIN;
1964   minutes = offset % MINSPERHOUR;
1965   offset /= MINSPERHOUR;
1966   if (100 <= offset) {
1967     error(_("%%z UTC offset magnitude exceeds 99:59:59"));
1968     return "%z";
1969   } else {
1970     char *p = buf;
1971     *p++ = sign;
1972     *p++ = '0' + offset / 10;
1973     *p++ = '0' + offset % 10;
1974     if (minutes | seconds) {
1975       *p++ = '0' + minutes / 10;
1976       *p++ = '0' + minutes % 10;
1977       if (seconds) {
1978         *p++ = '0' + seconds / 10;
1979         *p++ = '0' + seconds % 10;
1980       }
1981     }
1982     *p = '\0';
1983     return buf;
1984   }
1985 }
1986
1987 static size_t
1988 doabbr(char *abbr, struct zone const *zp, char const *letters,
1989        zic_t stdoff, bool doquotes)
1990 {
1991         register char * cp;
1992         register char * slashp;
1993         register size_t len;
1994         char const *format = zp->z_format;
1995
1996         slashp = strchr(format, '/');
1997         if (slashp == NULL) {
1998           char letterbuf[PERCENT_Z_LEN_BOUND + 1];
1999           if (zp->z_format_specifier == 'z')
2000             letters = abbroffset(letterbuf, zp->z_gmtoff + stdoff);
2001           else if (!letters)
2002             letters = "%s";
2003           sprintf(abbr, format, letters);
2004         } else if (stdoff != 0) {
2005                 strcpy(abbr, slashp + 1);
2006         } else {
2007                 memcpy(abbr, format, slashp - format);
2008                 abbr[slashp - format] = '\0';
2009         }
2010         len = strlen(abbr);
2011         if (!doquotes)
2012                 return len;
2013         for (cp = abbr; is_alpha(*cp); cp++)
2014                 continue;
2015         if (len > 0 && *cp == '\0')
2016                 return len;
2017         abbr[len + 2] = '\0';
2018         abbr[len + 1] = '>';
2019         memmove(abbr + 1, abbr, len);
2020         abbr[0] = '<';
2021         return len + 2;
2022 }
2023
2024 static void
2025 updateminmax(const zic_t x)
2026 {
2027         if (min_year > x)
2028                 min_year = x;
2029         if (max_year < x)
2030                 max_year = x;
2031 }
2032
2033 static int
2034 stringoffset(char *result, zic_t offset)
2035 {
2036         register int    hours;
2037         register int    minutes;
2038         register int    seconds;
2039         bool negative = offset < 0;
2040         int len = negative;
2041
2042         if (negative) {
2043                 offset = -offset;
2044                 result[0] = '-';
2045         }
2046         seconds = offset % SECSPERMIN;
2047         offset /= SECSPERMIN;
2048         minutes = offset % MINSPERHOUR;
2049         offset /= MINSPERHOUR;
2050         hours = offset;
2051         if (hours >= HOURSPERDAY * DAYSPERWEEK) {
2052                 result[0] = '\0';
2053                 return 0;
2054         }
2055         len += sprintf(result + len, "%d", hours);
2056         if (minutes != 0 || seconds != 0) {
2057                 len += sprintf(result + len, ":%02d", minutes);
2058                 if (seconds != 0)
2059                         len += sprintf(result + len, ":%02d", seconds);
2060         }
2061         return len;
2062 }
2063
2064 static int
2065 stringrule(char *result, const struct rule *const rp, const zic_t dstoff,
2066            const zic_t gmtoff)
2067 {
2068         register zic_t  tod = rp->r_tod;
2069         register int    compat = 0;
2070
2071         if (rp->r_dycode == DC_DOM) {
2072                 register int    month, total;
2073
2074                 if (rp->r_dayofmonth == 29 && rp->r_month == TM_FEBRUARY)
2075                         return -1;
2076                 total = 0;
2077                 for (month = 0; month < rp->r_month; ++month)
2078                         total += len_months[0][month];
2079                 /* Omit the "J" in Jan and Feb, as that's shorter.  */
2080                 if (rp->r_month <= 1)
2081                   result += sprintf(result, "%d", total + rp->r_dayofmonth - 1);
2082                 else
2083                   result += sprintf(result, "J%d", total + rp->r_dayofmonth);
2084         } else {
2085                 register int    week;
2086                 register int    wday = rp->r_wday;
2087                 register int    wdayoff;
2088
2089                 if (rp->r_dycode == DC_DOWGEQ) {
2090                         wdayoff = (rp->r_dayofmonth - 1) % DAYSPERWEEK;
2091                         if (wdayoff)
2092                                 compat = 2013;
2093                         wday -= wdayoff;
2094                         tod += wdayoff * SECSPERDAY;
2095                         week = 1 + (rp->r_dayofmonth - 1) / DAYSPERWEEK;
2096                 } else if (rp->r_dycode == DC_DOWLEQ) {
2097                         if (rp->r_dayofmonth == len_months[1][rp->r_month])
2098                                 week = 5;
2099                         else {
2100                                 wdayoff = rp->r_dayofmonth % DAYSPERWEEK;
2101                                 if (wdayoff)
2102                                         compat = 2013;
2103                                 wday -= wdayoff;
2104                                 tod += wdayoff * SECSPERDAY;
2105                                 week = rp->r_dayofmonth / DAYSPERWEEK;
2106                         }
2107                 } else  return -1;      /* "cannot happen" */
2108                 if (wday < 0)
2109                         wday += DAYSPERWEEK;
2110                 result += sprintf(result, "M%d.%d.%d",
2111                                   rp->r_month + 1, week, wday);
2112         }
2113         if (rp->r_todisgmt)
2114                 tod += gmtoff;
2115         if (rp->r_todisstd && rp->r_stdoff == 0)
2116                 tod += dstoff;
2117         if (tod != 2 * SECSPERMIN * MINSPERHOUR) {
2118                 *result++ = '/';
2119                 if (! stringoffset(result, tod))
2120                         return -1;
2121                 if (tod < 0) {
2122                         if (compat < 2013)
2123                                 compat = 2013;
2124                 } else if (SECSPERDAY <= tod) {
2125                         if (compat < 1994)
2126                                 compat = 1994;
2127                 }
2128         }
2129         return compat;
2130 }
2131
2132 static int
2133 rule_cmp(struct rule const *a, struct rule const *b)
2134 {
2135         if (!a)
2136                 return -!!b;
2137         if (!b)
2138                 return 1;
2139         if (a->r_hiyear != b->r_hiyear)
2140                 return a->r_hiyear < b->r_hiyear ? -1 : 1;
2141         if (a->r_month - b->r_month != 0)
2142                 return a->r_month - b->r_month;
2143         return a->r_dayofmonth - b->r_dayofmonth;
2144 }
2145
2146 enum { YEAR_BY_YEAR_ZONE = 1 };
2147
2148 static int
2149 stringzone(char *result, const struct zone *const zpfirst, const int zonecount)
2150 {
2151         register const struct zone *    zp;
2152         register struct rule *          rp;
2153         register struct rule *          stdrp;
2154         register struct rule *          dstrp;
2155         register int                    i;
2156         register const char *           abbrvar;
2157         register int                    compat = 0;
2158         register int                    c;
2159         size_t                          len;
2160         int                             offsetlen;
2161         struct rule                     stdr, dstr;
2162
2163         result[0] = '\0';
2164         zp = zpfirst + zonecount - 1;
2165         stdrp = dstrp = NULL;
2166         for (i = 0; i < zp->z_nrules; ++i) {
2167                 rp = &zp->z_rules[i];
2168                 if (rp->r_hiwasnum || rp->r_hiyear != ZIC_MAX)
2169                         continue;
2170                 if (rp->r_yrtype != NULL)
2171                         continue;
2172                 if (rp->r_stdoff == 0) {
2173                         if (stdrp == NULL)
2174                                 stdrp = rp;
2175                         else    return -1;
2176                 } else {
2177                         if (dstrp == NULL)
2178                                 dstrp = rp;
2179                         else    return -1;
2180                 }
2181         }
2182         if (stdrp == NULL && dstrp == NULL) {
2183                 /*
2184                 ** There are no rules running through "max".
2185                 ** Find the latest std rule in stdabbrrp
2186                 ** and latest rule of any type in stdrp.
2187                 */
2188                 register struct rule *stdabbrrp = NULL;
2189                 for (i = 0; i < zp->z_nrules; ++i) {
2190                         rp = &zp->z_rules[i];
2191                         if (rp->r_stdoff == 0 && rule_cmp(stdabbrrp, rp) < 0)
2192                                 stdabbrrp = rp;
2193                         if (rule_cmp(stdrp, rp) < 0)
2194                                 stdrp = rp;
2195                 }
2196                 /*
2197                 ** Horrid special case: if year is 2037,
2198                 ** presume this is a zone handled on a year-by-year basis;
2199                 ** do not try to apply a rule to the zone.
2200                 */
2201                 if (stdrp != NULL && stdrp->r_hiyear == 2037)
2202                         return YEAR_BY_YEAR_ZONE;
2203
2204                 if (stdrp != NULL && stdrp->r_stdoff != 0) {
2205                         /* Perpetual DST.  */
2206                         dstr.r_month = TM_JANUARY;
2207                         dstr.r_dycode = DC_DOM;
2208                         dstr.r_dayofmonth = 1;
2209                         dstr.r_tod = 0;
2210                         dstr.r_todisstd = dstr.r_todisgmt = false;
2211                         dstr.r_stdoff = stdrp->r_stdoff;
2212                         dstr.r_abbrvar = stdrp->r_abbrvar;
2213                         stdr.r_month = TM_DECEMBER;
2214                         stdr.r_dycode = DC_DOM;
2215                         stdr.r_dayofmonth = 31;
2216                         stdr.r_tod = SECSPERDAY + stdrp->r_stdoff;
2217                         stdr.r_todisstd = stdr.r_todisgmt = false;
2218                         stdr.r_stdoff = 0;
2219                         stdr.r_abbrvar
2220                           = (stdabbrrp ? stdabbrrp->r_abbrvar : "");
2221                         dstrp = &dstr;
2222                         stdrp = &stdr;
2223                 }
2224         }
2225         if (stdrp == NULL && (zp->z_nrules != 0 || zp->z_stdoff != 0))
2226                 return -1;
2227         abbrvar = (stdrp == NULL) ? "" : stdrp->r_abbrvar;
2228         len = doabbr(result, zp, abbrvar, 0, true);
2229         offsetlen = stringoffset(result + len, -zp->z_gmtoff);
2230         if (! offsetlen) {
2231                 result[0] = '\0';
2232                 return -1;
2233         }
2234         len += offsetlen;
2235         if (dstrp == NULL)
2236                 return compat;
2237         len += doabbr(result + len, zp, dstrp->r_abbrvar, dstrp->r_stdoff, true);
2238         if (dstrp->r_stdoff != SECSPERMIN * MINSPERHOUR) {
2239           offsetlen = stringoffset(result + len,
2240                                    -(zp->z_gmtoff + dstrp->r_stdoff));
2241           if (! offsetlen) {
2242             result[0] = '\0';
2243             return -1;
2244           }
2245           len += offsetlen;
2246         }
2247         result[len++] = ',';
2248         c = stringrule(result + len, dstrp, dstrp->r_stdoff, zp->z_gmtoff);
2249         if (c < 0) {
2250                 result[0] = '\0';
2251                 return -1;
2252         }
2253         if (compat < c)
2254                 compat = c;
2255         len += strlen(result + len);
2256         result[len++] = ',';
2257         c = stringrule(result + len, stdrp, dstrp->r_stdoff, zp->z_gmtoff);
2258         if (c < 0) {
2259                 result[0] = '\0';
2260                 return -1;
2261         }
2262         if (compat < c)
2263                 compat = c;
2264         return compat;
2265 }
2266
2267 static void
2268 outzone(const struct zone *zpfirst, int zonecount)
2269 {
2270         register const struct zone *    zp;
2271         register struct rule *          rp;
2272         register int                    i, j;
2273         register bool                   usestart, useuntil;
2274         register zic_t                  starttime, untiltime;
2275         register zic_t                  gmtoff;
2276         register zic_t                  stdoff;
2277         register zic_t                  year;
2278         register zic_t                  startoff;
2279         register bool                   startttisstd;
2280         register bool                   startttisgmt;
2281         register int                    type;
2282         register char *                 startbuf;
2283         register char *                 ab;
2284         register char *                 envvar;
2285         register int                    max_abbr_len;
2286         register int                    max_envvar_len;
2287         register bool                   prodstic; /* all rules are min to max */
2288         register int                    compat;
2289         register bool                   do_extend;
2290         register char                   version;
2291
2292         max_abbr_len = 2 + max_format_len + max_abbrvar_len;
2293         max_envvar_len = 2 * max_abbr_len + 5 * 9;
2294         startbuf = emalloc(max_abbr_len + 1);
2295         ab = emalloc(max_abbr_len + 1);
2296         envvar = emalloc(max_envvar_len + 1);
2297         INITIALIZE(untiltime);
2298         INITIALIZE(starttime);
2299         /*
2300         ** Now. . .finally. . .generate some useful data!
2301         */
2302         timecnt = 0;
2303         typecnt = 0;
2304         charcnt = 0;
2305         prodstic = zonecount == 1;
2306         /*
2307         ** Thanks to Earl Chew
2308         ** for noting the need to unconditionally initialize startttisstd.
2309         */
2310         startttisstd = false;
2311         startttisgmt = false;
2312         min_year = max_year = EPOCH_YEAR;
2313         if (leapseen) {
2314                 updateminmax(leapminyear);
2315                 updateminmax(leapmaxyear + (leapmaxyear < ZIC_MAX));
2316         }
2317         for (i = 0; i < zonecount; ++i) {
2318                 zp = &zpfirst[i];
2319                 if (i < zonecount - 1)
2320                         updateminmax(zp->z_untilrule.r_loyear);
2321                 for (j = 0; j < zp->z_nrules; ++j) {
2322                         rp = &zp->z_rules[j];
2323                         if (rp->r_lowasnum)
2324                                 updateminmax(rp->r_loyear);
2325                         if (rp->r_hiwasnum)
2326                                 updateminmax(rp->r_hiyear);
2327                         if (rp->r_lowasnum || rp->r_hiwasnum)
2328                                 prodstic = false;
2329                 }
2330         }
2331         /*
2332         ** Generate lots of data if a rule can't cover all future times.
2333         */
2334         compat = stringzone(envvar, zpfirst, zonecount);
2335         version = compat < 2013 ? ZIC_VERSION_PRE_2013 : ZIC_VERSION;
2336         do_extend = compat < 0 || compat == YEAR_BY_YEAR_ZONE;
2337         if (noise) {
2338                 if (!*envvar)
2339                         warning("%s %s",
2340                                 _("no POSIX environment variable for zone"),
2341                                 zpfirst->z_name);
2342                 else if (compat != 0 && compat != YEAR_BY_YEAR_ZONE) {
2343                         /* Circa-COMPAT clients, and earlier clients, might
2344                            not work for this zone when given dates before
2345                            1970 or after 2038.  */
2346                         warning(_("%s: pre-%d clients may mishandle"
2347                                   " distant timestamps"),
2348                                 zpfirst->z_name, compat);
2349                 }
2350         }
2351         if (do_extend) {
2352                 /*
2353                 ** Search through a couple of extra years past the obvious
2354                 ** 400, to avoid edge cases.  For example, suppose a non-POSIX
2355                 ** rule applies from 2012 onwards and has transitions in March
2356                 ** and September, plus some one-off transitions in November
2357                 ** 2013.  If zic looked only at the last 400 years, it would
2358                 ** set max_year=2413, with the intent that the 400 years 2014
2359                 ** through 2413 will be repeated.  The last transition listed
2360                 ** in the tzfile would be in 2413-09, less than 400 years
2361                 ** after the last one-off transition in 2013-11.  Two years
2362                 ** might be overkill, but with the kind of edge cases
2363                 ** available we're not sure that one year would suffice.
2364                 */
2365                 enum { years_of_observations = YEARSPERREPEAT + 2 };
2366
2367                 if (min_year >= ZIC_MIN + years_of_observations)
2368                         min_year -= years_of_observations;
2369                 else    min_year = ZIC_MIN;
2370                 if (max_year <= ZIC_MAX - years_of_observations)
2371                         max_year += years_of_observations;
2372                 else    max_year = ZIC_MAX;
2373                 /*
2374                 ** Regardless of any of the above,
2375                 ** for a "proDSTic" zone which specifies that its rules
2376                 ** always have and always will be in effect,
2377                 ** we only need one cycle to define the zone.
2378                 */
2379                 if (prodstic) {
2380                         min_year = 1900;
2381                         max_year = min_year + years_of_observations;
2382                 }
2383         }
2384         /*
2385         ** For the benefit of older systems,
2386         ** generate data from 1900 through 2037.
2387         */
2388         if (min_year > 1900)
2389                 min_year = 1900;
2390         if (max_year < 2037)
2391                 max_year = 2037;
2392         for (i = 0; i < zonecount; ++i) {
2393                 /*
2394                 ** A guess that may well be corrected later.
2395                 */
2396                 stdoff = 0;
2397                 zp = &zpfirst[i];
2398                 usestart = i > 0 && (zp - 1)->z_untiltime > early_time;
2399                 useuntil = i < (zonecount - 1);
2400                 if (useuntil && zp->z_untiltime <= early_time)
2401                         continue;
2402                 gmtoff = zp->z_gmtoff;
2403                 eat(zp->z_filename, zp->z_linenum);
2404                 *startbuf = '\0';
2405                 startoff = zp->z_gmtoff;
2406                 if (zp->z_nrules == 0) {
2407                         stdoff = zp->z_stdoff;
2408                         doabbr(startbuf, zp, NULL, stdoff, false);
2409                         type = addtype(oadd(zp->z_gmtoff, stdoff),
2410                                 startbuf, stdoff != 0, startttisstd,
2411                                 startttisgmt);
2412                         if (usestart) {
2413                                 addtt(starttime, type);
2414                                 usestart = false;
2415                         } else  addtt(early_time, type);
2416                 } else for (year = min_year; year <= max_year; ++year) {
2417                         if (useuntil && year > zp->z_untilrule.r_hiyear)
2418                                 break;
2419                         /*
2420                         ** Mark which rules to do in the current year.
2421                         ** For those to do, calculate rpytime(rp, year);
2422                         */
2423                         for (j = 0; j < zp->z_nrules; ++j) {
2424                                 rp = &zp->z_rules[j];
2425                                 eats(zp->z_filename, zp->z_linenum,
2426                                         rp->r_filename, rp->r_linenum);
2427                                 rp->r_todo = year >= rp->r_loyear &&
2428                                                 year <= rp->r_hiyear &&
2429                                                 yearistype(year, rp->r_yrtype);
2430                                 if (rp->r_todo)
2431                                         rp->r_temp = rpytime(rp, year);
2432                         }
2433                         for ( ; ; ) {
2434                                 register int    k;
2435                                 register zic_t  jtime, ktime;
2436                                 register zic_t  offset;
2437
2438                                 INITIALIZE(ktime);
2439                                 if (useuntil) {
2440                                         /*
2441                                         ** Turn untiltime into UT
2442                                         ** assuming the current gmtoff and
2443                                         ** stdoff values.
2444                                         */
2445                                         untiltime = zp->z_untiltime;
2446                                         if (!zp->z_untilrule.r_todisgmt)
2447                                                 untiltime = tadd(untiltime,
2448                                                         -gmtoff);
2449                                         if (!zp->z_untilrule.r_todisstd)
2450                                                 untiltime = tadd(untiltime,
2451                                                         -stdoff);
2452                                 }
2453                                 /*
2454                                 ** Find the rule (of those to do, if any)
2455                                 ** that takes effect earliest in the year.
2456                                 */
2457                                 k = -1;
2458                                 for (j = 0; j < zp->z_nrules; ++j) {
2459                                         rp = &zp->z_rules[j];
2460                                         if (!rp->r_todo)
2461                                                 continue;
2462                                         eats(zp->z_filename, zp->z_linenum,
2463                                                 rp->r_filename, rp->r_linenum);
2464                                         offset = rp->r_todisgmt ? 0 : gmtoff;
2465                                         if (!rp->r_todisstd)
2466                                                 offset = oadd(offset, stdoff);
2467                                         jtime = rp->r_temp;
2468                                         if (jtime == min_time ||
2469                                                 jtime == max_time)
2470                                                         continue;
2471                                         jtime = tadd(jtime, -offset);
2472                                         if (k < 0 || jtime < ktime) {
2473                                                 k = j;
2474                                                 ktime = jtime;
2475                                         } else if (jtime == ktime) {
2476                                           char const *dup_rules_msg =
2477                                             _("two rules for same instant");
2478                                           eats(zp->z_filename, zp->z_linenum,
2479                                                rp->r_filename, rp->r_linenum);
2480                                           warning("%s", dup_rules_msg);
2481                                           rp = &zp->z_rules[k];
2482                                           eats(zp->z_filename, zp->z_linenum,
2483                                                rp->r_filename, rp->r_linenum);
2484                                           error("%s", dup_rules_msg);
2485                                         }
2486                                 }
2487                                 if (k < 0)
2488                                         break;  /* go on to next year */
2489                                 rp = &zp->z_rules[k];
2490                                 rp->r_todo = false;
2491                                 if (useuntil && ktime >= untiltime)
2492                                         break;
2493                                 stdoff = rp->r_stdoff;
2494                                 if (usestart && ktime == starttime)
2495                                         usestart = false;
2496                                 if (usestart) {
2497                                         if (ktime < starttime) {
2498                                                 startoff = oadd(zp->z_gmtoff,
2499                                                         stdoff);
2500                                                 doabbr(startbuf, zp,
2501                                                         rp->r_abbrvar,
2502                                                         rp->r_stdoff,
2503                                                         false);
2504                                                 continue;
2505                                         }
2506                                         if (*startbuf == '\0' &&
2507                                                 startoff == oadd(zp->z_gmtoff,
2508                                                 stdoff)) {
2509                                                         doabbr(startbuf,
2510                                                                 zp,
2511                                                                 rp->r_abbrvar,
2512                                                                 rp->r_stdoff,
2513                                                                 false);
2514                                         }
2515                                 }
2516                                 eats(zp->z_filename, zp->z_linenum,
2517                                         rp->r_filename, rp->r_linenum);
2518                                 doabbr(ab, zp, rp->r_abbrvar,
2519                                        rp->r_stdoff, false);
2520                                 offset = oadd(zp->z_gmtoff, rp->r_stdoff);
2521                                 type = addtype(offset, ab, rp->r_stdoff != 0,
2522                                         rp->r_todisstd, rp->r_todisgmt);
2523                                 addtt(ktime, type);
2524                         }
2525                 }
2526                 if (usestart) {
2527                         if (*startbuf == '\0' &&
2528                                 zp->z_format != NULL &&
2529                                 strchr(zp->z_format, '%') == NULL &&
2530                                 strchr(zp->z_format, '/') == NULL)
2531                                         strcpy(startbuf, zp->z_format);
2532                         eat(zp->z_filename, zp->z_linenum);
2533                         if (*startbuf == '\0')
2534 error(_("can't determine time zone abbreviation to use just after until time"));
2535                         else    addtt(starttime,
2536                                         addtype(startoff, startbuf,
2537                                                 startoff != zp->z_gmtoff,
2538                                                 startttisstd,
2539                                                 startttisgmt));
2540                 }
2541                 /*
2542                 ** Now we may get to set starttime for the next zone line.
2543                 */
2544                 if (useuntil) {
2545                         startttisstd = zp->z_untilrule.r_todisstd;
2546                         startttisgmt = zp->z_untilrule.r_todisgmt;
2547                         starttime = zp->z_untiltime;
2548                         if (!startttisstd)
2549                                 starttime = tadd(starttime, -stdoff);
2550                         if (!startttisgmt)
2551                                 starttime = tadd(starttime, -gmtoff);
2552                 }
2553         }
2554         if (do_extend) {
2555                 /*
2556                 ** If we're extending the explicitly listed observations
2557                 ** for 400 years because we can't fill the POSIX-TZ field,
2558                 ** check whether we actually ended up explicitly listing
2559                 ** observations through that period.  If there aren't any
2560                 ** near the end of the 400-year period, add a redundant
2561                 ** one at the end of the final year, to make it clear
2562                 ** that we are claiming to have definite knowledge of
2563                 ** the lack of transitions up to that point.
2564                 */
2565                 struct rule xr;
2566                 struct attype *lastat;
2567                 xr.r_month = TM_JANUARY;
2568                 xr.r_dycode = DC_DOM;
2569                 xr.r_dayofmonth = 1;
2570                 xr.r_tod = 0;
2571                 for (lastat = &attypes[0], i = 1; i < timecnt; i++)
2572                         if (attypes[i].at > lastat->at)
2573                                 lastat = &attypes[i];
2574                 if (lastat->at < rpytime(&xr, max_year - 1)) {
2575                         /*
2576                         ** Create new type code for the redundant entry,
2577                         ** to prevent it being optimized away.
2578                         */
2579                         if (typecnt >= TZ_MAX_TYPES) {
2580                                 error(_("too many local time types"));
2581                                 exit(EXIT_FAILURE);
2582                         }
2583                         gmtoffs[typecnt] = gmtoffs[lastat->type];
2584                         isdsts[typecnt] = isdsts[lastat->type];
2585                         ttisstds[typecnt] = ttisstds[lastat->type];
2586                         ttisgmts[typecnt] = ttisgmts[lastat->type];
2587                         abbrinds[typecnt] = abbrinds[lastat->type];
2588                         ++typecnt;
2589                         addtt(rpytime(&xr, max_year + 1), typecnt-1);
2590                 }
2591         }
2592         writezone(zpfirst->z_name, envvar, version);
2593         free(startbuf);
2594         free(ab);
2595         free(envvar);
2596 }
2597
2598 static void
2599 addtt(zic_t starttime, int type)
2600 {
2601         if (starttime <= early_time
2602             || (timecnt == 1 && attypes[0].at < early_time)) {
2603                 gmtoffs[0] = gmtoffs[type];
2604                 isdsts[0] = isdsts[type];
2605                 ttisstds[0] = ttisstds[type];
2606                 ttisgmts[0] = ttisgmts[type];
2607                 if (abbrinds[type] != 0)
2608                         strcpy(chars, &chars[abbrinds[type]]);
2609                 abbrinds[0] = 0;
2610                 charcnt = strlen(chars) + 1;
2611                 typecnt = 1;
2612                 timecnt = 0;
2613                 type = 0;
2614         }
2615         attypes = growalloc(attypes, sizeof *attypes, timecnt, &timecnt_alloc);
2616         attypes[timecnt].at = starttime;
2617         attypes[timecnt].type = type;
2618         ++timecnt;
2619 }
2620
2621 static int
2622 addtype(zic_t gmtoff, char const *abbr, bool isdst, bool ttisstd, bool ttisgmt)
2623 {
2624         register int    i, j;
2625
2626         /*
2627         ** See if there's already an entry for this zone type.
2628         ** If so, just return its index.
2629         */
2630         for (i = 0; i < typecnt; ++i) {
2631                 if (gmtoff == gmtoffs[i] && isdst == isdsts[i] &&
2632                         strcmp(abbr, &chars[abbrinds[i]]) == 0 &&
2633                         ttisstd == ttisstds[i] &&
2634                         ttisgmt == ttisgmts[i])
2635                                 return i;
2636         }
2637         /*
2638         ** There isn't one; add a new one, unless there are already too
2639         ** many.
2640         */
2641         if (typecnt >= TZ_MAX_TYPES) {
2642                 error(_("too many local time types"));
2643                 exit(EXIT_FAILURE);
2644         }
2645         if (! (-1L - 2147483647L <= gmtoff && gmtoff <= 2147483647L)) {
2646                 error(_("UT offset out of range"));
2647                 exit(EXIT_FAILURE);
2648         }
2649         gmtoffs[i] = gmtoff;
2650         isdsts[i] = isdst;
2651         ttisstds[i] = ttisstd;
2652         ttisgmts[i] = ttisgmt;
2653
2654         for (j = 0; j < charcnt; ++j)
2655                 if (strcmp(&chars[j], abbr) == 0)
2656                         break;
2657         if (j == charcnt)
2658                 newabbr(abbr);
2659         abbrinds[i] = j;
2660         ++typecnt;
2661         return i;
2662 }
2663
2664 static void
2665 leapadd(zic_t t, bool positive, int rolling, int count)
2666 {
2667         register int    i, j;
2668
2669         if (leapcnt + (positive ? count : 1) > TZ_MAX_LEAPS) {
2670                 error(_("too many leap seconds"));
2671                 exit(EXIT_FAILURE);
2672         }
2673         for (i = 0; i < leapcnt; ++i)
2674                 if (t <= trans[i]) {
2675                         if (t == trans[i]) {
2676                                 error(_("repeated leap second moment"));
2677                                 exit(EXIT_FAILURE);
2678                         }
2679                         break;
2680                 }
2681         do {
2682                 for (j = leapcnt; j > i; --j) {
2683                         trans[j] = trans[j - 1];
2684                         corr[j] = corr[j - 1];
2685                         roll[j] = roll[j - 1];
2686                 }
2687                 trans[i] = t;
2688                 corr[i] = positive ? 1 : -count;
2689                 roll[i] = rolling;
2690                 ++leapcnt;
2691         } while (positive && --count != 0);
2692 }
2693
2694 static void
2695 adjleap(void)
2696 {
2697         register int    i;
2698         register zic_t  last = 0;
2699
2700         /*
2701         ** propagate leap seconds forward
2702         */
2703         for (i = 0; i < leapcnt; ++i) {
2704                 trans[i] = tadd(trans[i], last);
2705                 last = corr[i] += last;
2706         }
2707 }
2708
2709 static bool
2710 yearistype(int year, const char *type)
2711 {
2712         static char *   buf;
2713         int             result;
2714
2715         if (type == NULL || *type == '\0')
2716                 return true;
2717         buf = erealloc(buf, 132 + strlen(yitcommand) + strlen(type));
2718         sprintf(buf, "%s %d %s", yitcommand, year, type);
2719         result = system(buf);
2720         if (WIFEXITED(result)) switch (WEXITSTATUS(result)) {
2721                 case 0:
2722                         return true;
2723                 case 1:
2724                         return false;
2725         }
2726         error(_("Wild result from command execution"));
2727         fprintf(stderr, _("%s: command was '%s', result was %d\n"),
2728                 progname, buf, result);
2729         for ( ; ; )
2730                 exit(EXIT_FAILURE);
2731 }
2732
2733 /* Is A a space character in the C locale?  */
2734 static bool
2735 is_space(char a)
2736 {
2737         switch (a) {
2738           default:
2739                 return false;
2740           case ' ': case '\f': case '\n': case '\r': case '\t': case '\v':
2741                 return true;
2742         }
2743 }
2744
2745 /* Is A an alphabetic character in the C locale?  */
2746 static bool
2747 is_alpha(char a)
2748 {
2749         switch (a) {
2750           default:
2751                 return false;
2752           case 'A': case 'B': case 'C': case 'D': case 'E': case 'F': case 'G':
2753           case 'H': case 'I': case 'J': case 'K': case 'L': case 'M': case 'N':
2754           case 'O': case 'P': case 'Q': case 'R': case 'S': case 'T': case 'U':
2755           case 'V': case 'W': case 'X': case 'Y': case 'Z':
2756           case 'a': case 'b': case 'c': case 'd': case 'e': case 'f': case 'g':
2757           case 'h': case 'i': case 'j': case 'k': case 'l': case 'm': case 'n':
2758           case 'o': case 'p': case 'q': case 'r': case 's': case 't': case 'u':
2759           case 'v': case 'w': case 'x': case 'y': case 'z':
2760                 return true;
2761         }
2762 }
2763
2764 /* If A is an uppercase character in the C locale, return its lowercase
2765    counterpart.  Otherwise, return A.  */
2766 static char
2767 lowerit(char a)
2768 {
2769         switch (a) {
2770           default: return a;
2771           case 'A': return 'a'; case 'B': return 'b'; case 'C': return 'c';
2772           case 'D': return 'd'; case 'E': return 'e'; case 'F': return 'f';
2773           case 'G': return 'g'; case 'H': return 'h'; case 'I': return 'i';
2774           case 'J': return 'j'; case 'K': return 'k'; case 'L': return 'l';
2775           case 'M': return 'm'; case 'N': return 'n'; case 'O': return 'o';
2776           case 'P': return 'p'; case 'Q': return 'q'; case 'R': return 'r';
2777           case 'S': return 's'; case 'T': return 't'; case 'U': return 'u';
2778           case 'V': return 'v'; case 'W': return 'w'; case 'X': return 'x';
2779           case 'Y': return 'y'; case 'Z': return 'z';
2780         }
2781 }
2782
2783 /* case-insensitive equality */
2784 static ATTRIBUTE_PURE bool
2785 ciequal(register const char *ap, register const char *bp)
2786 {
2787         while (lowerit(*ap) == lowerit(*bp++))
2788                 if (*ap++ == '\0')
2789                         return true;
2790         return false;
2791 }
2792
2793 static ATTRIBUTE_PURE bool
2794 itsabbr(register const char *abbr, register const char *word)
2795 {
2796         if (lowerit(*abbr) != lowerit(*word))
2797                 return false;
2798         ++word;
2799         while (*++abbr != '\0')
2800                 do {
2801                         if (*word == '\0')
2802                                 return false;
2803                 } while (lowerit(*word++) != lowerit(*abbr));
2804         return true;
2805 }
2806
2807 static ATTRIBUTE_PURE const struct lookup *
2808 byword(const char *word, const struct lookup *table)
2809 {
2810         register const struct lookup *  foundlp;
2811         register const struct lookup *  lp;
2812
2813         if (word == NULL || table == NULL)
2814                 return NULL;
2815         /*
2816         ** Look for exact match.
2817         */
2818         for (lp = table; lp->l_word != NULL; ++lp)
2819                 if (ciequal(word, lp->l_word))
2820                         return lp;
2821         /*
2822         ** Look for inexact match.
2823         */
2824         foundlp = NULL;
2825         for (lp = table; lp->l_word != NULL; ++lp)
2826                 if (itsabbr(word, lp->l_word)) {
2827                         if (foundlp == NULL)
2828                                 foundlp = lp;
2829                         else    return NULL;    /* multiple inexact matches */
2830                 }
2831         return foundlp;
2832 }
2833
2834 static char **
2835 getfields(register char *cp)
2836 {
2837         register char *         dp;
2838         register char **        array;
2839         register int            nsubs;
2840
2841         if (cp == NULL)
2842                 return NULL;
2843         array = emalloc(size_product(strlen(cp) + 1, sizeof *array));
2844         nsubs = 0;
2845         for ( ; ; ) {
2846                 while (is_space(*cp))
2847                                 ++cp;
2848                 if (*cp == '\0' || *cp == '#')
2849                         break;
2850                 array[nsubs++] = dp = cp;
2851                 do {
2852                         if ((*dp = *cp++) != '"')
2853                                 ++dp;
2854                         else while ((*dp = *cp++) != '"')
2855                                 if (*dp != '\0')
2856                                         ++dp;
2857                                 else {
2858                                         error(_(
2859                                                 "Odd number of quotation marks"
2860                                                 ));
2861                                         exit(1);
2862                                 }
2863                 } while (*cp && *cp != '#' && !is_space(*cp));
2864                 if (is_space(*cp))
2865                         ++cp;
2866                 *dp = '\0';
2867         }
2868         array[nsubs] = NULL;
2869         return array;
2870 }
2871
2872 static _Noreturn void
2873 time_overflow(void)
2874 {
2875   error(_("time overflow"));
2876   exit(EXIT_FAILURE);
2877 }
2878
2879 static ATTRIBUTE_PURE zic_t
2880 oadd(zic_t t1, zic_t t2)
2881 {
2882         if (t1 < 0 ? t2 < ZIC_MIN - t1 : ZIC_MAX - t1 < t2)
2883           time_overflow();
2884         return t1 + t2;
2885 }
2886
2887 static ATTRIBUTE_PURE zic_t
2888 tadd(zic_t t1, zic_t t2)
2889 {
2890   if (t1 < 0) {
2891     if (t2 < min_time - t1) {
2892       if (t1 != min_time)
2893         time_overflow();
2894       return min_time;
2895     }
2896   } else {
2897     if (max_time - t1 < t2) {
2898       if (t1 != max_time)
2899         time_overflow();
2900       return max_time;
2901     }
2902   }
2903   return t1 + t2;
2904 }
2905
2906 /*
2907 ** Given a rule, and a year, compute the date (in seconds since January 1,
2908 ** 1970, 00:00 LOCAL time) in that year that the rule refers to.
2909 */
2910
2911 static zic_t
2912 rpytime(const struct rule *rp, zic_t wantedy)
2913 {
2914         register int    m, i;
2915         register zic_t  dayoff;                 /* with a nod to Margaret O. */
2916         register zic_t  t, y;
2917
2918         if (wantedy == ZIC_MIN)
2919                 return min_time;
2920         if (wantedy == ZIC_MAX)
2921                 return max_time;
2922         dayoff = 0;
2923         m = TM_JANUARY;
2924         y = EPOCH_YEAR;
2925         while (wantedy != y) {
2926                 if (wantedy > y) {
2927                         i = len_years[isleap(y)];
2928                         ++y;
2929                 } else {
2930                         --y;
2931                         i = -len_years[isleap(y)];
2932                 }
2933                 dayoff = oadd(dayoff, i);
2934         }
2935         while (m != rp->r_month) {
2936                 i = len_months[isleap(y)][m];
2937                 dayoff = oadd(dayoff, i);
2938                 ++m;
2939         }
2940         i = rp->r_dayofmonth;
2941         if (m == TM_FEBRUARY && i == 29 && !isleap(y)) {
2942                 if (rp->r_dycode == DC_DOWLEQ)
2943                         --i;
2944                 else {
2945                         error(_("use of 2/29 in non leap-year"));
2946                         exit(EXIT_FAILURE);
2947                 }
2948         }
2949         --i;
2950         dayoff = oadd(dayoff, i);
2951         if (rp->r_dycode == DC_DOWGEQ || rp->r_dycode == DC_DOWLEQ) {
2952                 register zic_t  wday;
2953
2954 #define LDAYSPERWEEK    ((zic_t) DAYSPERWEEK)
2955                 wday = EPOCH_WDAY;
2956                 /*
2957                 ** Don't trust mod of negative numbers.
2958                 */
2959                 if (dayoff >= 0)
2960                         wday = (wday + dayoff) % LDAYSPERWEEK;
2961                 else {
2962                         wday -= ((-dayoff) % LDAYSPERWEEK);
2963                         if (wday < 0)
2964                                 wday += LDAYSPERWEEK;
2965                 }
2966                 while (wday != rp->r_wday)
2967                         if (rp->r_dycode == DC_DOWGEQ) {
2968                                 dayoff = oadd(dayoff, 1);
2969                                 if (++wday >= LDAYSPERWEEK)
2970                                         wday = 0;
2971                                 ++i;
2972                         } else {
2973                                 dayoff = oadd(dayoff, -1);
2974                                 if (--wday < 0)
2975                                         wday = LDAYSPERWEEK - 1;
2976                                 --i;
2977                         }
2978                 if (i < 0 || i >= len_months[isleap(y)][m]) {
2979                         if (noise)
2980                                 warning(_("rule goes past start/end of month; \
2981 will not work with pre-2004 versions of zic"));
2982                 }
2983         }
2984         if (dayoff < min_time / SECSPERDAY)
2985                 return min_time;
2986         if (dayoff > max_time / SECSPERDAY)
2987                 return max_time;
2988         t = (zic_t) dayoff * SECSPERDAY;
2989         return tadd(t, rp->r_tod);
2990 }
2991
2992 static void
2993 newabbr(const char *string)
2994 {
2995         register int    i;
2996
2997         if (strcmp(string, GRANDPARENTED) != 0) {
2998                 register const char *   cp;
2999                 const char *            mp;
3000
3001                 cp = string;
3002                 mp = NULL;
3003                 while (is_alpha(*cp) || ('0' <= *cp && *cp <= '9')
3004                        || *cp == '-' || *cp == '+')
3005                                 ++cp;
3006                 if (noise && cp - string < 3)
3007                   mp = _("time zone abbreviation has fewer than 3 characters");
3008                 if (cp - string > ZIC_MAX_ABBR_LEN_WO_WARN)
3009                   mp = _("time zone abbreviation has too many characters");
3010                 if (*cp != '\0')
3011 mp = _("time zone abbreviation differs from POSIX standard");
3012                 if (mp != NULL)
3013                         warning("%s (%s)", mp, string);
3014         }
3015         i = strlen(string) + 1;
3016         if (charcnt + i > TZ_MAX_CHARS) {
3017                 error(_("too many, or too long, time zone abbreviations"));
3018                 exit(EXIT_FAILURE);
3019         }
3020         strcpy(&chars[charcnt], string);
3021         charcnt += i;
3022 }
3023
3024 static bool
3025 mkdirs(char *argname)
3026 {
3027         register char * name;
3028         register char * cp;
3029
3030         if (argname == NULL || *argname == '\0')
3031                 return true;
3032         cp = name = ecpyalloc(argname);
3033         while ((cp = strchr(cp + 1, '/')) != 0) {
3034                 *cp = '\0';
3035 #ifdef HAVE_DOS_FILE_NAMES
3036                 /*
3037                 ** DOS drive specifier?
3038                 */
3039                 if (is_alpha(name[0]) && name[1] == ':' && name[2] == '\0') {
3040                                 *cp = '/';
3041                                 continue;
3042                 }
3043 #endif
3044                 /*
3045                 ** Try to create it.  It's OK if creation fails because
3046                 ** the directory already exists, perhaps because some
3047                 ** other process just created it.
3048                 */
3049                 if (mkdir(name, MKDIR_UMASK) != 0) {
3050                         int err = errno;
3051                         if (itsdir(name) <= 0) {
3052                                 char const *e = strerror(err);
3053                                 warning(_("%s: Can't create directory"
3054                                           " %s: %s"),
3055                                         progname, name, e);
3056                                 free(name);
3057                                 return false;
3058                         }
3059                 }
3060                 *cp = '/';
3061         }
3062         free(name);
3063         return true;
3064 }