diff options
| -rw-r--r-- | time/tzfile.c | 2 | ||||
| -rw-r--r-- | timezone/private.h | 37 | ||||
| -rw-r--r-- | timezone/tzfile.h | 20 | ||||
| -rw-r--r-- | timezone/version | 2 | ||||
| -rw-r--r-- | timezone/zdump.c | 6 | ||||
| -rw-r--r-- | timezone/zic.c | 814 |
6 files changed, 554 insertions, 327 deletions
diff --git a/time/tzfile.c b/time/tzfile.c index 013b3d03f3..af6da1bf00 100644 --- a/time/tzfile.c +++ b/time/tzfile.c @@ -189,7 +189,7 @@ __tzfile_read (const char *file, size_t extra, char **extrap) chars = (size_t) decode (tzhead.tzh_charcnt); num_leaps = (size_t) decode (tzhead.tzh_leapcnt); num_isstd = (size_t) decode (tzhead.tzh_ttisstdcnt); - num_isgmt = (size_t) decode (tzhead.tzh_ttisgmtcnt); + num_isgmt = (size_t) decode (tzhead.tzh_ttisutcnt); if (__glibc_unlikely (num_isstd > num_types || num_isgmt > num_types)) goto lose; diff --git a/timezone/private.h b/timezone/private.h index 1ead14793b..8513663036 100644 --- a/timezone/private.h +++ b/timezone/private.h @@ -132,11 +132,16 @@ ** Nested includes */ -/* Avoid clashes with NetBSD by renaming NetBSD's declarations. */ +/* Avoid clashes with NetBSD by renaming NetBSD's declarations. + If defining the 'timezone' variable, avoid a clash with FreeBSD's + 'timezone' function by renaming its declaration. */ #define localtime_rz sys_localtime_rz #define mktime_z sys_mktime_z #define posix2time_z sys_posix2time_z #define time2posix_z sys_time2posix_z +#if defined USG_COMPAT && USG_COMPAT == 2 +# define timezone sys_timezone +#endif #define timezone_t sys_timezone_t #define tzalloc sys_tzalloc #define tzfree sys_tzfree @@ -145,6 +150,9 @@ #undef mktime_z #undef posix2time_z #undef time2posix_z +#if defined USG_COMPAT && USG_COMPAT == 2 +# undef timezone +#endif #undef timezone_t #undef tzalloc #undef tzfree @@ -198,6 +206,14 @@ # endif #endif +#ifndef ALTZONE +# if defined __sun || defined _M_XENIX +# define ALTZONE 1 +# else +# define ALTZONE 0 +# endif +#endif + #ifndef R_OK #define R_OK 4 #endif /* !defined R_OK */ @@ -409,6 +425,10 @@ static time_t sys_time(time_t *x) { return time(x); } typedef time_tz tz_time_t; +# undef asctime +# define asctime tz_asctime +# undef asctime_r +# define asctime_r tz_asctime_r # undef ctime # define ctime tz_ctime # undef ctime_r @@ -473,11 +493,13 @@ typedef time_tz tz_time_t; # undef timezone # define timezone tz_timezone # endif -# ifdef ALTZONE +# if ALTZONE # undef altzone # define altzone tz_altzone # endif +char *asctime(struct tm const *); +char *asctime_r(struct tm const *restrict, char *restrict); char *ctime(time_t const *); char *ctime_r(time_t const *, char *); double difftime(time_t, time_t) ATTRIBUTE_CONST; @@ -512,17 +534,14 @@ extern char *asctime_r(struct tm const *restrict, char *restrict); extern char **environ; #endif -#if TZ_TIME_T || !HAVE_POSIX_DECLS -# if HAVE_TZNAME +#if 2 <= HAVE_TZNAME + (TZ_TIME_T || !HAVE_POSIX_DECLS) extern char *tzname[]; -# endif -# if USG_COMPAT +#endif +#if 2 <= USG_COMPAT + (TZ_TIME_T || !HAVE_POSIX_DECLS) extern long timezone; extern int daylight; -# endif #endif - -#ifdef ALTZONE +#if 2 <= ALTZONE + (TZ_TIME_T || !HAVE_POSIX_DECLS) extern long altzone; #endif diff --git a/timezone/tzfile.h b/timezone/tzfile.h index 27a38cc74d..ee91104443 100644 --- a/timezone/tzfile.h +++ b/timezone/tzfile.h @@ -33,6 +33,9 @@ #define TZDEFRULES "posixrules" #endif /* !defined TZDEFRULES */ + +/* See Internet RFC 8536 for more details about the following format. */ + /* ** Each file begins with. . . */ @@ -43,7 +46,7 @@ struct tzhead { char tzh_magic[4]; /* TZ_MAGIC */ char tzh_version[1]; /* '\0' or '2' or '3' as of 2013 */ char tzh_reserved[15]; /* reserved; must be zero */ - char tzh_ttisgmtcnt[4]; /* coded number of trans. time flags */ + char tzh_ttisutcnt[4]; /* coded number of trans. time flags */ char tzh_ttisstdcnt[4]; /* coded number of trans. time flags */ char tzh_leapcnt[4]; /* coded number of leap seconds */ char tzh_timecnt[4]; /* coded number of transition times */ @@ -66,14 +69,15 @@ struct tzhead { ** one (char [4]) total correction after above ** tzh_ttisstdcnt (char)s indexed by type; if 1, transition ** time is standard time, if 0, -** transition time is wall clock time -** if absent, transition times are -** assumed to be wall clock time -** tzh_ttisgmtcnt (char)s indexed by type; if 1, transition -** time is UT, if 0, -** transition time is local time -** if absent, transition times are +** transition time is local (wall clock) +** time; if absent, transition times are ** assumed to be local time +** tzh_ttisutcnt (char)s indexed by type; if 1, transition +** time is UT, if 0, transition time is +** local time; if absent, transition +** times are assumed to be local time. +** When this is 1, the corresponding +** std/wall indicator must also be 1. */ /* diff --git a/timezone/version b/timezone/version index 63f58006ee..7f680eec36 100644 --- a/timezone/version +++ b/timezone/version @@ -1 +1 @@ -2018i +2020a diff --git a/timezone/zdump.c b/timezone/zdump.c index 0fc8ced96a..b532fe3eae 100644 --- a/timezone/zdump.c +++ b/timezone/zdump.c @@ -328,12 +328,12 @@ abbrok(const char *const abbrp, const char *const zone) cp = abbrp; while (is_alpha(*cp) || is_digit(*cp) || *cp == '-' || *cp == '+') ++cp; - if (cp - abbrp < 3) + if (*cp) + wp = _("has characters other than ASCII alphanumerics, '-' or '+'"); + else if (cp - abbrp < 3) wp = _("has fewer than 3 characters"); else if (cp - abbrp > 6) wp = _("has more than 6 characters"); - else if (*cp) - wp = _("has characters other than ASCII alphanumerics, '-' or '+'"); else return; fflush(stdout); diff --git a/timezone/zic.c b/timezone/zic.c index 2ebc66a9af..2875b5544c 100644 --- a/timezone/zic.c +++ b/timezone/zic.c @@ -92,13 +92,10 @@ struct rule { int r_wday; zic_t r_tod; /* time from midnight */ - bool r_todisstd; /* above is standard time if 1 */ - /* or wall clock time if 0 */ - bool r_todisgmt; /* above is GMT if 1 */ - /* or local time if 0 */ + bool r_todisstd; /* is r_tod standard time? */ + bool r_todisut; /* is r_tod UT? */ bool r_isdst; /* is this daylight saving time? */ - zic_t r_stdoff; /* offset from default time (which is - usually standard time) */ + zic_t r_save; /* offset from standard time */ const char * r_abbrvar; /* variable part of abbreviation */ bool r_todo; /* a rule to do (used in outzone) */ @@ -118,13 +115,13 @@ struct zone { lineno z_linenum; const char * z_name; - zic_t z_gmtoff; + zic_t z_stdoff; char * z_rule; const char * z_format; char z_format_specifier; bool z_isdst; - zic_t z_stdoff; + zic_t z_save; struct rule * z_rules; ptrdiff_t z_nrules; @@ -156,13 +153,14 @@ extern int optind; static void addtt(zic_t starttime, int type); static int addtype(zic_t, char const *, bool, bool, bool); -static void leapadd(zic_t, bool, int, int); +static void leapadd(zic_t, int, int); static void adjleap(void); static void associate(void); static void dolink(const char *, const char *, bool); static char ** getfields(char * buf); static zic_t gethms(const char * string, const char * errstring); -static zic_t getstdoff(char *, bool *); +static zic_t getsave(char *, bool *); +static void inexpires(char **, int); static void infile(const char * filename); static void inleap(char ** fields, int nfields); static void inlink(char ** fields, int nfields); @@ -227,13 +225,14 @@ static int typecnt; #define LC_ZONE 1 #define LC_LINK 2 #define LC_LEAP 3 +#define LC_EXPIRES 4 /* ** Which fields are which on a Zone line. */ #define ZF_NAME 1 -#define ZF_GMTOFF 2 +#define ZF_STDOFF 2 #define ZF_RULE 3 #define ZF_FORMAT 4 #define ZF_TILYEAR 5 @@ -247,7 +246,7 @@ static int typecnt; ** Which fields are which on a Zone continuation line. */ -#define ZFC_GMTOFF 0 +#define ZFC_STDOFF 0 #define ZFC_RULE 1 #define ZFC_FORMAT 2 #define ZFC_TILYEAR 3 @@ -268,7 +267,7 @@ static int typecnt; #define RF_MONTH 5 #define RF_DAY 6 #define RF_TOD 7 -#define RF_STDOFF 8 +#define RF_SAVE 8 #define RF_ABBRVAR 9 #define RULE_FIELDS 10 @@ -292,6 +291,9 @@ static int typecnt; #define LP_ROLL 6 #define LEAP_FIELDS 7 +/* Expires lines are like Leap lines, except without CORR and ROLL fields. */ +#define EXPIRES_FIELDS 5 + /* ** Year synonyms. */ @@ -335,6 +337,7 @@ static struct lookup const zi_line_codes[] = { }; static struct lookup const leap_line_codes[] = { { "Leap", LC_LEAP }, + { "Expires", LC_EXPIRES }, { NULL, 0} }; @@ -409,11 +412,11 @@ static struct attype { bool dontmerge; unsigned char type; } * attypes; -static zic_t gmtoffs[TZ_MAX_TYPES]; +static zic_t utoffs[TZ_MAX_TYPES]; static char isdsts[TZ_MAX_TYPES]; -static unsigned char abbrinds[TZ_MAX_TYPES]; +static unsigned char desigidx[TZ_MAX_TYPES]; static bool ttisstds[TZ_MAX_TYPES]; -static bool ttisgmts[TZ_MAX_TYPES]; +static bool ttisuts[TZ_MAX_TYPES]; static char chars[TZ_MAX_CHARS]; static zic_t trans[TZ_MAX_LEAPS]; static zic_t corr[TZ_MAX_LEAPS]; @@ -574,8 +577,10 @@ usage(FILE *stream, int status) { fprintf(stream, _("%s: usage is %s [ --version ] [ --help ] [ -v ] \\\n" - "\t[ -l localtime ] [ -p posixrules ] [ -d directory ] \\\n" - "\t[ -t localtime-link ] [ -L leapseconds ] [ filename ... ]\n\n" + "\t[ -b {slim|fat} ] [ -d directory ] [ -l localtime ]" + " [ -L leapseconds ] \\\n" + "\t[ -p posixrules ] [ -r '[@lo][/@hi]' ] [ -t localtime-link ] \\\n" + "\t[ filename ... ]\n\n" "Report bugs to %s.\n"), progname, progname, REPORT_BUGS_TO); if (status == EXIT_SUCCESS) @@ -603,6 +608,51 @@ change_directory (char const *dir) } } +#define TIME_T_BITS_IN_FILE 64 + +/* The minimum and maximum values representable in a TZif file. */ +static zic_t const min_time = MINVAL(zic_t, TIME_T_BITS_IN_FILE); +static zic_t const max_time = MAXVAL(zic_t, TIME_T_BITS_IN_FILE); + +/* The minimum, and one less than the maximum, values specified by + the -r option. These default to MIN_TIME and MAX_TIME. */ +static zic_t lo_time = MINVAL(zic_t, TIME_T_BITS_IN_FILE); +static zic_t hi_time = MAXVAL(zic_t, TIME_T_BITS_IN_FILE); + +/* The time specified by an Expires line, or negative if no such line. */ +static zic_t leapexpires = -1; + +/* The time specified by an #expires comment, or negative if no such line. */ +static zic_t comment_leapexpires = -1; + +/* Set the time range of the output to TIMERANGE. + Return true if successful. */ +static bool +timerange_option(char *timerange) +{ + intmax_t lo = min_time, hi = max_time; + char *lo_end = timerange, *hi_end; + if (*timerange == '@') { + errno = 0; + lo = strtoimax (timerange + 1, &lo_end, 10); + if (lo_end == timerange + 1 || (lo == INTMAX_MAX && errno == ERANGE)) + return false; + } + hi_end = lo_end; + if (lo_end[0] == '/' && lo_end[1] == '@') { + errno = 0; + hi = strtoimax (lo_end + 2, &hi_end, 10); + if (hi_end == lo_end + 2 || hi == INTMAX_MIN) + return false; + hi -= ! (hi == INTMAX_MAX && errno == ERANGE); + } + if (*hi_end || hi < lo || max_time < lo || hi < min_time) + return false; + lo_time = lo < min_time ? min_time : lo; + hi_time = max_time < hi ? max_time : hi; + return true; +} + static const char * psxrules; static const char * lcltime; static const char * directory; @@ -610,11 +660,27 @@ static const char * leapsec; static const char * tzdefault; static const char * yitcommand; +/* -1 if the TZif output file should be slim, 0 if default, 1 if the + output should be fat for backward compatibility. Currently the + default is fat, although this may change. */ +static int bloat; + +static bool +want_bloat(void) +{ + return 0 <= bloat; +} + +#ifndef ZIC_BLOAT_DEFAULT +# define ZIC_BLOAT_DEFAULT "fat" +#endif + int main(int argc, char **argv) { register int c, k; register ptrdiff_t i, j; + bool timerange_given = false; #ifdef S_IWGRP umask(umask(S_IWGRP | S_IWOTH) | (S_IWGRP | S_IWOTH)); @@ -640,10 +706,22 @@ main(int argc, char **argv) } else if (strcmp(argv[k], "--help") == 0) { usage(stdout, EXIT_SUCCESS); } - while ((c = getopt(argc, argv, "d:l:L:p:st:vy:")) != EOF && c != -1) + while ((c = getopt(argc, argv, "b:d:l:L:p:r:st:vy:")) != EOF && c != -1) switch (c) { default: usage(stderr, EXIT_FAILURE); + case 'b': + if (strcmp(optarg, "slim") == 0) { + if (0 < bloat) + error(_("incompatible -b options")); + bloat = -1; + } else if (strcmp(optarg, "fat") == 0) { + if (bloat < 0) + error(_("incompatible -b options")); + bloat = 1; + } else + error(_("invalid option: -b '%s'"), optarg); + break; case 'd': if (directory == NULL) directory = optarg; @@ -708,12 +786,29 @@ _("%s: More than one -L option specified\n"), case 'v': noise = true; break; + case 'r': + if (timerange_given) { + fprintf(stderr, +_("%s: More than one -r option specified\n"), + progname); + return EXIT_FAILURE; + } + if (! timerange_option(optarg)) { + fprintf(stderr, +_("%s: invalid time range: %s\n"), + progname, optarg); + return EXIT_FAILURE; + } + timerange_given = true; + break; case 's': warning(_("-s ignored")); break; } if (optind == argc - 1 && strcmp(argv[optind], "=") == 0) usage(stderr, EXIT_FAILURE); /* usage message by request */ + if (bloat == 0) + bloat = strcmp(ZIC_BLOAT_DEFAULT, "slim") == 0 ? -1 : 1; if (directory == NULL) directory = TZDIR; if (tzdefault == NULL) @@ -961,11 +1056,6 @@ dolink(char const *fromfield, char const *tofield, bool staysymlink) } } -#define TIME_T_BITS_IN_FILE 64 - -static zic_t const min_time = MINVAL(zic_t, TIME_T_BITS_IN_FILE); -static zic_t const max_time = MAXVAL(zic_t, TIME_T_BITS_IN_FILE); - /* Return true if NAME is a directory. */ static bool itsdir(char const *name) @@ -1072,7 +1162,7 @@ associate(void) ** Maybe we have a local standard time offset. */ eat(zp->z_filename, zp->z_linenum); - zp->z_stdoff = getstdoff(zp->z_rule, &zp->z_isdst); + zp->z_save = getsave(zp->z_rule, &zp->z_isdst); /* ** Note, though, that if there's no rule, ** a '%s' in the format is a bad thing. @@ -1128,7 +1218,8 @@ infile(const char *name) ++nfields; } if (nfields == 0) { - /* nothing to do */ + if (name == leapsec && *buf == '#') + sscanf(buf, "#expires %"SCNdZIC, &comment_leapexpires); } else if (wantcont) { wantcont = inzcont(fields, nfields); } else { @@ -1153,6 +1244,10 @@ infile(const char *name) inleap(fields, nfields); wantcont = false; break; + case LC_EXPIRES: + inexpires(fields, nfields); + wantcont = false; + break; default: /* "cannot happen" */ fprintf(stderr, _("%s: panic: Invalid l_value %d\n"), @@ -1230,10 +1325,10 @@ warning(_("values over 24 hours not handled by pre-2007 versions of zic")); } static zic_t -getstdoff(char *field, bool *isdst) +getsave(char *field, bool *isdst) { int dst = -1; - zic_t stdoff; + zic_t save; size_t fieldlen = strlen(field); if (fieldlen != 0) { char *ep = field + fieldlen - 1; @@ -1242,9 +1337,9 @@ getstdoff(char *field, bool *isdst) case 's': dst = 0; *ep = '\0'; break; } } - stdoff = gethms(field, _("invalid saved time")); - *isdst = dst < 0 ? stdoff != 0 : dst; - return stdoff; + save = gethms(field, _("invalid saved time")); + *isdst = dst < 0 ? save != 0 : dst; + return save; } static void @@ -1267,7 +1362,7 @@ inrule(char **fields, int nfields) } r.r_filename = filename; r.r_linenum = linenum; - r.r_stdoff = getstdoff(fields[RF_STDOFF], &r.r_isdst); + r.r_save = getsave(fields[RF_SAVE], &r.r_isdst); 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]); @@ -1328,13 +1423,13 @@ inzsub(char **fields, int nfields, bool iscont) register char * cp; char * cp1; static struct zone z; - register int i_gmtoff, i_rule, i_format; + register int i_stdoff, i_rule, i_format; register int i_untilyear, i_untilmonth; register int i_untilday, i_untiltime; register bool hasuntil; if (iscont) { - i_gmtoff = ZFC_GMTOFF; + i_stdoff = ZFC_STDOFF; i_rule = ZFC_RULE; i_format = ZFC_FORMAT; i_untilyear = ZFC_TILYEAR; @@ -1345,7 +1440,7 @@ inzsub(char **fields, int nfields, bool iscont) } else if (!namecheck(fields[ZF_NAME])) return false; else { - i_gmtoff = ZF_GMTOFF; + i_stdoff = ZF_STDOFF; i_rule = ZF_RULE; i_format = ZF_FORMAT; i_untilyear = ZF_TILYEAR; @@ -1356,7 +1451,7 @@ inzsub(char **fields, int nfields, bool iscont) } z.z_filename = filename; z.z_linenum = linenum; - z.z_gmtoff = gethms(fields[i_gmtoff], _("invalid UT offset")); + z.z_stdoff = gethms(fields[i_stdoff], _("invalid UT offset")); if ((cp = strchr(fields[i_format], '%')) != 0) { if ((*++cp != 's' && *cp != 'z') || strchr(cp, '%') || strchr(fields[i_format], '/')) { @@ -1410,8 +1505,8 @@ inzsub(char **fields, int nfields, bool iscont) return hasuntil; } -static void -inleap(char **fields, int nfields) +static zic_t +getleapdatetime(char **fields, int nfields, bool expire_line) { register const char * cp; register const struct lookup * lp; @@ -1422,10 +1517,6 @@ inleap(char **fields, int nfields) zic_t t; char xs; - if (nfields != LEAP_FIELDS) { - error(_("wrong number of fields on Leap line")); - return; - } dayoff = 0; cp = fields[LP_YEAR]; if (sscanf(cp, "%"SCNdZIC"%c", &year, &xs) != 1) { @@ -1433,13 +1524,15 @@ inleap(char **fields, int nfields) ** Leapin' Lizards! */ error(_("invalid leaping year")); - return; + return -1; } - if (!leapseen || leapmaxyear < year) + if (!expire_line) { + if (!leapseen || leapmaxyear < year) leapmaxyear = year; - if (!leapseen || leapminyear > year) + if (!leapseen || leapminyear > year) leapminyear = year; - leapseen = true; + leapseen = true; + } j = EPOCH_YEAR; while (j != year) { if (year > j) { @@ -1453,7 +1546,7 @@ inleap(char **fields, int nfields) } if ((lp = byword(fields[LP_MONTH], mon_names)) == NULL) { error(_("invalid month name")); - return; + return -1; } month = lp->l_value; j = TM_JANUARY; @@ -1466,47 +1559,60 @@ inleap(char **fields, int nfields) if (sscanf(cp, "%d%c", &day, &xs) != 1 || day <= 0 || day > len_months[isleap(year)][month]) { error(_("invalid day of month")); - return; + return -1; } dayoff = oadd(dayoff, day - 1); if (dayoff < min_time / SECSPERDAY) { error(_("time too small")); - return; + return -1; } if (dayoff > max_time / SECSPERDAY) { error(_("time too large")); - return; + return -1; } t = dayoff * SECSPERDAY; tod = gethms(fields[LP_TIME], _("invalid time of day")); - cp = fields[LP_CORR]; - { - register bool positive; - int count; - - if (strcmp(cp, "") == 0) { /* infile() turns "-" into "" */ - positive = false; - count = 1; - } else if (strcmp(cp, "+") == 0) { - positive = true; - count = 1; - } else { - 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" - )); - return; - } - t = tadd(t, tod); - if (t < 0) { - error(_("leap second precedes Epoch")); - return; - } - leapadd(t, positive, lp->l_value, count); - } + t = tadd(t, tod); + if (t < 0) + error(_("leap second precedes Epoch")); + return t; +} + +static void +inleap(char **fields, int nfields) +{ + if (nfields != LEAP_FIELDS) + error(_("wrong number of fields on Leap line")); + else { + zic_t t = getleapdatetime(fields, nfields, false); + if (0 <= t) { + struct lookup const *lp = byword(fields[LP_ROLL], leap_types); + if (!lp) + error(_("invalid Rolling/Stationary field on Leap line")); + else { + int correction = 0; + if (!fields[LP_CORR][0]) /* infile() turns "-" into "". */ + correction = -1; + else if (strcmp(fields[LP_CORR], "+") == 0) + correction = 1; + else + error(_("invalid CORRECTION field on Leap line")); + if (correction) + leapadd(t, correction, lp->l_value); + } + } + } +} + +static void +inexpires(char **fields, int nfields) +{ + if (nfields != EXPIRES_FIELDS) + error(_("wrong number of fields on Expires line")); + else if (0 <= leapexpires) + error(_("multiple Expires lines")); + else + leapexpires = getleapdatetime(fields, nfields, true); } static void @@ -1549,26 +1655,26 @@ rulesub(struct rule *rp, const char *loyearp, const char *hiyearp, } rp->r_month = lp->l_value; rp->r_todisstd = false; - rp->r_todisgmt = false; + rp->r_todisut = false; dp = ecpyalloc(timep); if (*dp != '\0') { ep = dp + strlen(dp) - 1; switch (lowerit(*ep)) { case 's': /* Standard */ rp->r_todisstd = true; - rp->r_todisgmt = false; + rp->r_todisut = false; *ep = '\0'; break; case 'w': /* Wall */ rp->r_todisstd = false; - rp->r_todisgmt = false; + rp->r_todisut = false; *ep = '\0'; break; case 'g': /* Greenwich */ case 'u': /* Universal */ case 'z': /* Zulu */ rp->r_todisstd = true; - rp->r_todisgmt = true; + rp->r_todisut = true; *ep = '\0'; break; } @@ -1714,12 +1820,16 @@ puttzcode(const int_fast32_t val, FILE *const fp) } static void -puttzcode64(const zic_t val, FILE *const fp) +puttzcodepass(zic_t val, FILE *fp, int pass) { + if (pass == 1) + puttzcode(val, fp); + else { char buf[8]; |
