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 --- |