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