diff options
Diffstat (limited to 'time/zic.c')
-rw-r--r-- | time/zic.c | 155 |
1 files changed, 96 insertions, 59 deletions
diff --git a/time/zic.c b/time/zic.c index 73ea46821e..fc1a16bff9 100644 --- a/time/zic.c +++ b/time/zic.c @@ -1,11 +1,14 @@ #ifndef lint #ifndef NOID -static char elsieid[] = "@(#)zic.c 7.28"; +static char elsieid[] = "@(#)zic.c 7.50"; #endif /* !defined NOID */ #endif /* !defined lint */ #include "private.h" #include "tzfile.h" +#ifdef unix +#include "sys/stat.h" /* for umask manifest constants */ +#endif /* defined unix */ struct rule { const char * r_filename; @@ -25,7 +28,7 @@ struct rule { long r_tod; /* time from midnight */ int r_todisstd; /* above is standard time if TRUE */ /* or wall clock time if FALSE */ - int r_todisuniv; /* above is universal time if TRUE */ + int r_todisgmt; /* above is GMT if TRUE */ /* or local time if FALSE */ long r_stdoff; /* offset from standard time */ const char * r_abbrvar; /* variable part of abbreviation */ @@ -60,8 +63,8 @@ struct zone { time_t z_untiltime; }; -extern int emkdir P((const char * name, int mode)); -extern int getopt P((int argc, char * argv[], const char * options)); +extern int getopt P((int argc, char * const argv[], + const char * options)); extern char * icatalloc P((char * old, const char * new)); extern char * icpyalloc P((const char * string)); extern void ifree P((char * p)); @@ -74,13 +77,15 @@ extern char * scheck P((const char * string, const char * format)); static void addtt P((time_t starttime, int type)); static int addtype P((long gmtoff, const char * abbr, int isdst, - int ttisstd)); + int ttisstd, int ttisgmt)); static void leapadd P((time_t t, int positive, int rolling, int count)); static void adjleap P((void)); static void associate P((void)); static int ciequal P((const char * ap, const char * bp)); static void convert P((long val, char * buf)); static void dolink P((const char * fromfile, const char * tofile)); +static void doabbr P((char * abbr, const char * format, + const char * letters, int isdst)); static void eat P((const char * name, int num)); static void eats P((const char * name, int num, const char * rname, int rnum)); @@ -105,7 +110,7 @@ static void newabbr P((const char * abbr)); static long oadd P((long t1, long t2)); static void outzone P((const struct zone * zp, int ntzones)); static void puttzcode P((long code, FILE * fp)); -static int rcomp P((const genericptr_T leftp, const genericptr_T rightp)); +static int rcomp P((const void * leftp, const void * rightp)); static time_t rpytime P((const struct rule * rp, int wantedy)); static void rulesub P((struct rule * rp, const char * loyearp, const char * hiyearp, @@ -321,6 +326,7 @@ static long gmtoffs[TZ_MAX_TYPES]; static char isdsts[TZ_MAX_TYPES]; static unsigned char abbrinds[TZ_MAX_TYPES]; static char ttisstds[TZ_MAX_TYPES]; +static char ttisgmts[TZ_MAX_TYPES]; static char chars[TZ_MAX_CHARS]; static time_t trans[TZ_MAX_LEAPS]; static long corr[TZ_MAX_LEAPS]; @@ -377,7 +383,7 @@ const char * const string; { /* ** Match the format of "cc" to allow sh users to - ** zic ... 2>&1 | error -t "*" -v + ** zic ... 2>&1 | error -t "*" -v ** on BSD systems. */ (void) fprintf(stderr, "\"%s\", line %d: %s", @@ -392,8 +398,8 @@ const char * const string; static void usage P((void)) { - (void) fprintf(stderr, -"%s: usage is %s [ -s ] [ -v ] [ -l localtime ] [ -p posixrules ] [ -d directory ] \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); @@ -411,11 +417,12 @@ main(argc, argv) int argc; char * argv[]; { - register int i, j; + register int i; + register int j; register int c; #ifdef unix - (void) umask(umask(022) | 022); + (void) umask(umask(S_IWGRP | S_IWOTH) | (S_IWGRP | S_IWOTH)); #endif /* defined unix */ progname = argv[0]; while ((c = getopt(argc, argv, "d:l:p:L:vsy:")) != EOF) @@ -601,7 +608,7 @@ const char * const name; myname = ecpyalloc(name); myname = ecatalloc(myname, "/."); - accres = access(myname, 0); + accres = access(myname, F_OK); ifree(myname); return accres == 0; } @@ -616,11 +623,11 @@ const char * const name; static int rcomp(cp1, cp2) -const genericptr_T cp1; -const genericptr_T cp2; +const void * cp1; +const void * cp2; { - return strcmp(((struct rule *) cp1)->r_name, - ((struct rule *) cp2)->r_name); + return strcmp(((const struct rule *) cp1)->r_name, + ((const struct rule *) cp2)->r_name); } static void @@ -632,9 +639,8 @@ associate P((void)) register int i; if (nrules != 0) - (void) qsort((genericptr_T) rules, - (qsort_size_T) nrules, - (qsort_size_T) sizeof *rules, rcomp); + (void) qsort((void *) rules, (size_t) nrules, + (size_t) sizeof *rules, rcomp); for (i = 0; i < nzones; ++i) { zp = &zones[i]; zp->z_rules = NULL; @@ -767,7 +773,7 @@ const char * name; /* ** Convert a string of one of the forms -** h -h hh:mm -hh:mm hh:mm:ss -hh:mm:ss +** h -h hh:mm -hh:mm hh:mm:ss -hh:mm:ss ** into a number of seconds. ** A null string maps to zero. ** Call error with errstring and return zero on errors. @@ -956,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; } } @@ -1115,25 +1122,25 @@ const char * const timep; } rp->r_month = lp->l_value; rp->r_todisstd = FALSE; - rp->r_todisuniv = FALSE; + rp->r_todisgmt = FALSE; dp = ecpyalloc(timep); if (*dp != '\0') { ep = dp + strlen(dp) - 1; switch (lowerit(*ep)) { case 's': /* Standard */ rp->r_todisstd = TRUE; - rp->r_todisuniv = FALSE; + rp->r_todisgmt = FALSE; *ep = '\0'; break; case 'w': /* Wall */ rp->r_todisstd = FALSE; - rp->r_todisuniv = FALSE; + rp->r_todisgmt = FALSE; *ep = '\0'; case 'g': /* Greenwich */ case 'u': /* Universal */ case 'z': /* Zulu */ rp->r_todisstd = TRUE; - rp->r_todisuniv = TRUE; + rp->r_todisgmt = TRUE; *ep = '\0'; break; } @@ -1144,7 +1151,8 @@ const char * const timep; ** Year work. */ cp = loyearp; - if ((lp = byword(cp, begin_years)) != NULL) switch ((int) lp->l_value) { + lp = byword(cp, begin_years); + if (lp != NULL) switch ((int) lp->l_value) { case YR_MINIMUM: rp->r_loyear = min_int; break; @@ -1260,9 +1268,7 @@ FILE * const fp; char buf[4]; convert(val, buf); - (void) fwrite((genericptr_T) buf, - (fwrite_size_T) sizeof buf, - (fwrite_size_T) 1, fp); + (void) fwrite((void *) buf, (size_t) sizeof buf, (size_t) 1, fp); } static void @@ -1286,14 +1292,22 @@ const char * const name; (void) exit(EXIT_FAILURE); } } + convert(eitol(typecnt), tzh.tzh_ttisgmtcnt); convert(eitol(typecnt), tzh.tzh_ttisstdcnt); convert(eitol(leapcnt), tzh.tzh_leapcnt); convert(eitol(timecnt), tzh.tzh_timecnt); convert(eitol(typecnt), tzh.tzh_typecnt); convert(eitol(charcnt), tzh.tzh_charcnt); - (void) fwrite((genericptr_T) &tzh, - (fwrite_size_T) sizeof tzh, - (fwrite_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); + DO(tzh_leapcnt); + DO(tzh_timecnt); + DO(tzh_typecnt); + DO(tzh_charcnt); +#undef DO for (i = 0; i < timecnt; ++i) { j = leapcnt; while (--j >= 0) @@ -1304,18 +1318,16 @@ const char * const name; puttzcode((long) ats[i], fp); } if (timecnt > 0) - (void) fwrite((genericptr_T) types, - (fwrite_size_T) sizeof types[0], - (fwrite_size_T) timecnt, fp); + (void) fwrite((void *) types, (size_t) sizeof types[0], + (size_t) timecnt, fp); for (i = 0; i < typecnt; ++i) { puttzcode((long) gmtoffs[i], fp); (void) putc(isdsts[i], fp); (void) putc(abbrinds[i], fp); } if (charcnt != 0) - (void) fwrite((genericptr_T) chars, - (fwrite_size_T) sizeof chars[0], - (fwrite_size_T) charcnt, fp); + (void) fwrite((void *) chars, (size_t) sizeof chars[0], + (size_t) charcnt, fp); for (i = 0; i < leapcnt; ++i) { if (roll[i]) { if (timecnt == 0 || trans[i] < ats[0]) { @@ -1337,6 +1349,8 @@ const char * const name; } for (i = 0; i < typecnt; ++i) (void) putc(ttisstds[i], fp); + for (i = 0; i < typecnt; ++i) + (void) putc(ttisgmts[i], fp); if (ferror(fp) || fclose(fp)) { (void) fprintf(stderr, "%s: Write error on ", progname); (void) perror(fullname); @@ -1345,6 +1359,25 @@ const char * const name; } static void +doabbr(abbr, format, letters, isdst) +char * const abbr; +const char * const format; +const char * const letters; +const int isdst; +{ + if (strchr(format, '/') == NULL) { + if (letters == NULL) + (void) strcpy(abbr, format); + else (void) sprintf(abbr, format, letters); + } else if (isdst) + (void) strcpy(abbr, strchr(format, '/') + 1); + else { + (void) strcpy(abbr, format); + *strchr(abbr, '/') = '\0'; + } +} + +static void outzone(zpfirst, zonecount) const struct zone * const zpfirst; const int zonecount; @@ -1360,6 +1393,7 @@ const int zonecount; register long startoff; register int startisdst; register int startttisstd; + register int startttisgmt; register int type; char startbuf[BUFSIZ]; @@ -1381,9 +1415,7 @@ const int zonecount; ** for noting the need to unconditionally initialize startttisstd. */ startttisstd = FALSE; -#ifdef lint - starttime = 0; -#endif /* defined lint */ + startttisgmt = FALSE; for (i = 0; i < zonecount; ++i) { zp = &zpfirst[i]; usestart = i > 0 && (zp - 1)->z_untiltime > min_time; @@ -1395,9 +1427,11 @@ const int zonecount; startisdst = -1; if (zp->z_nrules == 0) { stdoff = zp->z_stdoff; - (void) strcpy(startbuf, zp->z_format); + doabbr(startbuf, zp->z_format, + (char *) NULL, stdoff != 0); type = addtype(oadd(zp->z_gmtoff, stdoff), - startbuf, stdoff != 0, startttisstd); + startbuf, stdoff != 0, startttisstd, + startttisgmt); if (usestart) addtt(starttime, type); else if (stdoff != 0) @@ -1433,7 +1467,7 @@ const int zonecount; ** stdoff values. */ untiltime = zp->z_untiltime; - if (!zp->z_untilrule.r_todisuniv) + if (!zp->z_untilrule.r_todisgmt) untiltime = tadd(untiltime, -gmtoff); if (!zp->z_untilrule.r_todisstd) @@ -1445,16 +1479,13 @@ const int zonecount; ** that takes effect earliest in the year. */ k = -1; -#ifdef lint - ktime = 0; -#endif /* defined lint */ for (j = 0; j < zp->z_nrules; ++j) { rp = &zp->z_rules[j]; if (!rp->r_todo) continue; eats(zp->z_filename, zp->z_linenum, rp->r_filename, rp->r_linenum); - offset = rp->r_todisuniv ? 0 : gmtoff; + offset = rp->r_todisgmt ? 0 : gmtoff; if (!rp->r_todisstd) offset = oadd(offset, stdoff); jtime = rp->r_temp; @@ -1478,8 +1509,9 @@ const int zonecount; stdoff = rp->r_stdoff; startoff = oadd(zp->z_gmtoff, rp->r_stdoff); - (void) sprintf(startbuf, zp->z_format, - rp->r_abbrvar); + doabbr(startbuf, zp->z_format, + rp->r_abbrvar, + rp->r_stdoff != 0); startisdst = rp->r_stdoff != 0; continue; } @@ -1496,19 +1528,20 @@ const int zonecount; startoff = oadd(startoff, zp->z_gmtoff); (void) strcpy(startbuf, - &chars[abbrinds[type]]); + &chars[abbrinds[type]]); } if (startisdst >= 0) -addtt(starttime, addtype(startoff, startbuf, startisdst, startttisstd)); +addtt(starttime, addtype(startoff, startbuf, startisdst, startttisstd, + startttisgmt)); } } eats(zp->z_filename, zp->z_linenum, rp->r_filename, rp->r_linenum); - (void) sprintf(buf, zp->z_format, - rp->r_abbrvar); + doabbr(buf, zp->z_format, rp->r_abbrvar, + rp->r_stdoff != 0); offset = oadd(zp->z_gmtoff, rp->r_stdoff); type = addtype(offset, buf, rp->r_stdoff != 0, - rp->r_todisstd); + rp->r_todisstd, rp->r_todisgmt); addtt(ktime, type); stdoff = rp->r_stdoff; } @@ -1519,6 +1552,7 @@ addtt(starttime, addtype(startoff, startbuf, startisdst, startttisstd)); if (useuntil) { starttime = tadd(zp->z_untiltime, -gmtoff); startttisstd = zp->z_untilrule.r_todisstd; + startttisgmt = zp->z_untilrule.r_todisgmt; if (!startttisstd) starttime = tadd(starttime, -stdoff); } @@ -1545,11 +1579,12 @@ const int type; } static int -addtype(gmtoff, abbr, isdst, ttisstd) +addtype(gmtoff, abbr, isdst, ttisstd, ttisgmt) const long gmtoff; const char * const abbr; const int isdst; const int ttisstd; +const int ttisgmt; { register int i, j; @@ -1560,7 +1595,8 @@ const int ttisstd; for (i = 0; i < typecnt; ++i) { if (gmtoff == gmtoffs[i] && isdst == isdsts[i] && strcmp(abbr, &chars[abbrinds[i]]) == 0 && - ttisstd == ttisstds[i]) + ttisstd == ttisstds[i] && + ttisgmt == ttisgmts[i]) return i; } /* @@ -1574,6 +1610,7 @@ const int ttisstd; gmtoffs[i] = gmtoff; isdsts[i] = isdst; ttisstds[i] = ttisstd; + ttisgmts[i] = ttisgmt; for (j = 0; j < charcnt; ++j) if (strcmp(&chars[j], abbr) == 0) @@ -1908,7 +1945,7 @@ char * const argname; *cp = '\0'; #ifndef unix /* - ** MS-DOS drive specifier? + ** DOS drive specifier? */ if (strlen(name) == 2 && isascii(name[0]) && isalpha(name[0]) && name[1] == ':') { @@ -1920,7 +1957,7 @@ char * const argname; /* ** It doesn't seem to exist, so we try to create it. */ - if (emkdir(name, 0755) != 0) { + if (mkdir(name, 0755) != 0) { (void) fprintf(stderr, "%s: Can't create directory ", progname); |