Deleted Added
full compact
zic.c (174210) zic.c (192625)
1static const char elsieid[] = "@(#)zic.c 7.116";
1/*
2** This file is in the public domain, so clarified as of
3** 2006-07-17 by Arthur David Olson.
4*/
2
5
6static const char elsieid[] = "@(#)zic.c 8.19";
7
3#ifndef lint
4static const char rcsid[] =
8#ifndef lint
9static const char rcsid[] =
5 "$FreeBSD: head/usr.sbin/zic/zic.c 174210 2007-12-03 10:45:44Z kevlo $";
10 "$FreeBSD: head/usr.sbin/zic/zic.c 192625 2009-05-23 06:31:50Z edwin $";
6#endif /* not lint */
7
8#include "private.h"
9#include "tzfile.h"
10#include <err.h>
11#include <locale.h>
12#include <sys/stat.h> /* for umask manifest constants */
13#include <sys/types.h>
14#include <unistd.h>
15
11#endif /* not lint */
12
13#include "private.h"
14#include "tzfile.h"
15#include <err.h>
16#include <locale.h>
17#include <sys/stat.h> /* for umask manifest constants */
18#include <sys/types.h>
19#include <unistd.h>
20
21#define ZIC_VERSION '2'
22
23typedef int_fast64_t zic_t;
24
25#ifndef ZIC_MAX_ABBR_LEN_WO_WARN
26#define ZIC_MAX_ABBR_LEN_WO_WARN 6
27#endif /* !defined ZIC_MAX_ABBR_LEN_WO_WARN */
28
16#define MKDIR_UMASK (S_IRUSR|S_IWUSR|S_IXUSR|S_IRGRP|S_IXGRP|S_IROTH|S_IXOTH)
17
18/*
19** On some ancient hosts, predicates like `isspace(C)' are defined
29#define MKDIR_UMASK (S_IRUSR|S_IWUSR|S_IXUSR|S_IRGRP|S_IXGRP|S_IROTH|S_IXOTH)
30
31/*
32** On some ancient hosts, predicates like `isspace(C)' are defined
20** only if isascii(C) || C == EOF. Modern hosts obey the C Standard,
33** only if isascii(C) || C == EOF. Modern hosts obey the C Standard,
21** which says they are defined only if C == ((unsigned char) C) || C == EOF.
22** Neither the C Standard nor POSIX require that `isascii' exist.
23** For portability, we check both ancient and modern requirements.
24** If isascii is not defined, the isascii check succeeds trivially.
25*/
26#include "ctype.h"
27#ifndef isascii
28#define isascii(x) 1
29#endif
30
34** which says they are defined only if C == ((unsigned char) C) || C == EOF.
35** Neither the C Standard nor POSIX require that `isascii' exist.
36** For portability, we check both ancient and modern requirements.
37** If isascii is not defined, the isascii check succeeds trivially.
38*/
39#include "ctype.h"
40#ifndef isascii
41#define isascii(x) 1
42#endif
43
44#define OFFSET_STRLEN_MAXIMUM (7 + INT_STRLEN_MAXIMUM(long))
45#define RULE_STRLEN_MAXIMUM 8 /* "Mdd.dd.d" */
46
47#define end(cp) (strchr((cp), '\0'))
48
31struct rule {
32 const char * r_filename;
33 int r_linenum;
34 const char * r_name;
35
36 int r_loyear; /* for example, 1986 */
37 int r_hiyear; /* for example, 1986 */
38 const char * r_yrtype;
49struct rule {
50 const char * r_filename;
51 int r_linenum;
52 const char * r_name;
53
54 int r_loyear; /* for example, 1986 */
55 int r_hiyear; /* for example, 1986 */
56 const char * r_yrtype;
57 int r_lowasnum;
58 int r_hiwasnum;
39
40 int r_month; /* 0..11 */
41
42 int r_dycode; /* see below */
43 int r_dayofmonth;
44 int r_wday;
45
46 long r_tod; /* time from midnight */
47 int r_todisstd; /* above is standard time if TRUE */
48 /* or wall clock time if FALSE */
49 int r_todisgmt; /* above is GMT if TRUE */
50 /* or local time if FALSE */
51 long r_stdoff; /* offset from standard time */
52 const char * r_abbrvar; /* variable part of abbreviation */
53
54 int r_todo; /* a rule to do (used in outzone) */
59
60 int r_month; /* 0..11 */
61
62 int r_dycode; /* see below */
63 int r_dayofmonth;
64 int r_wday;
65
66 long r_tod; /* time from midnight */
67 int r_todisstd; /* above is standard time if TRUE */
68 /* or wall clock time if FALSE */
69 int r_todisgmt; /* above is GMT if TRUE */
70 /* or local time if FALSE */
71 long r_stdoff; /* offset from standard time */
72 const char * r_abbrvar; /* variable part of abbreviation */
73
74 int r_todo; /* a rule to do (used in outzone) */
55 time_t r_temp; /* used in outzone */
75 zic_t r_temp; /* used in outzone */
56};
57
58/*
59** r_dycode r_dayofmonth r_wday
60*/
61
62#define DC_DOM 0 /* 1..31 */ /* unused */
63#define DC_DOWGEQ 1 /* 1..31 */ /* 0..6 (Sun..Sat) */

--- 9 unchanged lines hidden (view full) ---

73 const char * z_format;
74
75 long z_stdoff;
76
77 struct rule * z_rules;
78 int z_nrules;
79
80 struct rule z_untilrule;
76};
77
78/*
79** r_dycode r_dayofmonth r_wday
80*/
81
82#define DC_DOM 0 /* 1..31 */ /* unused */
83#define DC_DOWGEQ 1 /* 1..31 */ /* 0..6 (Sun..Sat) */

--- 9 unchanged lines hidden (view full) ---

93 const char * z_format;
94
95 long z_stdoff;
96
97 struct rule * z_rules;
98 int z_nrules;
99
100 struct rule z_untilrule;
81 time_t z_untiltime;
101 zic_t z_untiltime;
82};
83
102};
103
84static void addtt P((time_t starttime, int type));
85static int addtype P((long gmtoff, const char * abbr, int isdst,
86 int ttisstd, int ttisgmt));
87static void leapadd P((time_t t, int positive, int rolling, int count));
88static void adjleap P((void));
89static void associate P((void));
90static int ciequal P((const char * ap, const char * bp));
91static void convert P((long val, char * buf));
92static void dolink P((const char * fromfile, const char * tofile));
93static void doabbr P((char * abbr, const char * format,
94 const char * letters, int isdst));
95static void eat P((const char * name, int num));
96static void eats P((const char * name, int num,
97 const char * rname, int rnum));
98static long eitol P((int i));
99static void error P((const char * message));
100static char ** getfields P((char * buf));
101static long gethms P((const char * string, const char * errstrng,
102 int signable));
103static void infile P((const char * filename));
104static void inleap P((char ** fields, int nfields));
105static void inlink P((char ** fields, int nfields));
106static void inrule P((char ** fields, int nfields));
107static int inzcont P((char ** fields, int nfields));
108static int inzone P((char ** fields, int nfields));
109static int inzsub P((char ** fields, int nfields, int iscont));
110static int itsabbr P((const char * abbr, const char * word));
111static int itsdir P((const char * name));
112static int lowerit P((int c));
113static char * memcheck P((char * tocheck));
114static int mkdirs P((char * filename));
115static void newabbr P((const char * abbr));
116static long oadd P((long t1, long t2));
117static void outzone P((const struct zone * zp, int ntzones));
118static void puttzcode P((long code, FILE * fp));
119static int rcomp P((const void * leftp, const void * rightp));
120static time_t rpytime P((const struct rule * rp, int wantedy));
121static void rulesub P((struct rule * rp,
104static void addtt(zic_t starttime, int type);
105static int addtype(long gmtoff, const char * abbr, int isdst,
106 int ttisstd, int ttisgmt);
107static void leapadd(zic_t t, int positive, int rolling, int count);
108static void adjleap(void);
109static void associate(void);
110static int ciequal(const char * ap, const char * bp);
111static void convert(long val, char * buf);
112static void convert64(zic_t val, char * buf);
113static void dolink(const char * fromfield, const char * tofield);
114static void doabbr(char * abbr, const char * format,
115 const char * letters, int isdst, int doquotes);
116static void eat(const char * name, int num);
117static void eats(const char * name, int num,
118 const char * rname, int rnum);
119static long eitol(int i);
120static void error(const char * message);
121static char ** getfields(char * buf);
122static long gethms(const char * string, const char * errstrng,
123 int signable);
124static void infile(const char * filename);
125static void inleap(char ** fields, int nfields);
126static void inlink(char ** fields, int nfields);
127static void inrule(char ** fields, int nfields);
128static int inzcont(char ** fields, int nfields);
129static int inzone(char ** fields, int nfields);
130static int inzsub(char ** fields, int nfields, int iscont);
131static int is32(zic_t x);
132static int itsabbr(const char * abbr, const char * word);
133static int itsdir(const char * name);
134static int lowerit(int c);
135static char * memcheck(char * tocheck);
136static int mkdirs(char * filename);
137static void newabbr(const char * abbr);
138static long oadd(long t1, long t2);
139static void outzone(const struct zone * zp, int ntzones);
140static void puttzcode(long code, FILE * fp);
141static void puttzcode64(zic_t code, FILE * fp);
142static int rcomp(const void * leftp, const void * rightp);
143static zic_t rpytime(const struct rule * rp, int wantedy);
144static void rulesub(struct rule * rp,
122 const char * loyearp, const char * hiyearp,
123 const char * typep, const char * monthp,
145 const char * loyearp, const char * hiyearp,
146 const char * typep, const char * monthp,
124 const char * dayp, const char * timep));
125static void setboundaries P((void));
126static void setgroup P((gid_t *flag, const char *name));
127static void setuser P((uid_t *flag, const char *name));
128static time_t tadd P((time_t t1, long t2));
129static void usage P((void));
130static void writezone P((const char * name));
131static int yearistype P((int year, const char * type));
147 const char * dayp, const char * timep);
148static int stringoffset(char * result, long offset);
149static int stringrule(char * result, const struct rule * rp,
150 long dstoff, long gmtoff);
151static void stringzone(char * result,
152 const struct zone * zp, int ntzones);
153static void setboundaries(void);
154static void setgroup(gid_t *flag, const char *name);
155static void setuser(uid_t *flag, const char *name);
156static zic_t tadd(zic_t t1, long t2);
157static void usage(FILE *stream, int status);
158static void writezone(const char * name, const char * string);
159static int yearistype(int year, const char * type);
132
160
133#if !(HAVE_STRERROR - 0)
134static char * strerror P((int));
135#endif /* !(HAVE_STRERROR - 0) */
136
137static int charcnt;
138static int errors;
139static const char * filename;
140static int leapcnt;
161static int charcnt;
162static int errors;
163static const char * filename;
164static int leapcnt;
165static int leapseen;
166static int leapminyear;
167static int leapmaxyear;
141static int linenum;
168static int linenum;
142static time_t max_time;
169static int max_abbrvar_len;
170static int max_format_len;
171static zic_t max_time;
143static int max_year;
172static int max_year;
144static int max_year_representable;
145static time_t min_time;
173static zic_t min_time;
146static int min_year;
174static int min_year;
147static int min_year_representable;
175static zic_t min_time;
148static int noise;
149static const char * rfilename;
150static int rlinenum;
151static int timecnt;
152static int typecnt;
153
154/*
155** Line codes.

--- 92 unchanged lines hidden (view full) ---

248static struct link * links;
249static int nlinks;
250
251struct lookup {
252 const char * l_word;
253 const int l_value;
254};
255
176static int noise;
177static const char * rfilename;
178static int rlinenum;
179static int timecnt;
180static int typecnt;
181
182/*
183** Line codes.

--- 92 unchanged lines hidden (view full) ---

276static struct link * links;
277static int nlinks;
278
279struct lookup {
280 const char * l_word;
281 const int l_value;
282};
283
256static struct lookup const * byword P((const char * string,
257 const struct lookup * lp));
284static struct lookup const * byword(const char * string,
285 const struct lookup * lp);
258
259static struct lookup const line_codes[] = {
260 { "Rule", LC_RULE },
261 { "Zone", LC_ZONE },
262 { "Link", LC_LINK },
263 { "Leap", LC_LEAP },
264 { NULL, 0}
265};

--- 60 unchanged lines hidden (view full) ---

326 { 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }
327};
328
329static const int len_years[2] = {
330 DAYSPERNYEAR, DAYSPERLYEAR
331};
332
333static struct attype {
286
287static struct lookup const line_codes[] = {
288 { "Rule", LC_RULE },
289 { "Zone", LC_ZONE },
290 { "Link", LC_LINK },
291 { "Leap", LC_LEAP },
292 { NULL, 0}
293};

--- 60 unchanged lines hidden (view full) ---

354 { 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }
355};
356
357static const int len_years[2] = {
358 DAYSPERNYEAR, DAYSPERLYEAR
359};
360
361static struct attype {
334 time_t at;
362 zic_t at;
335 unsigned char type;
336} attypes[TZ_MAX_TIMES];
337static long gmtoffs[TZ_MAX_TYPES];
338static char isdsts[TZ_MAX_TYPES];
339static unsigned char abbrinds[TZ_MAX_TYPES];
340static char ttisstds[TZ_MAX_TYPES];
341static char ttisgmts[TZ_MAX_TYPES];
342static char chars[TZ_MAX_CHARS];
363 unsigned char type;
364} attypes[TZ_MAX_TIMES];
365static long gmtoffs[TZ_MAX_TYPES];
366static char isdsts[TZ_MAX_TYPES];
367static unsigned char abbrinds[TZ_MAX_TYPES];
368static char ttisstds[TZ_MAX_TYPES];
369static char ttisgmts[TZ_MAX_TYPES];
370static char chars[TZ_MAX_CHARS];
343static time_t trans[TZ_MAX_LEAPS];
371static zic_t trans[TZ_MAX_LEAPS];
344static long corr[TZ_MAX_LEAPS];
345static char roll[TZ_MAX_LEAPS];
346
347/*
348** Memory allocation.
349*/
350
351static char *

--- 9 unchanged lines hidden (view full) ---

361#define erealloc(ptr, size) memcheck(irealloc((ptr), (size)))
362#define ecpyalloc(ptr) memcheck(icpyalloc(ptr))
363#define ecatalloc(oldp, newp) memcheck(icatalloc((oldp), (newp)))
364
365/*
366** Error handling.
367*/
368
372static long corr[TZ_MAX_LEAPS];
373static char roll[TZ_MAX_LEAPS];
374
375/*
376** Memory allocation.
377*/
378
379static char *

--- 9 unchanged lines hidden (view full) ---

389#define erealloc(ptr, size) memcheck(irealloc((ptr), (size)))
390#define ecpyalloc(ptr) memcheck(icpyalloc(ptr))
391#define ecatalloc(oldp, newp) memcheck(icatalloc((oldp), (newp)))
392
393/*
394** Error handling.
395*/
396
369#if !(HAVE_STRERROR - 0)
370static char *
371strerror(errnum)
372int errnum;
373{
374 extern char * sys_errlist[];
375 extern int sys_nerr;
376
377 return (errnum > 0 && errnum <= sys_nerr) ?
378 sys_errlist[errnum] : _("Unknown system error");
379}
380#endif /* !(HAVE_STRERROR - 0) */
381
382static void
383eats(name, num, rname, rnum)
384const char * const name;
385const int num;
386const char * const rname;
387const int rnum;
388{
389 filename = name;

--- 37 unchanged lines hidden (view full) ---

427 cp = ecpyalloc(_("warning: "));
428 cp = ecatalloc(cp, string);
429 error(cp);
430 ifree(cp);
431 --errors;
432}
433
434static void
397static void
398eats(name, num, rname, rnum)
399const char * const name;
400const int num;
401const char * const rname;
402const int rnum;
403{
404 filename = name;

--- 37 unchanged lines hidden (view full) ---

442 cp = ecpyalloc(_("warning: "));
443 cp = ecatalloc(cp, string);
444 error(cp);
445 ifree(cp);
446 --errors;
447}
448
449static void
435usage P((void))
436{
437 (void) fprintf(stderr, "%s\n%s\n",
438_("usage: zic [--version] [-s] [-v] [-l localtime] [-p posixrules] [-d directory]"),
439_(" [-L leapseconds] [-y yearistype] [filename ... ]"));
440 (void) exit(EXIT_FAILURE);
450usage(FILE *stream, int status)
451 {
452 (void) fprintf(stream, _("usage is zic \
453[ --version ] [--help] [ -v ] [ -l localtime ] [ -p posixrules ] \\\n\
454\t[ -d directory ] [ -L leapseconds ] [ -y yearistype ] [ filename ... ]\n\
455\n\
456Report bugs to tz@elsie.nci.nih.gov.\n"));
457 exit(status);
441}
442
443static const char * psxrules;
444static const char * lcltime;
445static const char * directory;
446static const char * leapsec;
447static const char * yitcommand;
458}
459
460static const char * psxrules;
461static const char * lcltime;
462static const char * directory;
463static const char * leapsec;
464static const char * yitcommand;
448static int sflag = FALSE;
449static int Dflag;
450static uid_t uflag = (uid_t)-1;
451static gid_t gflag = (gid_t)-1;
452static mode_t mflag = (S_IRUSR | S_IRGRP | S_IROTH
453 | S_IWUSR);
454
455int
456main(argc, argv)
457int argc;
458char * argv[];
459{
460 register int i;
461 register int j;
462 register int c;
463
464#ifdef unix
465 (void) umask(umask(S_IWGRP | S_IWOTH) | (S_IWGRP | S_IWOTH));
466#endif /* defined unix */
465static int Dflag;
466static uid_t uflag = (uid_t)-1;
467static gid_t gflag = (gid_t)-1;
468static mode_t mflag = (S_IRUSR | S_IRGRP | S_IROTH
469 | S_IWUSR);
470
471int
472main(argc, argv)
473int argc;
474char * argv[];
475{
476 register int i;
477 register int j;
478 register int c;
479
480#ifdef unix
481 (void) umask(umask(S_IWGRP | S_IWOTH) | (S_IWGRP | S_IWOTH));
482#endif /* defined unix */
467#if HAVE_GETTEXT - 0
468 (void) setlocale(LC_MESSAGES, "");
483#if HAVE_GETTEXT
484 (void) setlocale(LC_ALL, "");
469#ifdef TZ_DOMAINDIR
470 (void) bindtextdomain(TZ_DOMAIN, TZ_DOMAINDIR);
471#endif /* defined TEXTDOMAINDIR */
472 (void) textdomain(TZ_DOMAIN);
485#ifdef TZ_DOMAINDIR
486 (void) bindtextdomain(TZ_DOMAIN, TZ_DOMAINDIR);
487#endif /* defined TEXTDOMAINDIR */
488 (void) textdomain(TZ_DOMAIN);
473#endif /* HAVE_GETTEXT - 0 */
489#endif /* HAVE_GETTEXT */
490 if (TYPE_BIT(zic_t) < 64) {
491 (void) fprintf(stderr, "zic: %s\n",
492 _("wild compilation-time specification of zic_t"));
493 exit(EXIT_FAILURE);
494 }
474 for (i = 1; i < argc; ++i)
475 if (strcmp(argv[i], "--version") == 0) {
476 errx(EXIT_SUCCESS, "%s", elsieid);
495 for (i = 1; i < argc; ++i)
496 if (strcmp(argv[i], "--version") == 0) {
497 errx(EXIT_SUCCESS, "%s", elsieid);
498 } else if (strcmp(argv[i], "--help") == 0) {
499 usage(stdout, EXIT_SUCCESS);
477 }
478 while ((c = getopt(argc, argv, "Dd:g:l:m:p:L:u:vsy:")) != -1)
479 switch (c) {
480 default:
500 }
501 while ((c = getopt(argc, argv, "Dd:g:l:m:p:L:u:vsy:")) != -1)
502 switch (c) {
503 default:
481 usage();
504 usage(stderr, EXIT_FAILURE);
482 case 'D':
483 Dflag = 1;
484 break;
485 case 'd':
486 if (directory == NULL)
487 directory = optarg;
488 else
489 errx(EXIT_FAILURE,

--- 42 unchanged lines hidden (view full) ---

532 else
533 errx(EXIT_FAILURE,
534_("more than one -L option specified"));
535 break;
536 case 'v':
537 noise = TRUE;
538 break;
539 case 's':
505 case 'D':
506 Dflag = 1;
507 break;
508 case 'd':
509 if (directory == NULL)
510 directory = optarg;
511 else
512 errx(EXIT_FAILURE,

--- 42 unchanged lines hidden (view full) ---

555 else
556 errx(EXIT_FAILURE,
557_("more than one -L option specified"));
558 break;
559 case 'v':
560 noise = TRUE;
561 break;
562 case 's':
540 sflag = TRUE;
563 (void) printf("zic: -s ignored\n");
541 break;
542 }
543 if (optind == argc - 1 && strcmp(argv[optind], "=") == 0)
564 break;
565 }
566 if (optind == argc - 1 && strcmp(argv[optind], "=") == 0)
544 usage(); /* usage message by request */
567 usage(stderr, EXIT_FAILURE); /* usage message by request */
545 if (directory == NULL)
546 directory = TZDIR;
547 if (yitcommand == NULL)
548 yitcommand = "yearistype";
549
550 setboundaries();
551
552 if (optind < argc && leapsec != NULL) {
553 infile(leapsec);
554 adjleap();
555 }
556
557 for (i = optind; i < argc; ++i)
558 infile(argv[i]);
559 if (errors)
568 if (directory == NULL)
569 directory = TZDIR;
570 if (yitcommand == NULL)
571 yitcommand = "yearistype";
572
573 setboundaries();
574
575 if (optind < argc && leapsec != NULL) {
576 infile(leapsec);
577 adjleap();
578 }
579
580 for (i = optind; i < argc; ++i)
581 infile(argv[i]);
582 if (errors)
560 (void) exit(EXIT_FAILURE);
583 exit(EXIT_FAILURE);
561 associate();
562 for (i = 0; i < nzones; i = j) {
563 /*
564 ** Find the next non-continuation zone entry.
565 */
566 for (j = i + 1; j < nzones && zones[j].z_name == NULL; ++j)
567 continue;
568 outzone(&zones[i], j - i);
569 }
570 /*
571 ** Make links.
572 */
573 for (i = 0; i < nlinks; ++i) {
574 eat(links[i].l_filename, links[i].l_linenum);
575 dolink(links[i].l_from, links[i].l_to);
584 associate();
585 for (i = 0; i < nzones; i = j) {
586 /*
587 ** Find the next non-continuation zone entry.
588 */
589 for (j = i + 1; j < nzones && zones[j].z_name == NULL; ++j)
590 continue;
591 outzone(&zones[i], j - i);
592 }
593 /*
594 ** Make links.
595 */
596 for (i = 0; i < nlinks; ++i) {
597 eat(links[i].l_filename, links[i].l_linenum);
598 dolink(links[i].l_from, links[i].l_to);
599 if (noise)
600 for (j = 0; j < nlinks; ++j)
601 if (strcmp(links[i].l_to,
602 links[j].l_from) == 0)
603 warning(_("link to link"));
576 }
577 if (lcltime != NULL) {
578 eat("command line", 1);
579 dolink(lcltime, TZDEFAULT);
580 }
581 if (psxrules != NULL) {
582 eat("command line", 1);
583 dolink(psxrules, TZDEFRULES);
584 }
585 return (errors == 0) ? EXIT_SUCCESS : EXIT_FAILURE;
586}
587
588static void
604 }
605 if (lcltime != NULL) {
606 eat("command line", 1);
607 dolink(lcltime, TZDEFAULT);
608 }
609 if (psxrules != NULL) {
610 eat("command line", 1);
611 dolink(psxrules, TZDEFRULES);
612 }
613 return (errors == 0) ? EXIT_SUCCESS : EXIT_FAILURE;
614}
615
616static void
589dolink(fromfile, tofile)
590const char * const fromfile;
591const char * const tofile;
617dolink(fromfield, tofield)
618const char * const fromfield;
619const char * const tofield;
592{
593 register char * fromname;
594 register char * toname;
595
620{
621 register char * fromname;
622 register char * toname;
623
596 if (fromfile[0] == '/')
597 fromname = ecpyalloc(fromfile);
624 if (fromfield[0] == '/')
625 fromname = ecpyalloc(fromfield);
598 else {
599 fromname = ecpyalloc(directory);
600 fromname = ecatalloc(fromname, "/");
626 else {
627 fromname = ecpyalloc(directory);
628 fromname = ecatalloc(fromname, "/");
601 fromname = ecatalloc(fromname, fromfile);
629 fromname = ecatalloc(fromname, fromfield);
602 }
630 }
603 if (tofile[0] == '/')
604 toname = ecpyalloc(tofile);
631 if (tofield[0] == '/')
632 toname = ecpyalloc(tofield);
605 else {
606 toname = ecpyalloc(directory);
607 toname = ecatalloc(toname, "/");
633 else {
634 toname = ecpyalloc(directory);
635 toname = ecatalloc(toname, "/");
608 toname = ecatalloc(toname, tofile);
636 toname = ecatalloc(toname, tofield);
609 }
610 /*
611 ** We get to be careful here since
612 ** there's a fair chance of root running us.
613 */
614 if (!itsdir(toname))
615 (void) remove(toname);
616 if (link(fromname, toname) != 0) {
617 int result;
618
619 if (mkdirs(toname) != 0)
637 }
638 /*
639 ** We get to be careful here since
640 ** there's a fair chance of root running us.
641 */
642 if (!itsdir(toname))
643 (void) remove(toname);
644 if (link(fromname, toname) != 0) {
645 int result;
646
647 if (mkdirs(toname) != 0)
620 (void) exit(EXIT_FAILURE);
648 exit(EXIT_FAILURE);
621
622 result = link(fromname, toname);
649
650 result = link(fromname, toname);
623#if (HAVE_SYMLINK - 0)
651#if HAVE_SYMLINK
624 if (result != 0 &&
652 if (result != 0 &&
625 access(fromname, F_OK) == 0 &&
626 !itsdir(fromname)) {
627 const char *s = tofile;
628 register char * symlinkcontents = NULL;
629 while ((s = strchr(s+1, '/')) != NULL)
630 symlinkcontents = ecatalloc(symlinkcontents, "../");
631 symlinkcontents = ecatalloc(symlinkcontents, fromfile);
632
633 result = symlink(symlinkcontents, toname);
634 if (result == 0)
653 access(fromname, F_OK) == 0 &&
654 !itsdir(fromname)) {
655 const char *s = tofield;
656 register char * symlinkcontents = NULL;
657 while ((s = strchr(s+1, '/')) != NULL)
658 symlinkcontents =
659 ecatalloc(symlinkcontents,
660 "../");
661 symlinkcontents =
662 ecatalloc(symlinkcontents,
663 fromname);
664 result =
665 symlink(symlinkcontents,
666 toname);
667 if (result == 0)
635warning(_("hard link failed, symbolic link used"));
668warning(_("hard link failed, symbolic link used"));
636 ifree(symlinkcontents);
669 ifree(symlinkcontents);
637 }
670 }
638#endif
671#endif /* HAVE_SYMLINK */
639 if (result != 0) {
640 err(EXIT_FAILURE, _("can't link from %s to %s"),
641 fromname, toname);
642 }
643 }
644 ifree(fromname);
645 ifree(toname);
646}
647
672 if (result != 0) {
673 err(EXIT_FAILURE, _("can't link from %s to %s"),
674 fromname, toname);
675 }
676 }
677 ifree(fromname);
678 ifree(toname);
679}
680
648#ifndef INT_MAX
649#define INT_MAX ((int) (((unsigned)~0)>>1))
650#endif /* !defined INT_MAX */
681#define TIME_T_BITS_IN_FILE 64
651
682
652#ifndef INT_MIN
653#define INT_MIN ((int) ~(((unsigned)~0)>>1))
654#endif /* !defined INT_MIN */
655
656/*
657** The tz file format currently allows at most 32-bit quantities.
658** This restriction should be removed before signed 32-bit values
659** wrap around in 2038, but unfortunately this will require a
660** change to the tz file format.
661*/
662
663#define MAX_BITS_IN_FILE 32
664#define TIME_T_BITS_IN_FILE ((TYPE_BIT(time_t) < MAX_BITS_IN_FILE) ? TYPE_BIT(time_t) : MAX_BITS_IN_FILE)
665
666static void
683static void
667setboundaries P((void))
684setboundaries (void)
668{
685{
669 if (TYPE_SIGNED(time_t)) {
670 min_time = ~ (time_t) 0;
671 min_time <<= TIME_T_BITS_IN_FILE - 1;
672 max_time = ~ (time_t) 0 - min_time;
673 if (sflag)
674 min_time = 0;
675 } else {
676 min_time = 0;
677 max_time = 2 - sflag;
678 max_time <<= TIME_T_BITS_IN_FILE - 1;
679 --max_time;
680 }
681 min_year = TM_YEAR_BASE + gmtime(&min_time)->tm_year;
682 max_year = TM_YEAR_BASE + gmtime(&max_time)->tm_year;
683 min_year_representable = min_year;
684 max_year_representable = max_year;
686 register int i;
687
688 min_time = -1;
689 for (i = 0; i < TIME_T_BITS_IN_FILE - 1; ++i)
690 min_time *= 2;
691 max_time = -(min_time + 1);
685}
686
687static int
688itsdir(name)
689const char * const name;
690{
691 register char * myname;
692 register int accres;

--- 18 unchanged lines hidden (view full) ---

711const void * cp1;
712const void * cp2;
713{
714 return strcmp(((const struct rule *) cp1)->r_name,
715 ((const struct rule *) cp2)->r_name);
716}
717
718static void
692}
693
694static int
695itsdir(name)
696const char * const name;
697{
698 register char * myname;
699 register int accres;

--- 18 unchanged lines hidden (view full) ---

718const void * cp1;
719const void * cp2;
720{
721 return strcmp(((const struct rule *) cp1)->r_name,
722 ((const struct rule *) cp2)->r_name);
723}
724
725static void
719associate P((void))
726associate(void)
720{
721 register struct zone * zp;
722 register struct rule * rp;
723 register int base, out;
724 register int i, j;
725
726 if (nrules != 0) {
727 (void) qsort((void *) rules, (size_t) nrules,

--- 45 unchanged lines hidden (view full) ---

773 for (i = 0; i < nzones; ++i) {
774 zp = &zones[i];
775 if (zp->z_nrules == 0) {
776 /*
777 ** Maybe we have a local standard time offset.
778 */
779 eat(zp->z_filename, zp->z_linenum);
780 zp->z_stdoff = gethms(zp->z_rule, _("unruly zone"),
727{
728 register struct zone * zp;
729 register struct rule * rp;
730 register int base, out;
731 register int i, j;
732
733 if (nrules != 0) {
734 (void) qsort((void *) rules, (size_t) nrules,

--- 45 unchanged lines hidden (view full) ---

780 for (i = 0; i < nzones; ++i) {
781 zp = &zones[i];
782 if (zp->z_nrules == 0) {
783 /*
784 ** Maybe we have a local standard time offset.
785 */
786 eat(zp->z_filename, zp->z_linenum);
787 zp->z_stdoff = gethms(zp->z_rule, _("unruly zone"),
781 TRUE);
788 TRUE);
782 /*
783 ** Note, though, that if there's no rule,
784 ** a '%s' in the format is a bad thing.
785 */
786 if (strchr(zp->z_format, '%') != 0)
787 error(_("%s in ruleless zone"));
788 }
789 }
790 if (errors)
789 /*
790 ** Note, though, that if there's no rule,
791 ** a '%s' in the format is a bad thing.
792 */
793 if (strchr(zp->z_format, '%') != 0)
794 error(_("%s in ruleless zone"));
795 }
796 }
797 if (errors)
791 (void) exit(EXIT_FAILURE);
798 exit(EXIT_FAILURE);
792}
793
794static void
795infile(name)
796const char * name;
797{
798 register FILE * fp;
799 register char ** fields;

--- 12 unchanged lines hidden (view full) ---

812 wantcont = FALSE;
813 for (num = 1; ; ++num) {
814 eat(name, num);
815 if (fgets(buf, (int) sizeof buf, fp) != buf)
816 break;
817 cp = strchr(buf, '\n');
818 if (cp == NULL) {
819 error(_("line too long"));
799}
800
801static void
802infile(name)
803const char * name;
804{
805 register FILE * fp;
806 register char ** fields;

--- 12 unchanged lines hidden (view full) ---

819 wantcont = FALSE;
820 for (num = 1; ; ++num) {
821 eat(name, num);
822 if (fgets(buf, (int) sizeof buf, fp) != buf)
823 break;
824 cp = strchr(buf, '\n');
825 if (cp == NULL) {
826 error(_("line too long"));
820 (void) exit(EXIT_FAILURE);
827 exit(EXIT_FAILURE);
821 }
822 *cp = '\0';
823 fields = getfields(buf);
824 nfields = 0;
825 while (fields[nfields] != NULL) {
826 static char nada;
827
828 if (strcmp(fields[nfields], "-") == 0)

--- 51 unchanged lines hidden (view full) ---

880*/
881
882static long
883gethms(string, errstring, signable)
884const char * string;
885const char * const errstring;
886const int signable;
887{
828 }
829 *cp = '\0';
830 fields = getfields(buf);
831 nfields = 0;
832 while (fields[nfields] != NULL) {
833 static char nada;
834
835 if (strcmp(fields[nfields], "-") == 0)

--- 51 unchanged lines hidden (view full) ---

887*/
888
889static long
890gethms(string, errstring, signable)
891const char * string;
892const char * const errstring;
893const int signable;
894{
888 int hh, mm, ss, sign;
895 long hh;
896 int mm, ss, sign;
889
890 if (string == NULL || *string == '\0')
891 return 0;
892 if (!signable)
893 sign = 1;
894 else if (*string == '-') {
895 sign = -1;
896 ++string;
897 } else sign = 1;
897
898 if (string == NULL || *string == '\0')
899 return 0;
900 if (!signable)
901 sign = 1;
902 else if (*string == '-') {
903 sign = -1;
904 ++string;
905 } else sign = 1;
898 if (sscanf(string, scheck(string, "%d"), &hh) == 1)
906 if (sscanf(string, scheck(string, "%ld"), &hh) == 1)
899 mm = ss = 0;
907 mm = ss = 0;
900 else if (sscanf(string, scheck(string, "%d:%d"), &hh, &mm) == 2)
908 else if (sscanf(string, scheck(string, "%ld:%d"), &hh, &mm) == 2)
901 ss = 0;
909 ss = 0;
902 else if (sscanf(string, scheck(string, "%d:%d:%d"),
910 else if (sscanf(string, scheck(string, "%ld:%d:%d"),
903 &hh, &mm, &ss) != 3) {
904 error(errstring);
905 return 0;
906 }
911 &hh, &mm, &ss) != 3) {
912 error(errstring);
913 return 0;
914 }
907 if ((hh < 0 || hh >= HOURSPERDAY ||
915 if (hh < 0 ||
908 mm < 0 || mm >= MINSPERHOUR ||
916 mm < 0 || mm >= MINSPERHOUR ||
909 ss < 0 || ss > SECSPERMIN) &&
910 !(hh == HOURSPERDAY && mm == 0 && ss == 0)) {
917 ss < 0 || ss > SECSPERMIN) {
911 error(errstring);
912 return 0;
913 }
918 error(errstring);
919 return 0;
920 }
914 if (noise && hh == HOURSPERDAY)
921 if (LONG_MAX / SECSPERHOUR < hh) {
922 error(_("time overflow"));
923 return 0;
924 }
925 if (noise && hh == HOURSPERDAY && mm == 0 && ss == 0)
915 warning(_("24:00 not handled by pre-1998 versions of zic"));
926 warning(_("24:00 not handled by pre-1998 versions of zic"));
916 return eitol(sign) *
917 (eitol(hh * MINSPERHOUR + mm) *
918 eitol(SECSPERMIN) + eitol(ss));
927 if (noise && (hh > HOURSPERDAY ||
928 (hh == HOURSPERDAY && (mm != 0 || ss != 0))))
929warning(_("values over 24 hours not handled by pre-2007 versions of zic"));
930 return oadd(eitol(sign) * hh * eitol(SECSPERHOUR),
931 eitol(sign) * (eitol(mm) * eitol(SECSPERMIN) + eitol(ss)));
919}
920
921static void
922inrule(fields, nfields)
923register char ** const fields;
924const int nfields;
925{
926 static struct rule r;

--- 8 unchanged lines hidden (view full) ---

935 }
936 r.r_filename = filename;
937 r.r_linenum = linenum;
938 r.r_stdoff = gethms(fields[RF_STDOFF], _("invalid saved time"), TRUE);
939 rulesub(&r, fields[RF_LOYEAR], fields[RF_HIYEAR], fields[RF_COMMAND],
940 fields[RF_MONTH], fields[RF_DAY], fields[RF_TOD]);
941 r.r_name = ecpyalloc(fields[RF_NAME]);
942 r.r_abbrvar = ecpyalloc(fields[RF_ABBRVAR]);
932}
933
934static void
935inrule(fields, nfields)
936register char ** const fields;
937const int nfields;
938{
939 static struct rule r;

--- 8 unchanged lines hidden (view full) ---

948 }
949 r.r_filename = filename;
950 r.r_linenum = linenum;
951 r.r_stdoff = gethms(fields[RF_STDOFF], _("invalid saved time"), TRUE);
952 rulesub(&r, fields[RF_LOYEAR], fields[RF_HIYEAR], fields[RF_COMMAND],
953 fields[RF_MONTH], fields[RF_DAY], fields[RF_TOD]);
954 r.r_name = ecpyalloc(fields[RF_NAME]);
955 r.r_abbrvar = ecpyalloc(fields[RF_ABBRVAR]);
956 if (max_abbrvar_len < strlen(r.r_abbrvar))
957 max_abbrvar_len = strlen(r.r_abbrvar);
943 rules = (struct rule *) (void *) erealloc((char *) rules,
944 (int) ((nrules + 1) * sizeof *rules));
945 rules[nrules++] = r;
946}
947
948static int
949inzone(fields, nfields)
950register char ** const fields;

--- 89 unchanged lines hidden (view full) ---

1040 if ((cp = strchr(fields[i_format], '%')) != 0) {
1041 if (*++cp != 's' || strchr(cp, '%') != 0) {
1042 error(_("invalid abbreviation format"));
1043 return FALSE;
1044 }
1045 }
1046 z.z_rule = ecpyalloc(fields[i_rule]);
1047 z.z_format = ecpyalloc(fields[i_format]);
958 rules = (struct rule *) (void *) erealloc((char *) rules,
959 (int) ((nrules + 1) * sizeof *rules));
960 rules[nrules++] = r;
961}
962
963static int
964inzone(fields, nfields)
965register char ** const fields;

--- 89 unchanged lines hidden (view full) ---

1055 if ((cp = strchr(fields[i_format], '%')) != 0) {
1056 if (*++cp != 's' || strchr(cp, '%') != 0) {
1057 error(_("invalid abbreviation format"));
1058 return FALSE;
1059 }
1060 }
1061 z.z_rule = ecpyalloc(fields[i_rule]);
1062 z.z_format = ecpyalloc(fields[i_format]);
1063 if (max_format_len < strlen(z.z_format))
1064 max_format_len = strlen(z.z_format);
1048 hasuntil = nfields > i_untilyear;
1049 if (hasuntil) {
1050 z.z_untilrule.r_filename = filename;
1051 z.z_untilrule.r_linenum = linenum;
1052 rulesub(&z.z_untilrule,
1053 fields[i_untilyear],
1054 "only",
1055 "",

--- 4 unchanged lines hidden (view full) ---

1060 z.z_untiltime = rpytime(&z.z_untilrule,
1061 z.z_untilrule.r_loyear);
1062 if (iscont && nzones > 0 &&
1063 z.z_untiltime > min_time &&
1064 z.z_untiltime < max_time &&
1065 zones[nzones - 1].z_untiltime > min_time &&
1066 zones[nzones - 1].z_untiltime < max_time &&
1067 zones[nzones - 1].z_untiltime >= z.z_untiltime) {
1065 hasuntil = nfields > i_untilyear;
1066 if (hasuntil) {
1067 z.z_untilrule.r_filename = filename;
1068 z.z_untilrule.r_linenum = linenum;
1069 rulesub(&z.z_untilrule,
1070 fields[i_untilyear],
1071 "only",
1072 "",

--- 4 unchanged lines hidden (view full) ---

1077 z.z_untiltime = rpytime(&z.z_untilrule,
1078 z.z_untilrule.r_loyear);
1079 if (iscont && nzones > 0 &&
1080 z.z_untiltime > min_time &&
1081 z.z_untiltime < max_time &&
1082 zones[nzones - 1].z_untiltime > min_time &&
1083 zones[nzones - 1].z_untiltime < max_time &&
1084 zones[nzones - 1].z_untiltime >= z.z_untiltime) {
1068 error(_("Zone continuation line end time is not after end time of previous line"));
1085 error(_(
1086"Zone continuation line end time is not after end time of previous line"
1087 ));
1069 return FALSE;
1070 }
1071 }
1072 zones = (struct zone *) (void *) erealloc((char *) zones,
1073 (int) ((nzones + 1) * sizeof *zones));
1074 zones[nzones++] = z;
1075 /*
1076 ** If there was an UNTIL field on this line,

--- 7 unchanged lines hidden (view full) ---

1084register char ** const fields;
1085const int nfields;
1086{
1087 register const char * cp;
1088 register const struct lookup * lp;
1089 register int i, j;
1090 int year, month, day;
1091 long dayoff, tod;
1088 return FALSE;
1089 }
1090 }
1091 zones = (struct zone *) (void *) erealloc((char *) zones,
1092 (int) ((nzones + 1) * sizeof *zones));
1093 zones[nzones++] = z;
1094 /*
1095 ** If there was an UNTIL field on this line,

--- 7 unchanged lines hidden (view full) ---

1103register char ** const fields;
1104const int nfields;
1105{
1106 register const char * cp;
1107 register const struct lookup * lp;
1108 register int i, j;
1109 int year, month, day;
1110 long dayoff, tod;
1092 time_t t;
1111 zic_t t;
1093
1094 if (nfields != LEAP_FIELDS) {
1095 error(_("wrong number of fields on Leap line"));
1096 return;
1097 }
1098 dayoff = 0;
1099 cp = fields[LP_YEAR];
1100 if (sscanf(cp, scheck(cp, "%d"), &year) != 1) {
1112
1113 if (nfields != LEAP_FIELDS) {
1114 error(_("wrong number of fields on Leap line"));
1115 return;
1116 }
1117 dayoff = 0;
1118 cp = fields[LP_YEAR];
1119 if (sscanf(cp, scheck(cp, "%d"), &year) != 1) {
1101 /*
1102 * Leapin' Lizards!
1103 */
1104 error(_("invalid leaping year"));
1105 return;
1120 /*
1121 ** Leapin' Lizards!
1122 */
1123 error(_("invalid leaping year"));
1124 return;
1106 }
1125 }
1126 if (!leapseen || leapmaxyear < year)
1127 leapmaxyear = year;
1128 if (!leapseen || leapminyear > year)
1129 leapminyear = year;
1130 leapseen = TRUE;
1107 j = EPOCH_YEAR;
1108 while (j != year) {
1109 if (year > j) {
1110 i = len_years[isleap(j)];
1111 ++j;
1112 } else {
1113 --j;
1114 i = -len_years[isleap(j)];

--- 13 unchanged lines hidden (view full) ---

1128 }
1129 cp = fields[LP_DAY];
1130 if (sscanf(cp, scheck(cp, "%d"), &day) != 1 ||
1131 day <= 0 || day > len_months[isleap(year)][month]) {
1132 error(_("invalid day of month"));
1133 return;
1134 }
1135 dayoff = oadd(dayoff, eitol(day - 1));
1131 j = EPOCH_YEAR;
1132 while (j != year) {
1133 if (year > j) {
1134 i = len_years[isleap(j)];
1135 ++j;
1136 } else {
1137 --j;
1138 i = -len_years[isleap(j)];

--- 13 unchanged lines hidden (view full) ---

1152 }
1153 cp = fields[LP_DAY];
1154 if (sscanf(cp, scheck(cp, "%d"), &day) != 1 ||
1155 day <= 0 || day > len_months[isleap(year)][month]) {
1156 error(_("invalid day of month"));
1157 return;
1158 }
1159 dayoff = oadd(dayoff, eitol(day - 1));
1136 if (dayoff < 0 && !TYPE_SIGNED(time_t)) {
1160 if (dayoff < 0 && !TYPE_SIGNED(zic_t)) {
1137 error(_("time before zero"));
1138 return;
1139 }
1140 if (dayoff < min_time / SECSPERDAY) {
1141 error(_("time too small"));
1142 return;
1143 }
1144 if (dayoff > max_time / SECSPERDAY) {
1145 error(_("time too large"));
1146 return;
1147 }
1161 error(_("time before zero"));
1162 return;
1163 }
1164 if (dayoff < min_time / SECSPERDAY) {
1165 error(_("time too small"));
1166 return;
1167 }
1168 if (dayoff > max_time / SECSPERDAY) {
1169 error(_("time too large"));
1170 return;
1171 }
1148 t = (time_t) dayoff * SECSPERDAY;
1172 t = (zic_t) dayoff * SECSPERDAY;
1149 tod = gethms(fields[LP_TIME], _("invalid time of day"), FALSE);
1150 cp = fields[LP_CORR];
1151 {
1152 register int positive;
1153 int count;
1154
1155 if (strcmp(cp, "") == 0) { /* infile() turns "-" into "" */
1156 positive = FALSE;

--- 7 unchanged lines hidden (view full) ---

1164 } else if (strcmp(cp, "++") == 0) {
1165 positive = TRUE;
1166 count = 2;
1167 } else {
1168 error(_("illegal CORRECTION field on Leap line"));
1169 return;
1170 }
1171 if ((lp = byword(fields[LP_ROLL], leap_types)) == NULL) {
1173 tod = gethms(fields[LP_TIME], _("invalid time of day"), FALSE);
1174 cp = fields[LP_CORR];
1175 {
1176 register int positive;
1177 int count;
1178
1179 if (strcmp(cp, "") == 0) { /* infile() turns "-" into "" */
1180 positive = FALSE;

--- 7 unchanged lines hidden (view full) ---

1188 } else if (strcmp(cp, "++") == 0) {
1189 positive = TRUE;
1190 count = 2;
1191 } else {
1192 error(_("illegal CORRECTION field on Leap line"));
1193 return;
1194 }
1195 if ((lp = byword(fields[LP_ROLL], leap_types)) == NULL) {
1172 error(_("illegal Rolling/Stationary field on Leap line"));
1196 error(_(
1197 "illegal Rolling/Stationary field on Leap line"
1198 ));
1173 return;
1174 }
1175 leapadd(tadd(t, tod), positive, lp->l_value, count);
1176 }
1177}
1178
1179static void
1180inlink(fields, nfields)

--- 70 unchanged lines hidden (view full) ---

1251 }
1252 rp->r_tod = gethms(dp, _("invalid time of day"), FALSE);
1253 ifree(dp);
1254 /*
1255 ** Year work.
1256 */
1257 cp = loyearp;
1258 lp = byword(cp, begin_years);
1199 return;
1200 }
1201 leapadd(tadd(t, tod), positive, lp->l_value, count);
1202 }
1203}
1204
1205static void
1206inlink(fields, nfields)

--- 70 unchanged lines hidden (view full) ---

1277 }
1278 rp->r_tod = gethms(dp, _("invalid time of day"), FALSE);
1279 ifree(dp);
1280 /*
1281 ** Year work.
1282 */
1283 cp = loyearp;
1284 lp = byword(cp, begin_years);
1259 if (lp != NULL) switch ((int) lp->l_value) {
1285 rp->r_lowasnum = lp == NULL;
1286 if (!rp->r_lowasnum) switch ((int) lp->l_value) {
1260 case YR_MINIMUM:
1261 rp->r_loyear = INT_MIN;
1262 break;
1263 case YR_MAXIMUM:
1264 rp->r_loyear = INT_MAX;
1265 break;
1266 default: /* "cannot happen" */
1267 errx(EXIT_FAILURE,
1268 _("panic: invalid l_value %d"), lp->l_value);
1269 } else if (sscanf(cp, scheck(cp, "%d"), &rp->r_loyear) != 1) {
1270 error(_("invalid starting year"));
1271 return;
1287 case YR_MINIMUM:
1288 rp->r_loyear = INT_MIN;
1289 break;
1290 case YR_MAXIMUM:
1291 rp->r_loyear = INT_MAX;
1292 break;
1293 default: /* "cannot happen" */
1294 errx(EXIT_FAILURE,
1295 _("panic: invalid l_value %d"), lp->l_value);
1296 } else if (sscanf(cp, scheck(cp, "%d"), &rp->r_loyear) != 1) {
1297 error(_("invalid starting year"));
1298 return;
1272 } else if (noise) {
1273 if (rp->r_loyear < min_year_representable)
1274 warning(_("starting year too low to be represented"));
1275 else if (rp->r_loyear > max_year_representable)
1276 warning(_("starting year too high to be represented"));
1277 }
1278 cp = hiyearp;
1299 }
1300 cp = hiyearp;
1279 if ((lp = byword(cp, end_years)) != NULL) switch ((int) lp->l_value) {
1301 lp = byword(cp, end_years);
1302 rp->r_hiwasnum = lp == NULL;
1303 if (!rp->r_hiwasnum) switch ((int) lp->l_value) {
1280 case YR_MINIMUM:
1281 rp->r_hiyear = INT_MIN;
1282 break;
1283 case YR_MAXIMUM:
1284 rp->r_hiyear = INT_MAX;
1285 break;
1286 case YR_ONLY:
1287 rp->r_hiyear = rp->r_loyear;
1288 break;
1289 default: /* "cannot happen" */
1290 errx(EXIT_FAILURE,
1291 _("panic: invalid l_value %d"), lp->l_value);
1292 } else if (sscanf(cp, scheck(cp, "%d"), &rp->r_hiyear) != 1) {
1293 error(_("invalid ending year"));
1294 return;
1304 case YR_MINIMUM:
1305 rp->r_hiyear = INT_MIN;
1306 break;
1307 case YR_MAXIMUM:
1308 rp->r_hiyear = INT_MAX;
1309 break;
1310 case YR_ONLY:
1311 rp->r_hiyear = rp->r_loyear;
1312 break;
1313 default: /* "cannot happen" */
1314 errx(EXIT_FAILURE,
1315 _("panic: invalid l_value %d"), lp->l_value);
1316 } else if (sscanf(cp, scheck(cp, "%d"), &rp->r_hiyear) != 1) {
1317 error(_("invalid ending year"));
1318 return;
1295 } else if (noise) {
1296 if (rp->r_loyear < min_year_representable)
1297 warning(_("ending year too low to be represented"));
1298 else if (rp->r_loyear > max_year_representable)
1299 warning(_("ending year too high to be represented"));
1300 }
1301 if (rp->r_loyear > rp->r_hiyear) {
1302 error(_("starting year greater than ending year"));
1303 return;
1304 }
1305 if (*typep == '\0')
1306 rp->r_yrtype = NULL;
1307 else {
1308 if (rp->r_loyear == rp->r_hiyear) {
1309 error(_("typed single year"));
1310 return;
1311 }
1312 rp->r_yrtype = ecpyalloc(typep);
1313 }
1319 }
1320 if (rp->r_loyear > rp->r_hiyear) {
1321 error(_("starting year greater than ending year"));
1322 return;
1323 }
1324 if (*typep == '\0')
1325 rp->r_yrtype = NULL;
1326 else {
1327 if (rp->r_loyear == rp->r_hiyear) {
1328 error(_("typed single year"));
1329 return;
1330 }
1331 rp->r_yrtype = ecpyalloc(typep);
1332 }
1314 if (rp->r_loyear < min_year && rp->r_loyear > 0)
1315 min_year = rp->r_loyear;
1316 /*
1317 ** Day work.
1318 ** Accept things such as:
1319 ** 1
1320 ** last-Sunday
1321 ** Sun<=20
1322 ** Sun>=7
1323 */

--- 37 unchanged lines hidden (view full) ---

1361}
1362
1363static void
1364convert(val, buf)
1365const long val;
1366char * const buf;
1367{
1368 register int i;
1333 /*
1334 ** Day work.
1335 ** Accept things such as:
1336 ** 1
1337 ** last-Sunday
1338 ** Sun<=20
1339 ** Sun>=7
1340 */

--- 37 unchanged lines hidden (view full) ---

1378}
1379
1380static void
1381convert(val, buf)
1382const long val;
1383char * const buf;
1384{
1385 register int i;
1369 register long shift;
1386 register int shift;
1370
1371 for (i = 0, shift = 24; i < 4; ++i, shift -= 8)
1372 buf[i] = val >> shift;
1373}
1374
1375static void
1387
1388 for (i = 0, shift = 24; i < 4; ++i, shift -= 8)
1389 buf[i] = val >> shift;
1390}
1391
1392static void
1393convert64(val, buf)
1394const zic_t val;
1395char * const buf;
1396{
1397 register int i;
1398 register int shift;
1399
1400 for (i = 0, shift = 56; i < 8; ++i, shift -= 8)
1401 buf[i] = val >> shift;
1402}
1403
1404static void
1376puttzcode(val, fp)
1377const long val;
1378FILE * const fp;
1379{
1380 char buf[4];
1381
1382 convert(val, buf);
1383 (void) fwrite((void *) buf, (size_t) sizeof buf, (size_t) 1, fp);
1384}
1385
1405puttzcode(val, fp)
1406const long val;
1407FILE * const fp;
1408{
1409 char buf[4];
1410
1411 convert(val, buf);
1412 (void) fwrite((void *) buf, (size_t) sizeof buf, (size_t) 1, fp);
1413}
1414
1415static void
1416puttzcode64(val, fp)
1417const zic_t val;
1418FILE * const fp;
1419{
1420 char buf[8];
1421
1422 convert64(val, buf);
1423 (void) fwrite((void *) buf, (size_t) sizeof buf, (size_t) 1, fp);
1424}
1425
1386static int
1387atcomp(avp, bvp)
1426static int
1427atcomp(avp, bvp)
1388void * avp;
1389void * bvp;
1428const void * avp;
1429const void * bvp;
1390{
1430{
1391 if (((struct attype *) avp)->at < ((struct attype *) bvp)->at)
1392 return -1;
1393 else if (((struct attype *) avp)->at > ((struct attype *) bvp)->at)
1394 return 1;
1395 else return 0;
1431 const zic_t a = ((const struct attype *) avp)->at;
1432 const zic_t b = ((const struct attype *) bvp)->at;
1433
1434 return (a < b) ? -1 : (a > b);
1396}
1397
1435}
1436
1437static int
1438is32(x)
1439const zic_t x;
1440{
1441 return INT32_MIN <= x && x <= INT32_MAX;
1442}
1443
1398static void
1444static void
1399writezone(name)
1445writezone(name, string)
1400const char * const name;
1446const char * const name;
1447const char * const string;
1401{
1448{
1402 register FILE * fp;
1403 register int i, j;
1404 static char * fullname;
1405 static struct tzhead tzh;
1406 time_t ats[TZ_MAX_TIMES];
1407 unsigned char types[TZ_MAX_TIMES];
1449 register FILE * fp;
1450 register int i, j;
1451 register int leapcnt32, leapi32;
1452 register int timecnt32, timei32;
1453 register int pass;
1454 static char * fullname;
1455 static const struct tzhead tzh0;
1456 static struct tzhead tzh;
1457 zic_t ats[TZ_MAX_TIMES];
1458 unsigned char types[TZ_MAX_TIMES];
1408
1409 /*
1410 ** Sort.
1411 */
1412 if (timecnt > 1)
1413 (void) qsort((void *) attypes, (size_t) timecnt,
1414 (size_t) sizeof *attypes, atcomp);
1415 /*

--- 6 unchanged lines hidden (view full) ---

1422 toi = 0;
1423 fromi = 0;
1424 while (fromi < timecnt && attypes[fromi].at < min_time)
1425 ++fromi;
1426 if (isdsts[0] == 0)
1427 while (fromi < timecnt && attypes[fromi].type == 0)
1428 ++fromi; /* handled by default rule */
1429 for ( ; fromi < timecnt; ++fromi) {
1459
1460 /*
1461 ** Sort.
1462 */
1463 if (timecnt > 1)
1464 (void) qsort((void *) attypes, (size_t) timecnt,
1465 (size_t) sizeof *attypes, atcomp);
1466 /*

--- 6 unchanged lines hidden (view full) ---

1473 toi = 0;
1474 fromi = 0;
1475 while (fromi < timecnt && attypes[fromi].at < min_time)
1476 ++fromi;
1477 if (isdsts[0] == 0)
1478 while (fromi < timecnt && attypes[fromi].type == 0)
1479 ++fromi; /* handled by default rule */
1480 for ( ; fromi < timecnt; ++fromi) {
1430 if (toi != 0
1431 && ((attypes[fromi].at
1432 + gmtoffs[attypes[toi - 1].type])
1433 <= (attypes[toi - 1].at
1434 + gmtoffs[toi == 1 ? 0
1435 : attypes[toi - 2].type]))) {
1436 attypes[toi - 1].type = attypes[fromi].type;
1437 continue;
1481 if (toi != 0 && ((attypes[fromi].at +
1482 gmtoffs[attypes[toi - 1].type]) <=
1483 (attypes[toi - 1].at + gmtoffs[toi == 1 ? 0
1484 : attypes[toi - 2].type]))) {
1485 attypes[toi - 1].type =
1486 attypes[fromi].type;
1487 continue;
1438 }
1439 if (toi == 0 ||
1440 attypes[toi - 1].type != attypes[fromi].type)
1441 attypes[toi++] = attypes[fromi];
1442 }
1443 timecnt = toi;
1444 }
1445 /*
1446 ** Transfer.
1447 */
1448 for (i = 0; i < timecnt; ++i) {
1449 ats[i] = attypes[i].at;
1450 types[i] = attypes[i].type;
1451 }
1488 }
1489 if (toi == 0 ||
1490 attypes[toi - 1].type != attypes[fromi].type)
1491 attypes[toi++] = attypes[fromi];
1492 }
1493 timecnt = toi;
1494 }
1495 /*
1496 ** Transfer.
1497 */
1498 for (i = 0; i < timecnt; ++i) {
1499 ats[i] = attypes[i].at;
1500 types[i] = attypes[i].type;
1501 }
1502 /*
1503 ** Correct for leap seconds.
1504 */
1505 for (i = 0; i < timecnt; ++i) {
1506 j = leapcnt;
1507 while (--j >= 0)
1508 if (ats[i] > trans[j] - corr[j]) {
1509 ats[i] = tadd(ats[i], corr[j]);
1510 break;
1511 }
1512 }
1513 /*
1514 ** Figure out 32-bit-limited starts and counts.
1515 */
1516 timecnt32 = timecnt;
1517 timei32 = 0;
1518 leapcnt32 = leapcnt;
1519 leapi32 = 0;
1520 while (timecnt32 > 0 && !is32(ats[timecnt32 - 1]))
1521 --timecnt32;
1522 while (timecnt32 > 0 && !is32(ats[timei32])) {
1523 --timecnt32;
1524 ++timei32;
1525 }
1526 while (leapcnt32 > 0 && !is32(trans[leapcnt32 - 1]))
1527 --leapcnt32;
1528 while (leapcnt32 > 0 && !is32(trans[leapi32])) {
1529 --leapcnt32;
1530 ++leapi32;
1531 }
1452 fullname = erealloc(fullname,
1453 (int) (strlen(directory) + 1 + strlen(name) + 1));
1454 (void) sprintf(fullname, "%s/%s", directory, name);
1455
1456 /*
1457 * Remove old file, if any, to snap links.
1458 */
1459 if (!itsdir(fullname) && remove(fullname) != 0 && errno != ENOENT)
1460 err(EXIT_FAILURE, _("can't remove %s"), fullname);
1461
1462 if ((fp = fopen(fullname, "wb")) == NULL) {
1463 if (mkdirs(fullname) != 0)
1532 fullname = erealloc(fullname,
1533 (int) (strlen(directory) + 1 + strlen(name) + 1));
1534 (void) sprintf(fullname, "%s/%s", directory, name);
1535
1536 /*
1537 * Remove old file, if any, to snap links.
1538 */
1539 if (!itsdir(fullname) && remove(fullname) != 0 && errno != ENOENT)
1540 err(EXIT_FAILURE, _("can't remove %s"), fullname);
1541
1542 if ((fp = fopen(fullname, "wb")) == NULL) {
1543 if (mkdirs(fullname) != 0)
1464 (void) exit(EXIT_FAILURE);
1544 exit(EXIT_FAILURE);
1465 if ((fp = fopen(fullname, "wb")) == NULL)
1466 err(EXIT_FAILURE, _("can't create %s"), fullname);
1467 }
1545 if ((fp = fopen(fullname, "wb")) == NULL)
1546 err(EXIT_FAILURE, _("can't create %s"), fullname);
1547 }
1468 convert(eitol(typecnt), tzh.tzh_ttisgmtcnt);
1469 convert(eitol(typecnt), tzh.tzh_ttisstdcnt);
1470 convert(eitol(leapcnt), tzh.tzh_leapcnt);
1471 convert(eitol(timecnt), tzh.tzh_timecnt);
1472 convert(eitol(typecnt), tzh.tzh_typecnt);
1473 convert(eitol(charcnt), tzh.tzh_charcnt);
1474 (void) strncpy(tzh.tzh_magic, TZ_MAGIC, sizeof tzh.tzh_magic);
1475#define DO(field) (void) fwrite((void *) tzh.field, (size_t) sizeof tzh.field, (size_t) 1, fp)
1476 DO(tzh_magic);
1477 DO(tzh_reserved);
1478 DO(tzh_ttisgmtcnt);
1479 DO(tzh_ttisstdcnt);
1480 DO(tzh_leapcnt);
1481 DO(tzh_timecnt);
1482 DO(tzh_typecnt);
1483 DO(tzh_charcnt);
1548 for (pass = 1; pass <= 2; ++pass) {
1549 register int thistimei, thistimecnt;
1550 register int thisleapi, thisleapcnt;
1551 register int thistimelim, thisleaplim;
1552 int writetype[TZ_MAX_TIMES];
1553 int typemap[TZ_MAX_TYPES];
1554 register int thistypecnt;
1555 char thischars[TZ_MAX_CHARS];
1556 char thischarcnt;
1557 int indmap[TZ_MAX_CHARS];
1558
1559 if (pass == 1) {
1560 thistimei = timei32;
1561 thistimecnt = timecnt32;
1562 thisleapi = leapi32;
1563 thisleapcnt = leapcnt32;
1564 } else {
1565 thistimei = 0;
1566 thistimecnt = timecnt;
1567 thisleapi = 0;
1568 thisleapcnt = leapcnt;
1569 }
1570 thistimelim = thistimei + thistimecnt;
1571 thisleaplim = thisleapi + thisleapcnt;
1572 for (i = 0; i < typecnt; ++i)
1573 writetype[i] = thistimecnt == timecnt;
1574 if (thistimecnt == 0) {
1575 /*
1576 ** No transition times fall in the current
1577 ** (32- or 64-bit) window.
1578 */
1579 if (typecnt != 0)
1580 writetype[typecnt - 1] = TRUE;
1581 } else {
1582 for (i = thistimei - 1; i < thistimelim; ++i)
1583 if (i >= 0)
1584 writetype[types[i]] = TRUE;
1585 /*
1586 ** For America/Godthab and Antarctica/Palmer
1587 */
1588 if (thistimei == 0)
1589 writetype[0] = TRUE;
1590 }
1591 thistypecnt = 0;
1592 for (i = 0; i < typecnt; ++i)
1593 typemap[i] = writetype[i] ? thistypecnt++ : -1;
1594 for (i = 0; i < sizeof indmap / sizeof indmap[0]; ++i)
1595 indmap[i] = -1;
1596 thischarcnt = 0;
1597 for (i = 0; i < typecnt; ++i) {
1598 register char * thisabbr;
1599
1600 if (!writetype[i])
1601 continue;
1602 if (indmap[abbrinds[i]] >= 0)
1603 continue;
1604 thisabbr = &chars[abbrinds[i]];
1605 for (j = 0; j < thischarcnt; ++j)
1606 if (strcmp(&thischars[j], thisabbr) == 0)
1607 break;
1608 if (j == thischarcnt) {
1609 (void) strcpy(&thischars[(int) thischarcnt],
1610 thisabbr);
1611 thischarcnt += strlen(thisabbr) + 1;
1612 }
1613 indmap[abbrinds[i]] = j;
1614 }
1615#define DO(field) (void) fwrite((void *) tzh.field, \
1616 (size_t) sizeof tzh.field, (size_t) 1, fp)
1617 tzh = tzh0;
1618 (void) strncpy(tzh.tzh_magic, TZ_MAGIC, sizeof tzh.tzh_magic);
1619 tzh.tzh_version[0] = ZIC_VERSION;
1620 convert(eitol(thistypecnt), tzh.tzh_ttisgmtcnt);
1621 convert(eitol(thistypecnt), tzh.tzh_ttisstdcnt);
1622 convert(eitol(thisleapcnt), tzh.tzh_leapcnt);
1623 convert(eitol(thistimecnt), tzh.tzh_timecnt);
1624 convert(eitol(thistypecnt), tzh.tzh_typecnt);
1625 convert(eitol(thischarcnt), tzh.tzh_charcnt);
1626 DO(tzh_magic);
1627 DO(tzh_version);
1628 DO(tzh_reserved);
1629 DO(tzh_ttisgmtcnt);
1630 DO(tzh_ttisstdcnt);
1631 DO(tzh_leapcnt);
1632 DO(tzh_timecnt);
1633 DO(tzh_typecnt);
1634 DO(tzh_charcnt);
1484#undef DO
1635#undef DO
1485 for (i = 0; i < timecnt; ++i) {
1486 j = leapcnt;
1487 while (--j >= 0)
1488 if (ats[i] >= trans[j]) {
1489 ats[i] = tadd(ats[i], corr[j]);
1490 break;
1636 for (i = thistimei; i < thistimelim; ++i)
1637 if (pass == 1)
1638 puttzcode((long) ats[i], fp);
1639 else puttzcode64(ats[i], fp);
1640 for (i = thistimei; i < thistimelim; ++i) {
1641 unsigned char uc;
1642
1643 uc = typemap[types[i]];
1644 (void) fwrite((void *) &uc,
1645 (size_t) sizeof uc,
1646 (size_t) 1,
1647 fp);
1648 }
1649 for (i = 0; i < typecnt; ++i)
1650 if (writetype[i]) {
1651 puttzcode(gmtoffs[i], fp);
1652 (void) putc(isdsts[i], fp);
1653 (void) putc((unsigned char) indmap[abbrinds[i]], fp);
1491 }
1654 }
1492 puttzcode((long) ats[i], fp);
1655 if (thischarcnt != 0)
1656 (void) fwrite((void *) thischars,
1657 (size_t) sizeof thischars[0],
1658 (size_t) thischarcnt, fp);
1659 for (i = thisleapi; i < thisleaplim; ++i) {
1660 register zic_t todo;
1661
1662 if (roll[i]) {
1663 if (timecnt == 0 || trans[i] < ats[0]) {
1664 j = 0;
1665 while (isdsts[j])
1666 if (++j >= typecnt) {
1667 j = 0;
1668 break;
1669 }
1670 } else {
1671 j = 1;
1672 while (j < timecnt &&
1673 trans[i] >= ats[j])
1674 ++j;
1675 j = types[j - 1];
1676 }
1677 todo = tadd(trans[i], -gmtoffs[j]);
1678 } else todo = trans[i];
1679 if (pass == 1)
1680 puttzcode((long) todo, fp);
1681 else puttzcode64(todo, fp);
1682 puttzcode(corr[i], fp);
1683 }
1684 for (i = 0; i < typecnt; ++i)
1685 if (writetype[i])
1686 (void) putc(ttisstds[i], fp);
1687 for (i = 0; i < typecnt; ++i)
1688 if (writetype[i])
1689 (void) putc(ttisgmts[i], fp);
1493 }
1690 }
1494 if (timecnt > 0)
1495 (void) fwrite((void *) types, (size_t) sizeof types[0],
1496 (size_t) timecnt, fp);
1497 for (i = 0; i < typecnt; ++i) {
1498 puttzcode((long) gmtoffs[i], fp);
1499 (void) putc(isdsts[i], fp);
1500 (void) putc(abbrinds[i], fp);
1501 }
1502 if (charcnt != 0)
1503 (void) fwrite((void *) chars, (size_t) sizeof chars[0],
1504 (size_t) charcnt, fp);
1505 for (i = 0; i < leapcnt; ++i) {
1506 if (roll[i]) {
1507 if (timecnt == 0 || trans[i] < ats[0]) {
1508 j = 0;
1509 while (isdsts[j])
1510 if (++j >= typecnt) {
1511 j = 0;
1512 break;
1513 }
1514 } else {
1515 j = 1;
1516 while (j < timecnt && trans[i] >= ats[j])
1517 ++j;
1518 j = types[j - 1];
1519 }
1520 puttzcode((long) tadd(trans[i], -gmtoffs[j]), fp);
1521 } else puttzcode((long) trans[i], fp);
1522 puttzcode((long) corr[i], fp);
1523 }
1524 for (i = 0; i < typecnt; ++i)
1525 (void) putc(ttisstds[i], fp);
1526 for (i = 0; i < typecnt; ++i)
1527 (void) putc(ttisgmts[i], fp);
1691 (void) fprintf(fp, "\n%s\n", string);
1528 if (ferror(fp) || fclose(fp))
1529 errx(EXIT_FAILURE, _("error writing %s"), fullname);
1530 if (chmod(fullname, mflag) < 0)
1531 err(EXIT_FAILURE, _("cannot change mode of %s to %03o"),
1532 fullname, (unsigned)mflag);
1533 if ((uflag != (uid_t)-1 || gflag != (gid_t)-1)
1534 && chown(fullname, uflag, gflag) < 0)
1535 err(EXIT_FAILURE, _("cannot change ownership of %s"),
1536 fullname);
1537}
1538
1539static void
1692 if (ferror(fp) || fclose(fp))
1693 errx(EXIT_FAILURE, _("error writing %s"), fullname);
1694 if (chmod(fullname, mflag) < 0)
1695 err(EXIT_FAILURE, _("cannot change mode of %s to %03o"),
1696 fullname, (unsigned)mflag);
1697 if ((uflag != (uid_t)-1 || gflag != (gid_t)-1)
1698 && chown(fullname, uflag, gflag) < 0)
1699 err(EXIT_FAILURE, _("cannot change ownership of %s"),
1700 fullname);
1701}
1702
1703static void
1540doabbr(abbr, format, letters, isdst)
1704doabbr(abbr, format, letters, isdst, doquotes)
1541char * const abbr;
1542const char * const format;
1543const char * const letters;
1544const int isdst;
1705char * const abbr;
1706const char * const format;
1707const char * const letters;
1708const int isdst;
1709const int doquotes;
1545{
1710{
1546 if (strchr(format, '/') == NULL) {
1711 register char * cp;
1712 register char * slashp;
1713 register int len;
1714
1715 slashp = strchr(format, '/');
1716 if (slashp == NULL) {
1547 if (letters == NULL)
1548 (void) strcpy(abbr, format);
1549 else (void) sprintf(abbr, format, letters);
1717 if (letters == NULL)
1718 (void) strcpy(abbr, format);
1719 else (void) sprintf(abbr, format, letters);
1550 } else if (isdst)
1551 (void) strcpy(abbr, strchr(format, '/') + 1);
1552 else {
1553 (void) strcpy(abbr, format);
1554 *strchr(abbr, '/') = '\0';
1720 } else if (isdst) {
1721 (void) strcpy(abbr, slashp + 1);
1722 } else {
1723 if (slashp > format)
1724 (void) strncpy(abbr, format,
1725 (unsigned) (slashp - format));
1726 abbr[slashp - format] = '\0';
1555 }
1727 }
1728 if (!doquotes)
1729 return;
1730 for (cp = abbr; *cp != '\0'; ++cp)
1731 if (strchr("ABCDEFGHIJKLMNOPQRSTUVWXYZ", *cp) == NULL &&
1732 strchr("abcdefghijklmnopqrstuvwxyz", *cp) == NULL)
1733 break;
1734 len = strlen(abbr);
1735 if (len > 0 && *cp == '\0')
1736 return;
1737 abbr[len + 2] = '\0';
1738 abbr[len + 1] = '>';
1739 for ( ; len > 0; --len)
1740 abbr[len] = abbr[len - 1];
1741 abbr[0] = '<';
1556}
1557
1558static void
1742}
1743
1744static void
1745updateminmax(x)
1746const int x;
1747{
1748 if (min_year > x)
1749 min_year = x;
1750 if (max_year < x)
1751 max_year = x;
1752}
1753
1754static int
1755stringoffset(result, offset)
1756char * result;
1757long offset;
1758{
1759 register int hours;
1760 register int minutes;
1761 register int seconds;
1762
1763 result[0] = '\0';
1764 if (offset < 0) {
1765 (void) strcpy(result, "-");
1766 offset = -offset;
1767 }
1768 seconds = offset % SECSPERMIN;
1769 offset /= SECSPERMIN;
1770 minutes = offset % MINSPERHOUR;
1771 offset /= MINSPERHOUR;
1772 hours = offset;
1773 if (hours >= HOURSPERDAY) {
1774 result[0] = '\0';
1775 return -1;
1776 }
1777 (void) sprintf(end(result), "%d", hours);
1778 if (minutes != 0 || seconds != 0) {
1779 (void) sprintf(end(result), ":%02d", minutes);
1780 if (seconds != 0)
1781 (void) sprintf(end(result), ":%02d", seconds);
1782 }
1783 return 0;
1784}
1785
1786static int
1787stringrule(result, rp, dstoff, gmtoff)
1788char * result;
1789const struct rule * const rp;
1790const long dstoff;
1791const long gmtoff;
1792{
1793 register long tod;
1794
1795 result = end(result);
1796 if (rp->r_dycode == DC_DOM) {
1797 register int month, total;
1798
1799 if (rp->r_dayofmonth == 29 && rp->r_month == TM_FEBRUARY)
1800 return -1;
1801 total = 0;
1802 for (month = 0; month < rp->r_month; ++month)
1803 total += len_months[0][month];
1804 (void) sprintf(result, "J%d", total + rp->r_dayofmonth);
1805 } else {
1806 register int week;
1807
1808 if (rp->r_dycode == DC_DOWGEQ) {
1809 week = 1 + rp->r_dayofmonth / DAYSPERWEEK;
1810 if ((week - 1) * DAYSPERWEEK + 1 != rp->r_dayofmonth)
1811 return -1;
1812 } else if (rp->r_dycode == DC_DOWLEQ) {
1813 if (rp->r_dayofmonth == len_months[1][rp->r_month])
1814 week = 5;
1815 else {
1816 week = 1 + rp->r_dayofmonth / DAYSPERWEEK;
1817 if (week * DAYSPERWEEK - 1 != rp->r_dayofmonth)
1818 return -1;
1819 }
1820 } else return -1; /* "cannot happen" */
1821 (void) sprintf(result, "M%d.%d.%d",
1822 rp->r_month + 1, week, rp->r_wday);
1823 }
1824 tod = rp->r_tod;
1825 if (rp->r_todisgmt)
1826 tod += gmtoff;
1827 if (rp->r_todisstd && rp->r_stdoff == 0)
1828 tod += dstoff;
1829 if (tod < 0) {
1830 result[0] = '\0';
1831 return -1;
1832 }
1833 if (tod != 2 * SECSPERMIN * MINSPERHOUR) {
1834 (void) strcat(result, "/");
1835 if (stringoffset(end(result), tod) != 0)
1836 return -1;
1837 }
1838 return 0;
1839}
1840
1841static void
1842stringzone(result, zpfirst, zonecount)
1843char * result;
1844const struct zone * const zpfirst;
1845const int zonecount;
1846{
1847 register const struct zone * zp;
1848 register struct rule * rp;
1849 register struct rule * stdrp;
1850 register struct rule * dstrp;
1851 register int i;
1852 register const char * abbrvar;
1853
1854 result[0] = '\0';
1855 zp = zpfirst + zonecount - 1;
1856 stdrp = dstrp = NULL;
1857 for (i = 0; i < zp->z_nrules; ++i) {
1858 rp = &zp->z_rules[i];
1859 if (rp->r_hiwasnum || rp->r_hiyear != INT_MAX)
1860 continue;
1861 if (rp->r_yrtype != NULL)
1862 continue;
1863 if (rp->r_stdoff == 0) {
1864 if (stdrp == NULL)
1865 stdrp = rp;
1866 else return;
1867 } else {
1868 if (dstrp == NULL)
1869 dstrp = rp;
1870 else return;
1871 }
1872 }
1873 if (stdrp == NULL && dstrp == NULL) {
1874 /*
1875 ** There are no rules running through "max".
1876 ** Let's find the latest rule.
1877 */
1878 for (i = 0; i < zp->z_nrules; ++i) {
1879 rp = &zp->z_rules[i];
1880 if (stdrp == NULL || rp->r_hiyear > stdrp->r_hiyear ||
1881 (rp->r_hiyear == stdrp->r_hiyear &&
1882 rp->r_month > stdrp->r_month))
1883 stdrp = rp;
1884 }
1885 if (stdrp != NULL && stdrp->r_stdoff != 0)
1886 return; /* We end up in DST (a POSIX no-no). */
1887 /*
1888 ** Horrid special case: if year is 2037,
1889 ** presume this is a zone handled on a year-by-year basis;
1890 ** do not try to apply a rule to the zone.
1891 */
1892 if (stdrp != NULL && stdrp->r_hiyear == 2037)
1893 return;
1894 }
1895 if (stdrp == NULL && zp->z_nrules != 0)
1896 return;
1897 abbrvar = (stdrp == NULL) ? "" : stdrp->r_abbrvar;
1898 doabbr(result, zp->z_format, abbrvar, FALSE, TRUE);
1899 if (stringoffset(end(result), -zp->z_gmtoff) != 0) {
1900 result[0] = '\0';
1901 return;
1902 }
1903 if (dstrp == NULL)
1904 return;
1905 doabbr(end(result), zp->z_format, dstrp->r_abbrvar, TRUE, TRUE);
1906 if (dstrp->r_stdoff != SECSPERMIN * MINSPERHOUR)
1907 if (stringoffset(end(result),
1908 -(zp->z_gmtoff + dstrp->r_stdoff)) != 0) {
1909 result[0] = '\0';
1910 return;
1911 }
1912 (void) strcat(result, ",");
1913 if (stringrule(result, dstrp, dstrp->r_stdoff, zp->z_gmtoff) != 0) {
1914 result[0] = '\0';
1915 return;
1916 }
1917 (void) strcat(result, ",");
1918 if (stringrule(result, stdrp, dstrp->r_stdoff, zp->z_gmtoff) != 0) {
1919 result[0] = '\0';
1920 return;
1921 }
1922}
1923
1924static void
1559outzone(zpfirst, zonecount)
1560const struct zone * const zpfirst;
1561const int zonecount;
1562{
1563 register const struct zone * zp;
1564 register struct rule * rp;
1565 register int i, j;
1566 register int usestart, useuntil;
1925outzone(zpfirst, zonecount)
1926const struct zone * const zpfirst;
1927const int zonecount;
1928{
1929 register const struct zone * zp;
1930 register struct rule * rp;
1931 register int i, j;
1932 register int usestart, useuntil;
1567 register time_t starttime, untiltime;
1933 register zic_t starttime, untiltime;
1568 register long gmtoff;
1569 register long stdoff;
1570 register int year;
1571 register long startoff;
1572 register int startttisstd;
1573 register int startttisgmt;
1574 register int type;
1934 register long gmtoff;
1935 register long stdoff;
1936 register int year;
1937 register long startoff;
1938 register int startttisstd;
1939 register int startttisgmt;
1940 register int type;
1575 char startbuf[BUFSIZ];
1941 register char * startbuf;
1942 register char * ab;
1943 register char * envvar;
1944 register int max_abbr_len;
1945 register int max_envvar_len;
1576
1946
1947 max_abbr_len = 2 + max_format_len + max_abbrvar_len;
1948 max_envvar_len = 2 * max_abbr_len + 5 * 9;
1949 startbuf = emalloc(max_abbr_len + 1);
1950 ab = emalloc(max_abbr_len + 1);
1951 envvar = emalloc(max_envvar_len + 1);
1577 INITIALIZE(untiltime);
1578 INITIALIZE(starttime);
1579 /*
1580 ** Now. . .finally. . .generate some useful data!
1581 */
1582 timecnt = 0;
1583 typecnt = 0;
1584 charcnt = 0;
1585 /*
1952 INITIALIZE(untiltime);
1953 INITIALIZE(starttime);
1954 /*
1955 ** Now. . .finally. . .generate some useful data!
1956 */
1957 timecnt = 0;
1958 typecnt = 0;
1959 charcnt = 0;
1960 /*
1586 ** Thanks to Earl Chew (earl@dnd.icp.nec.com.au)
1961 ** Thanks to Earl Chew
1587 ** for noting the need to unconditionally initialize startttisstd.
1588 */
1589 startttisstd = FALSE;
1590 startttisgmt = FALSE;
1962 ** for noting the need to unconditionally initialize startttisstd.
1963 */
1964 startttisstd = FALSE;
1965 startttisgmt = FALSE;
1966 min_year = max_year = EPOCH_YEAR;
1967 if (leapseen) {
1968 updateminmax(leapminyear);
1969 updateminmax(leapmaxyear + (leapmaxyear < INT_MAX));
1970 }
1591 for (i = 0; i < zonecount; ++i) {
1971 for (i = 0; i < zonecount; ++i) {
1972 zp = &zpfirst[i];
1973 if (i < zonecount - 1)
1974 updateminmax(zp->z_untilrule.r_loyear);
1975 for (j = 0; j < zp->z_nrules; ++j) {
1976 rp = &zp->z_rules[j];
1977 if (rp->r_lowasnum)
1978 updateminmax(rp->r_loyear);
1979 if (rp->r_hiwasnum)
1980 updateminmax(rp->r_hiyear);
1981 }
1982 }
1983 /*
1984 ** Generate lots of data if a rule can't cover all future times.
1985 */
1986 stringzone(envvar, zpfirst, zonecount);
1987 if (noise && envvar[0] == '\0') {
1988 register char * wp;
1989
1990wp = ecpyalloc(_("no POSIX environment variable for zone"));
1991 wp = ecatalloc(wp, " ");
1992 wp = ecatalloc(wp, zpfirst->z_name);
1993 warning(wp);
1994 ifree(wp);
1995 }
1996 if (envvar[0] == '\0') {
1997 if (min_year >= INT_MIN + YEARSPERREPEAT)
1998 min_year -= YEARSPERREPEAT;
1999 else min_year = INT_MIN;
2000 if (max_year <= INT_MAX - YEARSPERREPEAT)
2001 max_year += YEARSPERREPEAT;
2002 else max_year = INT_MAX;
2003 }
2004 /*
2005 ** For the benefit of older systems,
2006 ** generate data from 1900 through 2037.
2007 */
2008 if (min_year > 1900)
2009 min_year = 1900;
2010 if (max_year < 2037)
2011 max_year = 2037;
2012 for (i = 0; i < zonecount; ++i) {
1592 /*
1593 ** A guess that may well be corrected later.
1594 */
1595 stdoff = 0;
1596 zp = &zpfirst[i];
1597 usestart = i > 0 && (zp - 1)->z_untiltime > min_time;
1598 useuntil = i < (zonecount - 1);
1599 if (useuntil && zp->z_untiltime <= min_time)
1600 continue;
1601 gmtoff = zp->z_gmtoff;
1602 eat(zp->z_filename, zp->z_linenum);
1603 *startbuf = '\0';
1604 startoff = zp->z_gmtoff;
1605 if (zp->z_nrules == 0) {
1606 stdoff = zp->z_stdoff;
1607 doabbr(startbuf, zp->z_format,
2013 /*
2014 ** A guess that may well be corrected later.
2015 */
2016 stdoff = 0;
2017 zp = &zpfirst[i];
2018 usestart = i > 0 && (zp - 1)->z_untiltime > min_time;
2019 useuntil = i < (zonecount - 1);
2020 if (useuntil && zp->z_untiltime <= min_time)
2021 continue;
2022 gmtoff = zp->z_gmtoff;
2023 eat(zp->z_filename, zp->z_linenum);
2024 *startbuf = '\0';
2025 startoff = zp->z_gmtoff;
2026 if (zp->z_nrules == 0) {
2027 stdoff = zp->z_stdoff;
2028 doabbr(startbuf, zp->z_format,
1608 (char *) NULL, stdoff != 0);
2029 (char *) NULL, stdoff != 0, FALSE);
1609 type = addtype(oadd(zp->z_gmtoff, stdoff),
1610 startbuf, stdoff != 0, startttisstd,
1611 startttisgmt);
1612 if (usestart) {
1613 addtt(starttime, type);
1614 usestart = FALSE;
1615 } else if (stdoff != 0)
1616 addtt(min_time, type);

--- 11 unchanged lines hidden (view full) ---

1628 rp->r_todo = year >= rp->r_loyear &&
1629 year <= rp->r_hiyear &&
1630 yearistype(year, rp->r_yrtype);
1631 if (rp->r_todo)
1632 rp->r_temp = rpytime(rp, year);
1633 }
1634 for ( ; ; ) {
1635 register int k;
2030 type = addtype(oadd(zp->z_gmtoff, stdoff),
2031 startbuf, stdoff != 0, startttisstd,
2032 startttisgmt);
2033 if (usestart) {
2034 addtt(starttime, type);
2035 usestart = FALSE;
2036 } else if (stdoff != 0)
2037 addtt(min_time, type);

--- 11 unchanged lines hidden (view full) ---

2049 rp->r_todo = year >= rp->r_loyear &&
2050 year <= rp->r_hiyear &&
2051 yearistype(year, rp->r_yrtype);
2052 if (rp->r_todo)
2053 rp->r_temp = rpytime(rp, year);
2054 }
2055 for ( ; ; ) {
2056 register int k;
1636 register time_t jtime, ktime;
2057 register zic_t jtime, ktime;
1637 register long offset;
2058 register long offset;
1638 char buf[BUFSIZ];
1639
1640 INITIALIZE(ktime);
1641 if (useuntil) {
1642 /*
1643 ** Turn untiltime into UTC
1644 ** assuming the current gmtoff and
1645 ** stdoff values.
1646 */

--- 39 unchanged lines hidden (view full) ---

1686 if (usestart && ktime == starttime)
1687 usestart = FALSE;
1688 if (usestart) {
1689 if (ktime < starttime) {
1690 startoff = oadd(zp->z_gmtoff,
1691 stdoff);
1692 doabbr(startbuf, zp->z_format,
1693 rp->r_abbrvar,
2059
2060 INITIALIZE(ktime);
2061 if (useuntil) {
2062 /*
2063 ** Turn untiltime into UTC
2064 ** assuming the current gmtoff and
2065 ** stdoff values.
2066 */

--- 39 unchanged lines hidden (view full) ---

2106 if (usestart && ktime == starttime)
2107 usestart = FALSE;
2108 if (usestart) {
2109 if (ktime < starttime) {
2110 startoff = oadd(zp->z_gmtoff,
2111 stdoff);
2112 doabbr(startbuf, zp->z_format,
2113 rp->r_abbrvar,
1694 rp->r_stdoff != 0);
2114 rp->r_stdoff != 0,
2115 FALSE);
1695 continue;
1696 }
1697 if (*startbuf == '\0' &&
2116 continue;
2117 }
2118 if (*startbuf == '\0' &&
1698 startoff == oadd(zp->z_gmtoff,
1699 stdoff)) {
1700 doabbr(startbuf, zp->z_format,
1701 rp->r_abbrvar,
1702 rp->r_stdoff != 0);
2119 startoff == oadd(zp->z_gmtoff,
2120 stdoff)) {
2121 doabbr(startbuf,
2122 zp->z_format,
2123 rp->r_abbrvar,
2124 rp->r_stdoff !=
2125 0,
2126 FALSE);
1703 }
1704 }
1705 eats(zp->z_filename, zp->z_linenum,
1706 rp->r_filename, rp->r_linenum);
2127 }
2128 }
2129 eats(zp->z_filename, zp->z_linenum,
2130 rp->r_filename, rp->r_linenum);
1707 doabbr(buf, zp->z_format, rp->r_abbrvar,
1708 rp->r_stdoff != 0);
2131 doabbr(ab, zp->z_format, rp->r_abbrvar,
2132 rp->r_stdoff != 0, FALSE);
1709 offset = oadd(zp->z_gmtoff, rp->r_stdoff);
2133 offset = oadd(zp->z_gmtoff, rp->r_stdoff);
1710 type = addtype(offset, buf, rp->r_stdoff != 0,
2134 type = addtype(offset, ab, rp->r_stdoff != 0,
1711 rp->r_todisstd, rp->r_todisgmt);
1712 addtt(ktime, type);
1713 }
1714 }
1715 if (usestart) {
1716 if (*startbuf == '\0' &&
1717 zp->z_format != NULL &&
1718 strchr(zp->z_format, '%') == NULL &&

--- 16 unchanged lines hidden (view full) ---

1735 startttisgmt = zp->z_untilrule.r_todisgmt;
1736 starttime = zp->z_untiltime;
1737 if (!startttisstd)
1738 starttime = tadd(starttime, -stdoff);
1739 if (!startttisgmt)
1740 starttime = tadd(starttime, -gmtoff);
1741 }
1742 }
2135 rp->r_todisstd, rp->r_todisgmt);
2136 addtt(ktime, type);
2137 }
2138 }
2139 if (usestart) {
2140 if (*startbuf == '\0' &&
2141 zp->z_format != NULL &&
2142 strchr(zp->z_format, '%') == NULL &&

--- 16 unchanged lines hidden (view full) ---

2159 startttisgmt = zp->z_untilrule.r_todisgmt;
2160 starttime = zp->z_untiltime;
2161 if (!startttisstd)
2162 starttime = tadd(starttime, -stdoff);
2163 if (!startttisgmt)
2164 starttime = tadd(starttime, -gmtoff);
2165 }
2166 }
1743 writezone(zpfirst->z_name);
2167 writezone(zpfirst->z_name, envvar);
2168 ifree(startbuf);
2169 ifree(ab);
2170 ifree(envvar);
1744}
1745
1746static void
1747addtt(starttime, type)
2171}
2172
2173static void
2174addtt(starttime, type)
1748const time_t starttime;
2175const zic_t starttime;
1749int type;
1750{
1751 if (starttime <= min_time ||
1752 (timecnt == 1 && attypes[0].at < min_time)) {
1753 gmtoffs[0] = gmtoffs[type];
1754 isdsts[0] = isdsts[type];
1755 ttisstds[0] = ttisstds[type];
1756 ttisgmts[0] = ttisgmts[type];
1757 if (abbrinds[type] != 0)
1758 (void) strcpy(chars, &chars[abbrinds[type]]);
1759 abbrinds[0] = 0;
1760 charcnt = strlen(chars) + 1;
1761 typecnt = 1;
1762 timecnt = 0;
1763 type = 0;
1764 }
1765 if (timecnt >= TZ_MAX_TIMES) {
1766 error(_("too many transitions?!"));
2176int type;
2177{
2178 if (starttime <= min_time ||
2179 (timecnt == 1 && attypes[0].at < min_time)) {
2180 gmtoffs[0] = gmtoffs[type];
2181 isdsts[0] = isdsts[type];
2182 ttisstds[0] = ttisstds[type];
2183 ttisgmts[0] = ttisgmts[type];
2184 if (abbrinds[type] != 0)
2185 (void) strcpy(chars, &chars[abbrinds[type]]);
2186 abbrinds[0] = 0;
2187 charcnt = strlen(chars) + 1;
2188 typecnt = 1;
2189 timecnt = 0;
2190 type = 0;
2191 }
2192 if (timecnt >= TZ_MAX_TIMES) {
2193 error(_("too many transitions?!"));
1767 (void) exit(EXIT_FAILURE);
2194 exit(EXIT_FAILURE);
1768 }
1769 attypes[timecnt].at = starttime;
1770 attypes[timecnt].type = type;
1771 ++timecnt;
1772}
1773
1774static int
1775addtype(gmtoff, abbr, isdst, ttisstd, ttisgmt)
1776const long gmtoff;
1777const char * const abbr;
1778const int isdst;
1779const int ttisstd;
1780const int ttisgmt;
1781{
1782 register int i, j;
1783
1784 if (isdst != TRUE && isdst != FALSE) {
1785 error(_("internal error - addtype called with bad isdst"));
2195 }
2196 attypes[timecnt].at = starttime;
2197 attypes[timecnt].type = type;
2198 ++timecnt;
2199}
2200
2201static int
2202addtype(gmtoff, abbr, isdst, ttisstd, ttisgmt)
2203const long gmtoff;
2204const char * const abbr;
2205const int isdst;
2206const int ttisstd;
2207const int ttisgmt;
2208{
2209 register int i, j;
2210
2211 if (isdst != TRUE && isdst != FALSE) {
2212 error(_("internal error - addtype called with bad isdst"));
1786 (void) exit(EXIT_FAILURE);
2213 exit(EXIT_FAILURE);
1787 }
1788 if (ttisstd != TRUE && ttisstd != FALSE) {
1789 error(_("internal error - addtype called with bad ttisstd"));
2214 }
2215 if (ttisstd != TRUE && ttisstd != FALSE) {
2216 error(_("internal error - addtype called with bad ttisstd"));
1790 (void) exit(EXIT_FAILURE);
2217 exit(EXIT_FAILURE);
1791 }
1792 if (ttisgmt != TRUE && ttisgmt != FALSE) {
1793 error(_("internal error - addtype called with bad ttisgmt"));
2218 }
2219 if (ttisgmt != TRUE && ttisgmt != FALSE) {
2220 error(_("internal error - addtype called with bad ttisgmt"));
1794 (void) exit(EXIT_FAILURE);
2221 exit(EXIT_FAILURE);
1795 }
1796 /*
1797 ** See if there's already an entry for this zone type.
1798 ** If so, just return its index.
1799 */
1800 for (i = 0; i < typecnt; ++i) {
1801 if (gmtoff == gmtoffs[i] && isdst == isdsts[i] &&
1802 strcmp(abbr, &chars[abbrinds[i]]) == 0 &&
1803 ttisstd == ttisstds[i] &&
1804 ttisgmt == ttisgmts[i])
1805 return i;
1806 }
1807 /*
1808 ** There isn't one; add a new one, unless there are already too
1809 ** many.
1810 */
1811 if (typecnt >= TZ_MAX_TYPES) {
1812 error(_("too many local time types"));
2222 }
2223 /*
2224 ** See if there's already an entry for this zone type.
2225 ** If so, just return its index.
2226 */
2227 for (i = 0; i < typecnt; ++i) {
2228 if (gmtoff == gmtoffs[i] && isdst == isdsts[i] &&
2229 strcmp(abbr, &chars[abbrinds[i]]) == 0 &&
2230 ttisstd == ttisstds[i] &&
2231 ttisgmt == ttisgmts[i])
2232 return i;
2233 }
2234 /*
2235 ** There isn't one; add a new one, unless there are already too
2236 ** many.
2237 */
2238 if (typecnt >= TZ_MAX_TYPES) {
2239 error(_("too many local time types"));
1813 (void) exit(EXIT_FAILURE);
2240 exit(EXIT_FAILURE);
1814 }
2241 }
2242 if (! (-1L - 2147483647L <= gmtoff && gmtoff <= 2147483647L)) {
2243 error(_("UTC offset out of range"));
2244 exit(EXIT_FAILURE);
2245 }
1815 gmtoffs[i] = gmtoff;
1816 isdsts[i] = isdst;
1817 ttisstds[i] = ttisstd;
1818 ttisgmts[i] = ttisgmt;
1819
1820 for (j = 0; j < charcnt; ++j)
1821 if (strcmp(&chars[j], abbr) == 0)
1822 break;
1823 if (j == charcnt)
1824 newabbr(abbr);
1825 abbrinds[i] = j;
1826 ++typecnt;
1827 return i;
1828}
1829
1830static void
1831leapadd(t, positive, rolling, count)
2246 gmtoffs[i] = gmtoff;
2247 isdsts[i] = isdst;
2248 ttisstds[i] = ttisstd;
2249 ttisgmts[i] = ttisgmt;
2250
2251 for (j = 0; j < charcnt; ++j)
2252 if (strcmp(&chars[j], abbr) == 0)
2253 break;
2254 if (j == charcnt)
2255 newabbr(abbr);
2256 abbrinds[i] = j;
2257 ++typecnt;
2258 return i;
2259}
2260
2261static void
2262leapadd(t, positive, rolling, count)
1832const time_t t;
2263const zic_t t;
1833const int positive;
1834const int rolling;
1835int count;
1836{
1837 register int i, j;
1838
1839 if (leapcnt + (positive ? count : 1) > TZ_MAX_LEAPS) {
1840 error(_("too many leap seconds"));
2264const int positive;
2265const int rolling;
2266int count;
2267{
2268 register int i, j;
2269
2270 if (leapcnt + (positive ? count : 1) > TZ_MAX_LEAPS) {
2271 error(_("too many leap seconds"));
1841 (void) exit(EXIT_FAILURE);
2272 exit(EXIT_FAILURE);
1842 }
1843 for (i = 0; i < leapcnt; ++i)
1844 if (t <= trans[i]) {
1845 if (t == trans[i]) {
1846 error(_("repeated leap second moment"));
2273 }
2274 for (i = 0; i < leapcnt; ++i)
2275 if (t <= trans[i]) {
2276 if (t == trans[i]) {
2277 error(_("repeated leap second moment"));
1847 (void) exit(EXIT_FAILURE);
2278 exit(EXIT_FAILURE);
1848 }
1849 break;
1850 }
1851 do {
1852 for (j = leapcnt; j > i; --j) {
1853 trans[j] = trans[j - 1];
1854 corr[j] = corr[j - 1];
1855 roll[j] = roll[j - 1];
1856 }
1857 trans[i] = t;
1858 corr[i] = positive ? 1L : eitol(-count);
1859 roll[i] = rolling;
1860 ++leapcnt;
1861 } while (positive && --count != 0);
1862}
1863
1864static void
2279 }
2280 break;
2281 }
2282 do {
2283 for (j = leapcnt; j > i; --j) {
2284 trans[j] = trans[j - 1];
2285 corr[j] = corr[j - 1];
2286 roll[j] = roll[j - 1];
2287 }
2288 trans[i] = t;
2289 corr[i] = positive ? 1L : eitol(-count);
2290 roll[i] = rolling;
2291 ++leapcnt;
2292 } while (positive && --count != 0);
2293}
2294
2295static void
1865adjleap P((void))
2296adjleap(void)
1866{
1867 register int i;
1868 register long last = 0;
1869
1870 /*
1871 ** propagate leap seconds forward
1872 */
1873 for (i = 0; i < leapcnt; ++i) {

--- 19 unchanged lines hidden (view full) ---

1893 case 0:
1894 return TRUE;
1895 case 1:
1896 return FALSE;
1897 }
1898 error(_("wild result from command execution"));
1899 warnx(_("command was '%s', result was %d"), buf, result);
1900 for ( ; ; )
2297{
2298 register int i;
2299 register long last = 0;
2300
2301 /*
2302 ** propagate leap seconds forward
2303 */
2304 for (i = 0; i < leapcnt; ++i) {

--- 19 unchanged lines hidden (view full) ---

2324 case 0:
2325 return TRUE;
2326 case 1:
2327 return FALSE;
2328 }
2329 error(_("wild result from command execution"));
2330 warnx(_("command was '%s', result was %d"), buf, result);
2331 for ( ; ; )
1901 (void) exit(EXIT_FAILURE);
2332 exit(EXIT_FAILURE);
1902}
1903
1904static int
1905lowerit(a)
1906int a;
1907{
1908 a = (unsigned char) a;
1909 return (isascii(a) && isupper(a)) ? tolower(a) : a;

--- 64 unchanged lines hidden (view full) ---

1974 register int nsubs;
1975
1976 if (cp == NULL)
1977 return NULL;
1978 array = (char **) (void *)
1979 emalloc((int) ((strlen(cp) + 1) * sizeof *array));
1980 nsubs = 0;
1981 for ( ; ; ) {
2333}
2334
2335static int
2336lowerit(a)
2337int a;
2338{
2339 a = (unsigned char) a;
2340 return (isascii(a) && isupper(a)) ? tolower(a) : a;

--- 64 unchanged lines hidden (view full) ---

2405 register int nsubs;
2406
2407 if (cp == NULL)
2408 return NULL;
2409 array = (char **) (void *)
2410 emalloc((int) ((strlen(cp) + 1) * sizeof *array));
2411 nsubs = 0;
2412 for ( ; ; ) {
1982 while (isascii(*cp) && isspace((unsigned char) *cp))
1983 ++cp;
2413 while (isascii((unsigned char) *cp) &&
2414 isspace((unsigned char) *cp))
2415 ++cp;
1984 if (*cp == '\0' || *cp == '#')
1985 break;
1986 array[nsubs++] = dp = cp;
1987 do {
1988 if ((*dp = *cp++) != '"')
1989 ++dp;
1990 else while ((*dp = *cp++) != '"')
1991 if (*dp != '\0')

--- 17 unchanged lines hidden (view full) ---

2009const long t1;
2010const long t2;
2011{
2012 register long t;
2013
2014 t = t1 + t2;
2015 if ((t2 > 0 && t <= t1) || (t2 < 0 && t >= t1)) {
2016 error(_("time overflow"));
2416 if (*cp == '\0' || *cp == '#')
2417 break;
2418 array[nsubs++] = dp = cp;
2419 do {
2420 if ((*dp = *cp++) != '"')
2421 ++dp;
2422 else while ((*dp = *cp++) != '"')
2423 if (*dp != '\0')

--- 17 unchanged lines hidden (view full) ---

2441const long t1;
2442const long t2;
2443{
2444 register long t;
2445
2446 t = t1 + t2;
2447 if ((t2 > 0 && t <= t1) || (t2 < 0 && t >= t1)) {
2448 error(_("time overflow"));
2017 (void) exit(EXIT_FAILURE);
2449 exit(EXIT_FAILURE);
2018 }
2019 return t;
2020}
2021
2450 }
2451 return t;
2452}
2453
2022static time_t
2454static zic_t
2023tadd(t1, t2)
2455tadd(t1, t2)
2024const time_t t1;
2456const zic_t t1;
2025const long t2;
2026{
2457const long t2;
2458{
2027 register time_t t;
2459 register zic_t t;
2028
2029 if (t1 == max_time && t2 > 0)
2030 return max_time;
2031 if (t1 == min_time && t2 < 0)
2032 return min_time;
2033 t = t1 + t2;
2034 if ((t2 > 0 && t <= t1) || (t2 < 0 && t >= t1)) {
2035 error(_("time overflow"));
2460
2461 if (t1 == max_time && t2 > 0)
2462 return max_time;
2463 if (t1 == min_time && t2 < 0)
2464 return min_time;
2465 t = t1 + t2;
2466 if ((t2 > 0 && t <= t1) || (t2 < 0 && t >= t1)) {
2467 error(_("time overflow"));
2036 (void) exit(EXIT_FAILURE);
2468 exit(EXIT_FAILURE);
2037 }
2038 return t;
2039}
2040
2041/*
2042** Given a rule, and a year, compute the date - in seconds since January 1,
2043** 1970, 00:00 LOCAL time - in that year that the rule refers to.
2044*/
2045
2469 }
2470 return t;
2471}
2472
2473/*
2474** Given a rule, and a year, compute the date - in seconds since January 1,
2475** 1970, 00:00 LOCAL time - in that year that the rule refers to.
2476*/
2477
2046static time_t
2478static zic_t
2047rpytime(rp, wantedy)
2048register const struct rule * const rp;
2049register const int wantedy;
2050{
2051 register int y, m, i;
2052 register long dayoff; /* with a nod to Margaret O. */
2479rpytime(rp, wantedy)
2480register const struct rule * const rp;
2481register const int wantedy;
2482{
2483 register int y, m, i;
2484 register long dayoff; /* with a nod to Margaret O. */
2053 register time_t t;
2485 register zic_t t;
2054
2055 if (wantedy == INT_MIN)
2056 return min_time;
2057 if (wantedy == INT_MAX)
2058 return max_time;
2059 dayoff = 0;
2060 m = TM_JANUARY;
2061 y = EPOCH_YEAR;

--- 13 unchanged lines hidden (view full) ---

2075 ++m;
2076 }
2077 i = rp->r_dayofmonth;
2078 if (m == TM_FEBRUARY && i == 29 && !isleap(y)) {
2079 if (rp->r_dycode == DC_DOWLEQ)
2080 --i;
2081 else {
2082 error(_("use of 2/29 in non leap-year"));
2486
2487 if (wantedy == INT_MIN)
2488 return min_time;
2489 if (wantedy == INT_MAX)
2490 return max_time;
2491 dayoff = 0;
2492 m = TM_JANUARY;
2493 y = EPOCH_YEAR;

--- 13 unchanged lines hidden (view full) ---

2507 ++m;
2508 }
2509 i = rp->r_dayofmonth;
2510 if (m == TM_FEBRUARY && i == 29 && !isleap(y)) {
2511 if (rp->r_dycode == DC_DOWLEQ)
2512 --i;
2513 else {
2514 error(_("use of 2/29 in non leap-year"));
2083 (void) exit(EXIT_FAILURE);
2515 exit(EXIT_FAILURE);
2084 }
2085 }
2086 --i;
2087 dayoff = oadd(dayoff, eitol(i));
2088 if (rp->r_dycode == DC_DOWGEQ || rp->r_dycode == DC_DOWLEQ) {
2089 register long wday;
2090
2091#define LDAYSPERWEEK ((long) DAYSPERWEEK)

--- 17 unchanged lines hidden (view full) ---

2109 } else {
2110 dayoff = oadd(dayoff, (long) -1);
2111 if (--wday < 0)
2112 wday = LDAYSPERWEEK - 1;
2113 --i;
2114 }
2115 if (i < 0 || i >= len_months[isleap(y)][m]) {
2116 if (noise)
2516 }
2517 }
2518 --i;
2519 dayoff = oadd(dayoff, eitol(i));
2520 if (rp->r_dycode == DC_DOWGEQ || rp->r_dycode == DC_DOWLEQ) {
2521 register long wday;
2522
2523#define LDAYSPERWEEK ((long) DAYSPERWEEK)

--- 17 unchanged lines hidden (view full) ---

2541 } else {
2542 dayoff = oadd(dayoff, (long) -1);
2543 if (--wday < 0)
2544 wday = LDAYSPERWEEK - 1;
2545 --i;
2546 }
2547 if (i < 0 || i >= len_months[isleap(y)][m]) {
2548 if (noise)
2117 warning(_("rule goes past start/end of month--will not work with pre-2004 versions of zic"));
2549 warning(_("rule goes past start/end of month--\
2550will not work with pre-2004 versions of zic"));
2118 }
2119 }
2551 }
2552 }
2120 if (dayoff < 0 && !TYPE_SIGNED(time_t))
2121 return min_time;
2122 if (dayoff < min_time / SECSPERDAY)
2123 return min_time;
2124 if (dayoff > max_time / SECSPERDAY)
2125 return max_time;
2553 if (dayoff < min_time / SECSPERDAY)
2554 return min_time;
2555 if (dayoff > max_time / SECSPERDAY)
2556 return max_time;
2126 t = (time_t) dayoff * SECSPERDAY;
2557 t = (zic_t) dayoff * SECSPERDAY;
2127 return tadd(t, rp->r_tod);
2128}
2129
2130static void
2131newabbr(string)
2132const char * const string;
2133{
2134 register int i;
2135
2558 return tadd(t, rp->r_tod);
2559}
2560
2561static void
2562newabbr(string)
2563const char * const string;
2564{
2565 register int i;
2566
2567 if (strcmp(string, GRANDPARENTED) != 0) {
2568 register const char * cp;
2569 register char * wp;
2570
2571 /*
2572 ** Want one to ZIC_MAX_ABBR_LEN_WO_WARN alphabetics
2573 ** optionally followed by a + or - and a number from 1 to 14.
2574 */
2575 cp = string;
2576 wp = NULL;
2577 while (isascii((unsigned char) *cp) &&
2578 isalpha((unsigned char) *cp))
2579 ++cp;
2580 if (cp - string == 0)
2581wp = _("time zone abbreviation lacks alphabetic at start");
2582 if (noise && cp - string > 3)
2583wp = _("time zone abbreviation has more than 3 alphabetics");
2584 if (cp - string > ZIC_MAX_ABBR_LEN_WO_WARN)
2585wp = _("time zone abbreviation has too many alphabetics");
2586 if (wp == NULL && (*cp == '+' || *cp == '-')) {
2587 ++cp;
2588 if (isascii((unsigned char) *cp) &&
2589 isdigit((unsigned char) *cp))
2590 if (*cp++ == '1' &&
2591 *cp >= '0' && *cp <= '4')
2592 ++cp;
2593 }
2594 if (*cp != '\0')
2595wp = _("time zone abbreviation differs from POSIX standard");
2596 if (wp != NULL) {
2597 wp = ecpyalloc(wp);
2598 wp = ecatalloc(wp, " (");
2599 wp = ecatalloc(wp, string);
2600 wp = ecatalloc(wp, ")");
2601 warning(wp);
2602 ifree(wp);
2603 }
2604 }
2136 i = strlen(string) + 1;
2137 if (charcnt + i > TZ_MAX_CHARS) {
2138 error(_("too many, or too long, time zone abbreviations"));
2605 i = strlen(string) + 1;
2606 if (charcnt + i > TZ_MAX_CHARS) {
2607 error(_("too many, or too long, time zone abbreviations"));
2139 (void) exit(EXIT_FAILURE);
2608 exit(EXIT_FAILURE);
2140 }
2141 (void) strcpy(&chars[charcnt], string);
2142 charcnt += eitol(i);
2143}
2144
2145static int
2146mkdirs(argname)
2609 }
2610 (void) strcpy(&chars[charcnt], string);
2611 charcnt += eitol(i);
2612}
2613
2614static int
2615mkdirs(argname)
2147char * const argname;
2616char * argname;
2148{
2149 register char * name;
2150 register char * cp;
2151
2152 if (argname == NULL || *argname == '\0' || Dflag)
2153 return 0;
2154 cp = name = ecpyalloc(argname);
2155 while ((cp = strchr(cp + 1, '/')) != 0) {

--- 99 unchanged lines hidden ---
2617{
2618 register char * name;
2619 register char * cp;
2620
2621 if (argname == NULL || *argname == '\0' || Dflag)
2622 return 0;
2623 cp = name = ecpyalloc(argname);
2624 while ((cp = strchr(cp + 1, '/')) != 0) {

--- 99 unchanged lines hidden ---