diff options
Diffstat (limited to 'usr.sbin/zic/zic.c')
-rw-r--r-- | usr.sbin/zic/zic.c | 508 |
1 files changed, 176 insertions, 332 deletions
diff --git a/usr.sbin/zic/zic.c b/usr.sbin/zic/zic.c index 0cec893..3959039 100644 --- a/usr.sbin/zic/zic.c +++ b/usr.sbin/zic/zic.c @@ -1,28 +1,14 @@ #ifndef lint #ifndef NOID -static char elsieid[] = "@(#)zic.c 7.77"; +static char elsieid[] = "@(#)zic.c 7.50"; #endif /* !defined NOID */ #endif /* !defined lint */ #include "private.h" -#include "locale.h" #include "tzfile.h" -#ifdef unix -#include "sys/stat.h" /* for umask manifest constants */ -#endif /* defined unix */ - -/* -** On some ancient hosts, predicates like `isspace(C)' are defined -** only if isascii(C) || C == EOF. Modern hosts obey the C Standard, -** which says they are defined only if C == ((unsigned char) C) || C == EOF. -** Neither the C Standard nor Posix require that `isascii' exist. -** For portability, we check both ancient and modern requirements. -** If isascii is not defined, the isascii check succeeds trivially. -*/ -#include "ctype.h" -#ifndef isascii -#define isascii(x) 1 -#endif +#include <sys/stat.h> /* for umask manifest constants */ +#include <sys/types.h> +#include <unistd.h> struct rule { const char * r_filename; @@ -136,17 +122,15 @@ static void usage P((void)); static void writezone P((const char * name)); static int yearistype P((int year, const char * type)); -#if !HAVE_STRERROR -static char * strerror P((int)); -#endif /* !HAVE_STRERROR */ - static int charcnt; static int errors; static const char * filename; static int leapcnt; static int linenum; +static int max_int; static time_t max_time; static int max_year; +static int min_int; static time_t min_time; static int min_year; static int noise; @@ -155,6 +139,7 @@ static int rlinenum; static const char * progname; static int timecnt; static int typecnt; +static int tt_signed; /* ** Line codes. @@ -335,10 +320,8 @@ static const int len_years[2] = { DAYSPERNYEAR, DAYSPERLYEAR }; -static struct attype { - time_t at; - unsigned char type; -} attypes[TZ_MAX_TIMES]; +static time_t ats[TZ_MAX_TIMES]; +static unsigned char types[TZ_MAX_TIMES]; static long gmtoffs[TZ_MAX_TYPES]; static char isdsts[TZ_MAX_TYPES]; static unsigned char abbrinds[TZ_MAX_TYPES]; @@ -358,9 +341,7 @@ memcheck(ptr) char * const ptr; { if (ptr == NULL) { - const char *e = strerror(errno); - (void) fprintf(stderr, _("%s: Memory exhausted: %s\n"), - progname, e); + (void) perror(progname); (void) exit(EXIT_FAILURE); } return ptr; @@ -375,20 +356,6 @@ char * const ptr; ** Error handling. */ -#if ! HAVE_STRERROR -static char * -strerror(errnum) -int errnum; -{ - extern char *sys_errlist[]; - extern int sys_nerr; - - if (errnum > 0 && errnum <= sys_nerr) - return sys_errlist[errnum]; - return "Unknown system error"; -} -#endif /* ! HAVE_STRERROR */ - static void eats(name, num, rname, rnum) const char * const name; @@ -419,32 +386,21 @@ const char * const string; ** zic ... 2>&1 | error -t "*" -v ** on BSD systems. */ - (void) fprintf(stderr, _("\"%s\", line %d: %s"), + (void) fprintf(stderr, "\"%s\", line %d: %s", filename, linenum, string); if (rfilename != NULL) - (void) fprintf(stderr, _(" (rule from \"%s\", line %d)"), + (void) fprintf(stderr, " (rule from \"%s\", line %d)", rfilename, rlinenum); (void) fprintf(stderr, "\n"); ++errors; } static void -warning(string) -const char * const string; -{ - char * cp; - - cp = ecpyalloc("warning: "); - cp = ecatalloc(cp, string); - error(string); - ifree(cp); - --errors; -} - -static void usage P((void)) { - (void) fprintf(stderr, _("%s: usage is %s [ -s ] [ -v ] [ -l localtime ] [ -p posixrules ] [ -d directory ]\n\t[ -L leapseconds ] [ -y yearistype ] [ filename ... ]\n"), + (void) fprintf(stderr, "%s: usage is %s \ +[ -s ] [ -v ] [ -l localtime ] [ -p posixrules ] [ -d directory ]\n\ +\t[ -L leapseconds ] [ -y yearistype ] [ filename ... ]\n", progname, progname); (void) exit(EXIT_FAILURE); } @@ -468,13 +424,6 @@ char * argv[]; #ifdef unix (void) umask(umask(S_IWGRP | S_IWOTH) | (S_IWGRP | S_IWOTH)); #endif /* defined unix */ -#if HAVE_GETTEXT - 0 - (void) setlocale(LC_MESSAGES, ""); -#ifdef TZ_DOMAINDIR - (void) bindtextdomain(TZ_DOMAIN, TZ_DOMAINDIR); -#endif /* defined TEXTDOMAINDIR */ - (void) textdomain(TZ_DOMAIN); -#endif /* HAVE_GETTEXT - 0 */ progname = argv[0]; while ((c = getopt(argc, argv, "d:l:p:L:vsy:")) != EOF) switch (c) { @@ -485,7 +434,7 @@ char * argv[]; directory = optarg; else { (void) fprintf(stderr, -_("%s: More than one -d option specified\n"), +"%s: More than one -d option specified\n", progname); (void) exit(EXIT_FAILURE); } @@ -495,7 +444,7 @@ _("%s: More than one -d option specified\n"), lcltime = optarg; else { (void) fprintf(stderr, -_("%s: More than one -l option specified\n"), +"%s: More than one -l option specified\n", progname); (void) exit(EXIT_FAILURE); } @@ -505,7 +454,7 @@ _("%s: More than one -l option specified\n"), psxrules = optarg; else { (void) fprintf(stderr, -_("%s: More than one -p option specified\n"), +"%s: More than one -p option specified\n", progname); (void) exit(EXIT_FAILURE); } @@ -515,7 +464,7 @@ _("%s: More than one -p option specified\n"), yitcommand = optarg; else { (void) fprintf(stderr, -_("%s: More than one -y option specified\n"), +"%s: More than one -y option specified\n", progname); (void) exit(EXIT_FAILURE); } @@ -525,7 +474,7 @@ _("%s: More than one -y option specified\n"), leapsec = optarg; else { (void) fprintf(stderr, -_("%s: More than one -L option specified\n"), +"%s: More than one -L option specified\n", progname); (void) exit(EXIT_FAILURE); } @@ -608,10 +557,9 @@ const char * const tofile; if (mkdirs(toname) != 0) (void) exit(EXIT_FAILURE); if (link(fromname, toname) != 0) { - const char *e = strerror(errno); - (void) fprintf(stderr, - _("%s: Can't link from %s to %s: %s\n"), - progname, fromname, toname, e); + (void) fprintf(stderr, "%s: Can't link from %s to ", + progname, fromname); + (void) perror(toname); (void) exit(EXIT_FAILURE); } } @@ -619,41 +567,36 @@ const char * const tofile; ifree(toname); } -#ifndef INT_MAX -#define INT_MAX ((int) (((unsigned)~0)>>1)) -#endif /* !defined INT_MAX */ - -#ifndef INT_MIN -#define INT_MIN ((int) ~(((unsigned)~0)>>1)) -#endif /* !defined INT_MIN */ - -/* -** The tz file format currently allows at most 32-bit quantities. -** This restriction should be removed before signed 32-bit values -** wrap around in 2038, but unfortunately this will require a -** change to the tz file format. -*/ - -#define MAX_BITS_IN_FILE 32 -#define TIME_T_BITS_IN_FILE ((TYPE_BIT(time_t) < MAX_BITS_IN_FILE) ? TYPE_BIT(time_t) : MAX_BITS_IN_FILE) - static void setboundaries P((void)) { - if (TYPE_SIGNED(time_t)) { - min_time = ~ (time_t) 0; - min_time <<= TIME_T_BITS_IN_FILE - 1; - max_time = ~ (time_t) 0 - min_time; + register time_t bit; + register int bii; + + for (bit = 1; bit > 0; bit <<= 1) + continue; + if (bit == 0) { /* time_t is an unsigned type */ + tt_signed = FALSE; + min_time = 0; + max_time = ~(time_t) 0; if (sflag) - min_time = 0; + max_time >>= 1; } else { - min_time = 0; - max_time = 2 - sflag; - max_time <<= TIME_T_BITS_IN_FILE - 1; - --max_time; + tt_signed = TRUE; + min_time = bit; + max_time = bit; + ++max_time; + max_time = -max_time; + if (sflag) + min_time = 0; } min_year = TM_YEAR_BASE + gmtime(&min_time)->tm_year; max_year = TM_YEAR_BASE + gmtime(&max_time)->tm_year; + + for (bii = 1; bii > 0; bii <<= 1) + continue; + min_int = bii; + max_int = -1 - bii; } static int @@ -693,37 +636,11 @@ associate P((void)) register struct zone * zp; register struct rule * rp; register int base, out; - register int i, j; + register int i; - if (nrules != 0) { + if (nrules != 0) (void) qsort((void *) rules, (size_t) nrules, (size_t) sizeof *rules, rcomp); - for (i = 0; i < nrules - 1; ++i) { - if (strcmp(rules[i].r_name, - rules[i + 1].r_name) != 0) - continue; - if (strcmp(rules[i].r_filename, - rules[i + 1].r_filename) == 0) - continue; - eat(rules[i].r_filename, rules[i].r_linenum); - warning(_("same rule name in multiple files")); - eat(rules[i + 1].r_filename, rules[i + 1].r_linenum); - warning(_("same rule name in multiple files")); - for (j = i + 2; j < nrules; ++j) { - if (strcmp(rules[i].r_name, - rules[j].r_name) != 0) - break; - if (strcmp(rules[i].r_filename, - rules[j].r_filename) == 0) - continue; - if (strcmp(rules[i + 1].r_filename, - rules[j].r_filename) == 0) - continue; - break; - } - i = j - 1; - } - } for (i = 0; i < nzones; ++i) { zp = &zones[i]; zp->z_rules = NULL; @@ -749,14 +666,13 @@ associate P((void)) ** Maybe we have a local standard time offset. */ eat(zp->z_filename, zp->z_linenum); - zp->z_stdoff = gethms(zp->z_rule, _("unruly zone"), - TRUE); + zp->z_stdoff = gethms(zp->z_rule, "unruly zone", TRUE); /* ** Note, though, that if there's no rule, ** a '%s' in the format is a bad thing. */ if (strchr(zp->z_format, '%') != 0) - error(_("%s in ruleless zone")); + error("%s in ruleless zone"); } } if (errors) @@ -777,12 +693,11 @@ const char * name; char buf[BUFSIZ]; if (strcmp(name, "-") == 0) { - name = _("standard input"); + name = "standard input"; fp = stdin; } else if ((fp = fopen(name, "r")) == NULL) { - const char *e = strerror(errno); - (void) fprintf(stderr, _("%s: Can't open %s: %s\n"), - progname, name, e); + (void) fprintf(stderr, "%s: Can't open ", progname); + (void) perror(name); (void) exit(EXIT_FAILURE); } wantcont = FALSE; @@ -792,7 +707,7 @@ const char * name; break; cp = strchr(buf, '\n'); if (cp == NULL) { - error(_("line too long")); + error("line too long"); (void) exit(EXIT_FAILURE); } *cp = '\0'; @@ -801,7 +716,7 @@ const char * name; while (fields[nfields] != NULL) { static char nada; - if (strcmp(fields[nfields], "-") == 0) + if (ciequal(fields[nfields], "-")) fields[nfields] = &nada; ++nfields; } @@ -812,7 +727,7 @@ const char * name; } else { lp = byword(fields[0], line_codes); if (lp == NULL) - error(_("input line of unknown type")); + error("input line of unknown type"); else switch ((int) (lp->l_value)) { case LC_RULE: inrule(fields, nfields); @@ -828,14 +743,14 @@ const char * name; case LC_LEAP: if (name != leapsec) (void) fprintf(stderr, -_("%s: Leap line in non leap seconds file %s\n"), +"%s: Leap line in non leap seconds file %s\n", progname, name); else inleap(fields, nfields); wantcont = FALSE; break; default: /* "cannot happen" */ (void) fprintf(stderr, -_("%s: panic: Invalid l_value %d\n"), +"%s: panic: Invalid l_value %d\n", progname, lp->l_value); (void) exit(EXIT_FAILURE); } @@ -843,18 +758,17 @@ _("%s: panic: Invalid l_value %d\n"), ifree((char *) fields); } if (ferror(fp)) { - (void) fprintf(stderr, _("%s: Error reading %s\n"), - progname, filename); + (void) fprintf(stderr, "%s: Error reading ", progname); + (void) perror(filename); (void) exit(EXIT_FAILURE); } if (fp != stdin && fclose(fp)) { - const char *e = strerror(errno); - (void) fprintf(stderr, _("%s: Error closing %s: %s\n"), - progname, filename, e); + (void) fprintf(stderr, "%s: Error closing ", progname); + (void) perror(filename); (void) exit(EXIT_FAILURE); } if (wantcont) - error(_("expected continuation line not found")); + error("expected continuation line not found"); } /* @@ -909,16 +823,16 @@ const int nfields; static struct rule r; if (nfields != RULE_FIELDS) { - error(_("wrong number of fields on Rule line")); + error("wrong number of fields on Rule line"); return; } if (*fields[RF_NAME] == '\0') { - error(_("nameless rule")); + error("nameless rule"); return; } r.r_filename = filename; r.r_linenum = linenum; - r.r_stdoff = gethms(fields[RF_STDOFF], _("invalid saved time"), TRUE); + r.r_stdoff = gethms(fields[RF_STDOFF], "invalid saved time", TRUE); rulesub(&r, fields[RF_LOYEAR], fields[RF_HIYEAR], fields[RF_COMMAND], fields[RF_MONTH], fields[RF_DAY], fields[RF_TOD]); r.r_name = ecpyalloc(fields[RF_NAME]); @@ -937,13 +851,13 @@ const int nfields; static char * buf; if (nfields < ZONE_MINFIELDS || nfields > ZONE_MAXFIELDS) { - error(_("wrong number of fields on Zone line")); + error("wrong number of fields on Zone line"); return FALSE; } if (strcmp(fields[ZF_NAME], TZDEFAULT) == 0 && lcltime != NULL) { buf = erealloc(buf, (int) (132 + strlen(TZDEFAULT))); (void) sprintf(buf, -_("\"Zone %s\" line and -l option are mutually exclusive"), +"\"Zone %s\" line and -l option are mutually exclusive", TZDEFAULT); error(buf); return FALSE; @@ -951,7 +865,7 @@ _("\"Zone %s\" line and -l option are mutually exclusive"), if (strcmp(fields[ZF_NAME], TZDEFRULES) == 0 && psxrules != NULL) { buf = erealloc(buf, (int) (132 + strlen(TZDEFRULES))); (void) sprintf(buf, -_("\"Zone %s\" line and -p option are mutually exclusive"), +"\"Zone %s\" line and -p option are mutually exclusive", TZDEFRULES); error(buf); return FALSE; @@ -963,7 +877,7 @@ _("\"Zone %s\" line and -p option are mutually exclusive"), strlen(fields[ZF_NAME]) + strlen(zones[i].z_filename))); (void) sprintf(buf, -_("duplicate zone name %s (file \"%s\", line %d)"), +"duplicate zone name %s (file \"%s\", line %d)", fields[ZF_NAME], zones[i].z_filename, zones[i].z_linenum); @@ -979,7 +893,7 @@ register char ** const fields; const int nfields; { if (nfields < ZONEC_MINFIELDS || nfields > ZONEC_MAXFIELDS) { - error(_("wrong number of fields on Zone continuation line")); + error("wrong number of fields on Zone continuation line"); return FALSE; } return inzsub(fields, nfields, TRUE); @@ -1019,10 +933,10 @@ const int iscont; } z.z_filename = filename; z.z_linenum = linenum; - z.z_gmtoff = gethms(fields[i_gmtoff], _("invalid GMT offset"), TRUE); + z.z_gmtoff = gethms(fields[i_gmtoff], "invalid GMT offset", TRUE); if ((cp = strchr(fields[i_format], '%')) != 0) { if (*++cp != 's' || strchr(cp, '%') != 0) { - error(_("invalid abbreviation format")); + error("invalid abbreviation format"); return FALSE; } } @@ -1048,7 +962,8 @@ const int iscont; zones[nzones - 1].z_untiltime > min_time && zones[nzones - 1].z_untiltime < max_time && zones[nzones - 1].z_untiltime >= z.z_untiltime) { - error(_("Zone continuation line end time is not after end time of previous line")); + error("Zone continuation line end time is not \ +after end time of previous line"); return FALSE; } } @@ -1075,7 +990,7 @@ const int nfields; time_t t; if (nfields != LEAP_FIELDS) { - error(_("wrong number of fields on Leap line")); + error("wrong number of fields on Leap line"); return; } dayoff = 0; @@ -1084,7 +999,7 @@ const int nfields; /* * Leapin' Lizards! */ - error(_("invalid leaping year")); + error("invalid leaping year"); return; } j = EPOCH_YEAR; @@ -1099,7 +1014,7 @@ const int nfields; dayoff = oadd(dayoff, eitol(i)); } if ((lp = byword(fields[LP_MONTH], mon_names)) == NULL) { - error(_("invalid month name")); + error("invalid month name"); return; } month = lp->l_value; @@ -1112,12 +1027,12 @@ const int nfields; cp = fields[LP_DAY]; if (sscanf(cp, scheck(cp, "%d"), &day) != 1 || day <= 0 || day > len_months[isleap(year)][month]) { - error(_("invalid day of month")); + error("invalid day of month"); return; } dayoff = oadd(dayoff, eitol(day - 1)); - if (dayoff < 0 && !TYPE_SIGNED(time_t)) { - error(_("time before zero")); + if (dayoff < 0 && !tt_signed) { + error("time before zero"); return; } t = (time_t) dayoff * SECSPERDAY; @@ -1125,10 +1040,10 @@ const int nfields; ** Cheap overflow check. */ if (t / SECSPERDAY != dayoff) { - error(_("time overflow")); + error("time overflow"); return; } - tod = gethms(fields[LP_TIME], _("invalid time of day"), FALSE); + tod = gethms(fields[LP_TIME], "invalid time of day", FALSE); cp = fields[LP_CORR]; { register int positive; @@ -1147,11 +1062,11 @@ const int nfields; positive = TRUE; count = 2; } else { - error(_("illegal CORRECTION field on Leap line")); + error("illegal CORRECTION field on Leap line"); return; } if ((lp = byword(fields[LP_ROLL], leap_types)) == NULL) { - error(_("illegal Rolling/Stationary field on Leap line")); + error("illegal Rolling/Stationary field on Leap line"); return; } leapadd(tadd(t, tod), positive, lp->l_value, count); @@ -1166,15 +1081,15 @@ const int nfields; struct link l; if (nfields != LINK_FIELDS) { - error(_("wrong number of fields on Link line")); + error("wrong number of fields on Link line"); return; } if (*fields[LF_FROM] == '\0') { - error(_("blank FROM field on Link line")); + error("blank FROM field on Link line"); return; } if (*fields[LF_TO] == '\0') { - error(_("blank TO field on Link line")); + error("blank TO field on Link line"); return; } l.l_filename = filename; @@ -1202,7 +1117,7 @@ const char * const timep; register char * ep; if ((lp = byword(monthp, mon_names)) == NULL) { - error(_("invalid month name")); + error("invalid month name"); return; } rp->r_month = lp->l_value; @@ -1230,7 +1145,7 @@ const char * const timep; break; } } - rp->r_tod = gethms(dp, _("invalid time of day"), FALSE); + rp->r_tod = gethms(dp, "invalid time of day", FALSE); ifree(dp); /* ** Year work. @@ -1239,49 +1154,49 @@ const char * const timep; lp = byword(cp, begin_years); if (lp != NULL) switch ((int) lp->l_value) { case YR_MINIMUM: - rp->r_loyear = INT_MIN; + rp->r_loyear = min_int; break; case YR_MAXIMUM: - rp->r_loyear = INT_MAX; + rp->r_loyear = max_int; break; default: /* "cannot happen" */ (void) fprintf(stderr, - _("%s: panic: Invalid l_value %d\n"), + "%s: panic: Invalid l_value %d\n", progname, lp->l_value); (void) exit(EXIT_FAILURE); } else if (sscanf(cp, scheck(cp, "%d"), &rp->r_loyear) != 1) { - error(_("invalid starting year")); + error("invalid starting year"); return; } cp = hiyearp; if ((lp = byword(cp, end_years)) != NULL) switch ((int) lp->l_value) { case YR_MINIMUM: - rp->r_hiyear = INT_MIN; + rp->r_hiyear = min_int; break; case YR_MAXIMUM: - rp->r_hiyear = INT_MAX; + rp->r_hiyear = max_int; break; case YR_ONLY: rp->r_hiyear = rp->r_loyear; break; default: /* "cannot happen" */ (void) fprintf(stderr, - _("%s: panic: Invalid l_value %d\n"), + "%s: panic: Invalid l_value %d\n", progname, lp->l_value); (void) exit(EXIT_FAILURE); } else if (sscanf(cp, scheck(cp, "%d"), &rp->r_hiyear) != 1) { - error(_("invalid ending year")); + error("invalid ending year"); return; } if (rp->r_loyear > rp->r_hiyear) { - error(_("starting year greater than ending year")); + error("starting year greater than ending year"); return; } if (*typep == '\0') rp->r_yrtype = NULL; else { if (rp->r_loyear == rp->r_hiyear) { - error(_("typed single year")); + error("typed single year"); return; } rp->r_yrtype = ecpyalloc(typep); @@ -1311,12 +1226,12 @@ const char * const timep; if (rp->r_dycode != DC_DOM) { *ep++ = 0; if (*ep++ != '=') { - error(_("invalid day of month")); + error("invalid day of month"); ifree(dp); return; } if ((lp = byword(dp, wday_names)) == NULL) { - error(_("invalid weekday name")); + error("invalid weekday name"); ifree(dp); return; } @@ -1325,7 +1240,7 @@ const char * const timep; if (sscanf(ep, scheck(ep, "%d"), &rp->r_dayofmonth) != 1 || rp->r_dayofmonth <= 0 || (rp->r_dayofmonth > len_months[1][rp->r_month])) { - error(_("invalid day of month")); + error("invalid day of month"); ifree(dp); return; } @@ -1356,18 +1271,6 @@ FILE * const fp; (void) fwrite((void *) buf, (size_t) sizeof buf, (size_t) 1, fp); } -static int -atcomp(avp, bvp) -void * avp; -void * bvp; -{ - if (((struct attype *) avp)->at < ((struct attype *) bvp)->at) - return -1; - else if (((struct attype *) avp)->at > ((struct attype *) bvp)->at) - return 1; - else return 0; -} - static void writezone(name) const char * const name; @@ -1376,50 +1279,7 @@ const char * const name; register int i, j; static char * fullname; static struct tzhead tzh; - time_t ats[TZ_MAX_TIMES]; - unsigned char types[TZ_MAX_TIMES]; - /* - ** Sort. - */ - if (timecnt > 1) - (void) qsort((void *) attypes, (size_t) timecnt, - (size_t) sizeof *attypes, atcomp); - /* - ** Optimize. - */ - { - int fromi; - int toi; - - toi = 0; - fromi = 0; - if (isdsts[0] == 0) - while (attypes[fromi].type == 0) - ++fromi; /* handled by default rule */ - for ( ; fromi < timecnt; ++fromi) { - if (toi != 0 - && ((attypes[fromi].at - + gmtoffs[attypes[toi - 1].type]) - <= (attypes[toi - 1].at - + gmtoffs[toi == 1 ? 0 - : attypes[toi - 2].type]))) { - attypes[toi - 1].type = attypes[fromi].type; - continue; - } - if (toi == 0 || - attypes[toi - 1].type != attypes[fromi].type) - attypes[toi++] = attypes[fromi]; - } - timecnt = toi; - } - /* - ** Transfer. - */ - for (i = 0; i < timecnt; ++i) { - ats[i] = attypes[i].at; - types[i] = attypes[i].type; - } fullname = erealloc(fullname, (int) (strlen(directory) + 1 + strlen(name) + 1)); (void) sprintf(fullname, "%s/%s", directory, name); @@ -1427,9 +1287,8 @@ const char * const name; if (mkdirs(fullname) != 0) (void) exit(EXIT_FAILURE); if ((fp = fopen(fullname, "wb")) == NULL) { - const char *e = strerror(errno); - (void) fprintf(stderr, _("%s: Can't create %s: %s\n"), - progname, fullname, e); + (void) fprintf(stderr, "%s: Can't create ", progname); + (void) perror(fullname); (void) exit(EXIT_FAILURE); } } @@ -1439,7 +1298,8 @@ const char * const name; convert(eitol(timecnt), tzh.tzh_timecnt); convert(eitol(typecnt), tzh.tzh_typecnt); convert(eitol(charcnt), tzh.tzh_charcnt); -#define DO(field) (void) fwrite((void *) tzh.field, (size_t) sizeof tzh.field, (size_t) 1, fp) +#define DO(field) (void) fwrite((void *) tzh.field, \ + (size_t) sizeof tzh.field, (size_t) 1, fp) DO(tzh_reserved); DO(tzh_ttisgmtcnt); DO(tzh_ttisstdcnt); @@ -1492,8 +1352,8 @@ const char * const name; for (i = 0; i < typecnt; ++i) (void) putc(ttisgmts[i], fp); if (ferror(fp) || fclose(fp)) { - (void) fprintf(stderr, _("%s: Error writing %s\n"), - progname, fullname); + (void) fprintf(stderr, "%s: Write error on ", progname); + (void) perror(fullname); (void) exit(EXIT_FAILURE); } } @@ -1531,6 +1391,7 @@ const int zonecount; register long stdoff; register int year; register long startoff; + register int startisdst; register int startttisstd; register int startttisgmt; register int type; @@ -1538,6 +1399,7 @@ const int zonecount; INITIALIZE(untiltime); INITIALIZE(starttime); + INITIALIZE(startoff); /* ** Now. . .finally. . .generate some useful data! */ @@ -1562,8 +1424,7 @@ const int zonecount; continue; gmtoff = zp->z_gmtoff; eat(zp->z_filename, zp->z_linenum); - *startbuf = '\0'; - startoff = zp->z_gmtoff; + startisdst = -1; if (zp->z_nrules == 0) { stdoff = zp->z_stdoff; doabbr(startbuf, zp->z_format, @@ -1571,10 +1432,8 @@ const int zonecount; type = addtype(oadd(zp->z_gmtoff, stdoff), startbuf, stdoff != 0, startttisstd, startttisgmt); - if (usestart) { + if (usestart) addtt(starttime, type); - usestart = FALSE; - } else if (stdoff != 0) addtt(min_time, type); } else for (year = min_year; year <= max_year; ++year) { @@ -1645,25 +1504,36 @@ const int zonecount; rp->r_todo = FALSE; if (useuntil && ktime >= untiltime) break; - stdoff = rp->r_stdoff; - if (usestart && ktime == starttime) - usestart = FALSE; if (usestart) { - if (ktime < starttime) { - startoff = oadd(zp->z_gmtoff, - stdoff); - doabbr(startbuf, zp->z_format, - rp->r_abbrvar, - rp->r_stdoff != 0); - continue; - } - if (*startbuf == '\0' && - startoff == oadd(zp->z_gmtoff, - stdoff)) { - doabbr(startbuf, zp->z_format, - rp->r_abbrvar, - rp->r_stdoff != 0); + if (ktime < starttime) { + stdoff = rp->r_stdoff; + startoff = oadd(zp->z_gmtoff, + rp->r_stdoff); + doabbr(startbuf, zp->z_format, + rp->r_abbrvar, + rp->r_stdoff != 0); + startisdst = rp->r_stdoff != 0; + continue; + } + usestart = FALSE; + if (ktime != starttime) { + if (startisdst < 0 && + zp->z_gmtoff != + (zp - 1)->z_gmtoff) { + type = (timecnt == 0) ? 0 : + types[timecnt - 1]; + startoff = oadd(gmtoffs[type], + -(zp - 1)->z_gmtoff); + startisdst = startoff != 0; + startoff = oadd(startoff, + zp->z_gmtoff); + (void) strcpy(startbuf, + &chars[abbrinds[type]]); } + if (startisdst >= 0) +addtt(starttime, addtype(startoff, startbuf, startisdst, startttisstd, + startttisgmt)); + } } eats(zp->z_filename, zp->z_linenum, rp->r_filename, rp->r_linenum); @@ -1673,34 +1543,18 @@ const int zonecount; type = addtype(offset, buf, rp->r_stdoff != 0, rp->r_todisstd, rp->r_todisgmt); addtt(ktime, type); + stdoff = rp->r_stdoff; } } - if (usestart) { - if (*startbuf == '\0' && - zp->z_format != NULL && - strchr(zp->z_format, '%') == NULL && - strchr(zp->z_format, '/') == NULL) - (void) strcpy(startbuf, zp->z_format); - eat(zp->z_filename, zp->z_linenum); - if (*startbuf == '\0') -error(_("can't determine time zone abbrevation to use just after until time")); - else addtt(starttime, - addtype(startoff, startbuf, - startoff != zp->z_gmtoff, - startttisstd, - startttisgmt)); - } /* ** Now we may get to set starttime for the next zone line. */ if (useuntil) { + starttime = tadd(zp->z_untiltime, -gmtoff); startttisstd = zp->z_untilrule.r_todisstd; startttisgmt = zp->z_untilrule.r_todisgmt; - starttime = zp->z_untiltime; if (!startttisstd) starttime = tadd(starttime, -stdoff); - if (!startttisgmt) - starttime = tadd(starttime, -gmtoff); } } writezone(zpfirst->z_name); @@ -1711,12 +1565,16 @@ addtt(starttime, type) const time_t starttime; const int type; { + if (timecnt != 0 && type == types[timecnt - 1]) + return; /* easy enough! */ + if (timecnt == 0 && type == 0 && isdsts[0] == 0) + return; /* handled by default rule */ if (timecnt >= TZ_MAX_TIMES) { - error(_("too many transitions?!")); + error("too many transitions?!"); (void) exit(EXIT_FAILURE); } - attypes[timecnt].at = starttime; - attypes[timecnt].type = type; + ats[timecnt] = starttime; + types[timecnt] = type; ++timecnt; } @@ -1730,18 +1588,6 @@ const int ttisgmt; { register int i, j; - if (isdst != TRUE && isdst != FALSE) { - error(_("internal error - addtype called with bad isdst")); - (void) exit(EXIT_FAILURE); - } - if (ttisstd != TRUE && ttisstd != FALSE) { - error(_("internal error - addtype called with bad ttisstd")); - (void) exit(EXIT_FAILURE); - } - if (ttisgmt != TRUE && ttisgmt != FALSE) { - error(_("internal error - addtype called with bad ttisgmt")); - (void) exit(EXIT_FAILURE); - } /* ** See if there's already an entry for this zone type. ** If so, just return its index. @@ -1758,7 +1604,7 @@ const int ttisgmt; ** many. */ if (typecnt >= TZ_MAX_TYPES) { - error(_("too many local time types")); + error("too many local time types"); (void) exit(EXIT_FAILURE); } gmtoffs[i] = gmtoff; @@ -1786,13 +1632,13 @@ int count; register int i, j; if (leapcnt + (positive ? count : 1) > TZ_MAX_LEAPS) { - error(_("too many leap seconds")); + error("too many leap seconds"); (void) exit(EXIT_FAILURE); } for (i = 0; i < leapcnt; ++i) if (t <= trans[i]) { if (t == trans[i]) { - error(_("repeated leap second moment")); + error("repeated leap second moment"); (void) exit(EXIT_FAILURE); } break; @@ -1842,8 +1688,8 @@ const char * const type; return TRUE; if (result == (1 << 8)) return FALSE; - error(_("Wild result from command execution")); - (void) fprintf(stderr, _("%s: command was '%s', result was %d\n"), + error("Wild result from command execution"); + (void) fprintf(stderr, "%s: command was '%s', result was %d\n", progname, buf, result); for ( ; ; ) (void) exit(EXIT_FAILURE); @@ -1851,9 +1697,8 @@ const char * const type; static int lowerit(a) -int a; +const int a; { - a = (unsigned char) a; return (isascii(a) && isupper(a)) ? tolower(a) : a; } @@ -1877,10 +1722,9 @@ register const char * word; return FALSE; ++word; while (*++abbr != '\0') - do { - if (*word == '\0') - return FALSE; - } while (lowerit(*word++) != lowerit(*abbr)); + do if (*word == '\0') + return FALSE; + while (lowerit(*word++) != lowerit(*abbr)); return TRUE; } @@ -1926,7 +1770,7 @@ register char * cp; emalloc((int) ((strlen(cp) + 1) * sizeof *array)); nsubs = 0; for ( ; ; ) { - while (isascii(*cp) && isspace((unsigned char) *cp)) + while (isascii(*cp) && isspace(*cp)) ++cp; if (*cp == '\0' || *cp == '#') break; @@ -1937,10 +1781,10 @@ register char * cp; else while ((*dp = *cp++) != '"') if (*dp != '\0') ++dp; - else error(_("Odd number of quotation marks")); + else error("Odd number of quotation marks"); } while (*cp != '\0' && *cp != '#' && - (!isascii(*cp) || !isspace((unsigned char) *cp))); - if (isascii(*cp) && isspace((unsigned char) *cp)) + (!isascii(*cp) || !isspace(*cp))); + if (isascii(*cp) && isspace(*cp)) ++cp; *dp = '\0'; } @@ -1957,7 +1801,7 @@ const long t2; t = t1 + t2; if ((t2 > 0 && t <= t1) || (t2 < 0 && t >= t1)) { - error(_("time overflow")); + error("time overflow"); (void) exit(EXIT_FAILURE); } return t; @@ -1976,7 +1820,7 @@ const long t2; return min_time; t = t1 + t2; if ((t2 > 0 && t <= t1) || (t2 < 0 && t >= t1)) { - error(_("time overflow")); + error("time overflow"); (void) exit(EXIT_FAILURE); } return t; @@ -1996,9 +1840,9 @@ register const int wantedy; register long dayoff; /* with a nod to Margaret O. */ register time_t t; - if (wantedy == INT_MIN) + if (wantedy == min_int) return min_time; - if (wantedy == INT_MAX) + if (wantedy == max_int) return max_time; dayoff = 0; m = TM_JANUARY; @@ -2023,7 +1867,7 @@ register const int wantedy; if (rp->r_dycode == DC_DOWLEQ) --i; else { - error(_("use of 2/29 in non leap-year")); + error("use of 2/29 in non leap-year"); (void) exit(EXIT_FAILURE); } } @@ -2057,11 +1901,11 @@ register const int wantedy; --i; } if (i < 0 || i >= len_months[isleap(y)][m]) { - error(_("no day in month matches rule")); + error("no day in month matches rule"); (void) exit(EXIT_FAILURE); } } - if (dayoff < 0 && !TYPE_SIGNED(time_t)) + if (dayoff < 0 && !tt_signed) return min_time; t = (time_t) dayoff * SECSPERDAY; /* @@ -2080,7 +1924,7 @@ const char * const string; i = strlen(string) + 1; if (charcnt + i > TZ_MAX_CHARS) { - error(_("too many, or too long, time zone abbreviations")); + error("too many, or too long, time zone abbreviations"); (void) exit(EXIT_FAILURE); } (void) strcpy(&chars[charcnt], string); @@ -2103,8 +1947,8 @@ char * const argname; /* ** DOS drive specifier? */ - if (isalpha((unsigned char) name[0]) && - name[1] == ':' && name[2] == '\0') { + if (strlen(name) == 2 && isascii(name[0]) && + isalpha(name[0]) && name[1] == ':') { *cp = '/'; continue; } @@ -2114,10 +1958,10 @@ char * const argname; ** It doesn't seem to exist, so we try to create it. */ if (mkdir(name, 0755) != 0) { - const char *e = strerror(errno); (void) fprintf(stderr, - _("%s: Can't create directory %s: %s\n"), - progname, name, e); + "%s: Can't create directory ", + progname); + (void) perror(name); ifree(name); return -1; } @@ -2137,7 +1981,7 @@ const int i; l = i; if ((i < 0 && l >= 0) || (i == 0 && l != 0) || (i > 0 && l <= 0)) { (void) fprintf(stderr, - _("%s: %d did not sign extend correctly\n"), + "%s: %d did not sign extend correctly\n", progname, i); (void) exit(EXIT_FAILURE); } |