Back to index

glibc  2.9
Classes | Defines | Typedefs | Functions | Variables
zic.c File Reference
#include "private.h"
#include "locale.h"
#include "tzfile.h"
#include "sys/stat.h"
#include "ctype.h"

Go to the source code of this file.

Classes

struct  rule
struct  zone
struct  lookup
struct  attype

Defines

#define ZIC_VERSION   '2'
#define ZIC_MAX_ABBR_LEN_WO_WARN   6
#define MKDIR_UMASK   0755
#define isascii(x)   1
#define OFFSET_STRLEN_MAXIMUM   (7 + INT_STRLEN_MAXIMUM(long))
#define RULE_STRLEN_MAXIMUM   8 /* "Mdd.dd.d" */
#define end(cp)   (strchr((cp), '\0'))
#define DC_DOM   0 /* 1..31 */ /* unused */
#define DC_DOWGEQ   1 /* 1..31 */ /* 0..6 (Sun..Sat) */
#define DC_DOWLEQ   2 /* 1..31 */ /* 0..6 (Sun..Sat) */
#define LC_RULE   0
#define LC_ZONE   1
#define LC_LINK   2
#define LC_LEAP   3
#define ZF_NAME   1
#define ZF_GMTOFF   2
#define ZF_RULE   3
#define ZF_FORMAT   4
#define ZF_TILYEAR   5
#define ZF_TILMONTH   6
#define ZF_TILDAY   7
#define ZF_TILTIME   8
#define ZONE_MINFIELDS   5
#define ZONE_MAXFIELDS   9
#define ZFC_GMTOFF   0
#define ZFC_RULE   1
#define ZFC_FORMAT   2
#define ZFC_TILYEAR   3
#define ZFC_TILMONTH   4
#define ZFC_TILDAY   5
#define ZFC_TILTIME   6
#define ZONEC_MINFIELDS   3
#define ZONEC_MAXFIELDS   7
#define RF_NAME   1
#define RF_LOYEAR   2
#define RF_HIYEAR   3
#define RF_COMMAND   4
#define RF_MONTH   5
#define RF_DAY   6
#define RF_TOD   7
#define RF_STDOFF   8
#define RF_ABBRVAR   9
#define RULE_FIELDS   10
#define LF_FROM   1
#define LF_TO   2
#define LINK_FIELDS   3
#define LP_YEAR   1
#define LP_MONTH   2
#define LP_DAY   3
#define LP_TIME   4
#define LP_CORR   5
#define LP_ROLL   6
#define LEAP_FIELDS   7
#define YR_MINIMUM   0
#define YR_MAXIMUM   1
#define YR_ONLY   2
#define emalloc(size)   memcheck(imalloc(size))
#define erealloc(ptr, size)   memcheck(irealloc((ptr), (size)))
#define ecpyalloc(ptr)   memcheck(icpyalloc(ptr))
#define ecatalloc(oldp, newp)   memcheck(icatalloc((oldp), (newp)))
#define TIME_T_BITS_IN_FILE   64
#define DO(field)
#define LDAYSPERWEEK   ((long) DAYSPERWEEK)

Typedefs

typedef int_fast64_t zic_t

Functions

int getopt (int argc, char *const argv[], const char *options)
int link (const char *fromname, const char *toname)
static void addtt (zic_t starttime, int type)
static int addtype (long gmtoff, const char *abbr, int isdst, int ttisstd, int ttisgmt)
static void leapadd (zic_t t, int positive, int rolling, int count)
static void adjleap (void)
static void associate (void)
static int ciequal (const char *ap, const char *bp)
static void convert (long val, char *buf)
static void convert64 (zic_t val, char *buf)
static void dolink (const char *fromfield, const char *tofield)
static void doabbr (char *abbr, const char *format, const char *letters, int isdst, int doquotes)
static void eat (const char *name, int num)
static void eats (const char *name, int num, const char *rname, int rnum)
static long eitol (int i)
static void error (const char *message)
static char ** getfields (char *buf)
static long gethms (const char *string, const char *errstrng, int signable)
static void infile (const char *filename)
static void inleap (char **fields, int nfields)
static void inlink (char **fields, int nfields)
static void inrule (char **fields, int nfields)
static int inzcont (char **fields, int nfields)
static int inzone (char **fields, int nfields)
static int inzsub (char **fields, int nfields, int iscont)
static int is32 (zic_t x)
static int itsabbr (const char *abbr, const char *word)
static int itsdir (const char *name)
static int lowerit (int c)
static char * memcheck (char *tocheck)
static int mkdirs (char *filename)
static void newabbr (const char *abbr)
static long oadd (long t1, long t2)
static void outzone (const struct zone *zp, int ntzones)
static void puttzcode (long code, FILE *fp)
static void puttzcode64 (zic_t code, FILE *fp)
static int rcomp (const void *leftp, const void *rightp)
static zic_t rpytime (const struct rule *rp, int wantedy)
static void rulesub (struct rule *rp, const char *loyearp, const char *hiyearp, const char *typep, const char *monthp, const char *dayp, const char *timep)
static int stringoffset (char *result, long offset)
static int stringrule (char *result, const struct rule *rp, long dstoff, long gmtoff)
static void stringzone (char *result, const struct zone *zp, int ntzones)
static void setboundaries (void)
static zic_t tadd (zic_t t1, long t2)
static void usage (void)
static void writezone (const char *name, const char *string)
static int yearistype (int year, const char *type)
static struct lookupbyword (const char *string, const struct lookup *lp)
static void eats (char *const name, const int num, const char *const rname, const int rnum) const
static void eat (char *const name, const int num) const
static void error (char *const string) const
static void warning (char *const string) const
int main (int argc, argv)
static void dolink (char *const fromfield, const char *const tofield) const
static int itsdir (char *const name) const
static int rcomp (void *cp1, const void *cp2) const
static void infile (char *name) const
static long gethms (char *string, const char *const errstring, const int signable) const
static int atcomp (void *avp, const void *bvp) const
static void writezone (char *const name, const char *const string) const
static void updateminmax (int x) const
static void outzone (struct zone *const zpfirst, const int zonecount) const
static void newabbr (char *const string) const

Variables

static char elsieid [] = "@(#)zic.c 8.17"
char * optarg
int optind
static int charcnt
static int errors
static const char * filename
static int leapcnt
static int leapseen
static int leapminyear
static int leapmaxyear
static int linenum
static int max_abbrvar_len
static int max_format_len
static zic_t max_time
static int max_year
static zic_t min_time
static int min_year
static int noise
static const char * rfilename
static int rlinenum
static const char * progname
static int timecnt
static int typecnt
static struct rulerules
static int nrules
static struct zonezones
static int nzones
static struct linklinks
static int nlinks
static struct lookup []
static const int len_months [2][MONSPERYEAR]
static const int len_years [2]
static struct attype attypes [TZ_MAX_TIMES]
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 zic_t trans [TZ_MAX_LEAPS]
static long corr [TZ_MAX_LEAPS]
static char roll [TZ_MAX_LEAPS]
static const char * psxrules
static const char * lcltime
static const char * directory
static const char * leapsec
static const char * yitcommand

Class Documentation

struct rule

Definition at line 47 of file zic.c.

Class Members
const char * r_abbrvar
int r_dayofmonth
int r_dycode
const char * r_filename
int r_hiwasnum
int r_hiyear
int r_linenum
int r_lowasnum
int r_loyear
int r_month
const char * r_name
long r_stdoff
zic_t r_temp
long r_tod
int r_todisgmt
int r_todisstd
int r_todo
int r_wday
const char * r_yrtype
struct zone

Definition at line 84 of file zic.c.

Collaboration diagram for zone:
Class Members
const char * z_filename
const char * z_format
long z_gmtoff
int z_linenum
const char * z_name
int z_nrules
const char * z_rule
struct rule * z_rules
long z_stdoff
zic_t z_untiltime
struct link

Definition at line 271 of file zic.c.

Class Members
const char * l_filename
const char * l_from
int l_linenum
const char * l_to
struct lookup

Definition at line 281 of file zic.c.

Class Members
const int l_value
const char * l_word
struct attype

Definition at line 363 of file zic.c.

Class Members
zic_t at
unsigned char type

Define Documentation

#define DC_DOM   0 /* 1..31 */ /* unused */

Definition at line 80 of file zic.c.

#define DC_DOWGEQ   1 /* 1..31 */ /* 0..6 (Sun..Sat) */

Definition at line 81 of file zic.c.

#define DC_DOWLEQ   2 /* 1..31 */ /* 0..6 (Sun..Sat) */

Definition at line 82 of file zic.c.

#define DO (   field)
Value:
(void) fwrite((void *) tzh.field, \
                            (size_t) sizeof tzh.field, (size_t) 1, fp)
#define ecatalloc (   oldp,
  newp 
)    memcheck(icatalloc((oldp), (newp)))

Definition at line 398 of file zic.c.

#define ecpyalloc (   ptr)    memcheck(icpyalloc(ptr))

Definition at line 397 of file zic.c.

#define emalloc (   size)    memcheck(imalloc(size))

Definition at line 395 of file zic.c.

#define end (   cp)    (strchr((cp), '\0'))

Definition at line 45 of file zic.c.

#define erealloc (   ptr,
  size 
)    memcheck(irealloc((ptr), (size)))

Definition at line 396 of file zic.c.

#define isascii (   x)    1

Definition at line 39 of file zic.c.

#define LC_LEAP   3

Definition at line 191 of file zic.c.

#define LC_LINK   2

Definition at line 190 of file zic.c.

#define LC_RULE   0

Definition at line 188 of file zic.c.

#define LC_ZONE   1

Definition at line 189 of file zic.c.

#define LDAYSPERWEEK   ((long) DAYSPERWEEK)
#define LEAP_FIELDS   7

Definition at line 255 of file zic.c.

#define LF_FROM   1

Definition at line 241 of file zic.c.

#define LF_TO   2

Definition at line 242 of file zic.c.

#define LINK_FIELDS   3

Definition at line 243 of file zic.c.

#define LP_CORR   5

Definition at line 253 of file zic.c.

#define LP_DAY   3

Definition at line 251 of file zic.c.

#define LP_MONTH   2

Definition at line 250 of file zic.c.

#define LP_ROLL   6

Definition at line 254 of file zic.c.

#define LP_TIME   4

Definition at line 252 of file zic.c.

#define LP_YEAR   1

Definition at line 249 of file zic.c.

#define MKDIR_UMASK   0755

Definition at line 26 of file zic.c.

#define OFFSET_STRLEN_MAXIMUM   (7 + INT_STRLEN_MAXIMUM(long))

Definition at line 42 of file zic.c.

#define RF_ABBRVAR   9

Definition at line 234 of file zic.c.

#define RF_COMMAND   4

Definition at line 229 of file zic.c.

#define RF_DAY   6

Definition at line 231 of file zic.c.

#define RF_HIYEAR   3

Definition at line 228 of file zic.c.

#define RF_LOYEAR   2

Definition at line 227 of file zic.c.

#define RF_MONTH   5

Definition at line 230 of file zic.c.

#define RF_NAME   1

Definition at line 226 of file zic.c.

#define RF_STDOFF   8

Definition at line 233 of file zic.c.

#define RF_TOD   7

Definition at line 232 of file zic.c.

#define RULE_FIELDS   10

Definition at line 235 of file zic.c.

#define RULE_STRLEN_MAXIMUM   8 /* "Mdd.dd.d" */

Definition at line 43 of file zic.c.

#define TIME_T_BITS_IN_FILE   64

Definition at line 682 of file zic.c.

#define YR_MAXIMUM   1

Definition at line 262 of file zic.c.

#define YR_MINIMUM   0

Definition at line 261 of file zic.c.

#define YR_ONLY   2

Definition at line 263 of file zic.c.

#define ZF_FORMAT   4

Definition at line 200 of file zic.c.

#define ZF_GMTOFF   2

Definition at line 198 of file zic.c.

#define ZF_NAME   1

Definition at line 197 of file zic.c.

#define ZF_RULE   3

Definition at line 199 of file zic.c.

#define ZF_TILDAY   7

Definition at line 203 of file zic.c.

#define ZF_TILMONTH   6

Definition at line 202 of file zic.c.

#define ZF_TILTIME   8

Definition at line 204 of file zic.c.

#define ZF_TILYEAR   5

Definition at line 201 of file zic.c.

#define ZFC_FORMAT   2

Definition at line 214 of file zic.c.

#define ZFC_GMTOFF   0

Definition at line 212 of file zic.c.

#define ZFC_RULE   1

Definition at line 213 of file zic.c.

#define ZFC_TILDAY   5

Definition at line 217 of file zic.c.

#define ZFC_TILMONTH   4

Definition at line 216 of file zic.c.

#define ZFC_TILTIME   6

Definition at line 218 of file zic.c.

#define ZFC_TILYEAR   3

Definition at line 215 of file zic.c.

#define ZIC_MAX_ABBR_LEN_WO_WARN   6

Definition at line 17 of file zic.c.

#define ZIC_VERSION   '2'

Definition at line 12 of file zic.c.

#define ZONE_MAXFIELDS   9

Definition at line 206 of file zic.c.

#define ZONE_MINFIELDS   5

Definition at line 205 of file zic.c.

#define ZONEC_MAXFIELDS   7

Definition at line 220 of file zic.c.

#define ZONEC_MINFIELDS   3

Definition at line 219 of file zic.c.


Typedef Documentation

Definition at line 14 of file zic.c.


Function Documentation

static void addtt ( zic_t  starttime,
int  type 
) [static]

Definition at line 2199 of file zic.c.

{
       if (starttime <= min_time ||
              (timecnt == 1 && attypes[0].at < min_time)) {
              gmtoffs[0] = gmtoffs[type];
              isdsts[0] = isdsts[type];
              ttisstds[0] = ttisstds[type];
              ttisgmts[0] = ttisgmts[type];
              if (abbrinds[type] != 0)
                     (void) strcpy(chars, &chars[abbrinds[type]]);
              abbrinds[0] = 0;
              charcnt = strlen(chars) + 1;
              typecnt = 1;
              timecnt = 0;
              type = 0;
       }
       if (timecnt >= TZ_MAX_TIMES) {
              error(_("too many transitions?!"));
              exit(EXIT_FAILURE);
       }
       attypes[timecnt].at = starttime;
       attypes[timecnt].type = type;
       ++timecnt;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static int addtype ( long  gmtoff,
const char *  abbr,
int  isdst,
int  ttisstd,
int  ttisgmt 
) [static]

Definition at line 2227 of file zic.c.

{
       register int  i, j;

       if (isdst != TRUE && isdst != FALSE) {
              error(_("internal error - addtype called with bad isdst"));
              exit(EXIT_FAILURE);
       }
       if (ttisstd != TRUE && ttisstd != FALSE) {
              error(_("internal error - addtype called with bad ttisstd"));
              exit(EXIT_FAILURE);
       }
       if (ttisgmt != TRUE && ttisgmt != FALSE) {
              error(_("internal error - addtype called with bad ttisgmt"));
              exit(EXIT_FAILURE);
       }
       /*
       ** See if there's already an entry for this zone type.
       ** If so, just return its index.
       */
       for (i = 0; i < typecnt; ++i) {
              if (gmtoff == gmtoffs[i] && isdst == isdsts[i] &&
                     strcmp(abbr, &chars[abbrinds[i]]) == 0 &&
                     ttisstd == ttisstds[i] &&
                     ttisgmt == ttisgmts[i])
                            return i;
       }
       /*
       ** There isn't one; add a new one, unless there are already too
       ** many.
       */
       if (typecnt >= TZ_MAX_TYPES) {
              error(_("too many local time types"));
              exit(EXIT_FAILURE);
       }
       if (! (-1L - 2147483647L <= gmtoff && gmtoff <= 2147483647L)) {
              error(_("UTC offset out of range"));
              exit(EXIT_FAILURE);
       }
       gmtoffs[i] = gmtoff;
       isdsts[i] = isdst;
       ttisstds[i] = ttisstd;
       ttisgmts[i] = ttisgmt;

       for (j = 0; j < charcnt; ++j)
              if (strcmp(&chars[j], abbr) == 0)
                     break;
       if (j == charcnt)
              newabbr(abbr);
       abbrinds[i] = j;
       ++typecnt;
       return i;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void adjleap ( void  ) [static]

Definition at line 2321 of file zic.c.

{
       register int  i;
       register long last = 0;

       /*
       ** propagate leap seconds forward
       */
       for (i = 0; i < leapcnt; ++i) {
              trans[i] = tadd(trans[i], last);
              last = corr[i] += last;
       }
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void associate ( void  ) [static]

Definition at line 727 of file zic.c.

{
       register struct zone *      zp;
       register struct rule *      rp;
       register int         base, out;
       register int         i, j;

       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;
              zp->z_nrules = 0;
       }
       for (base = 0; base < nrules; base = out) {
              rp = &rules[base];
              for (out = base + 1; out < nrules; ++out)
                     if (strcmp(rp->r_name, rules[out].r_name) != 0)
                            break;
              for (i = 0; i < nzones; ++i) {
                     zp = &zones[i];
                     if (strcmp(zp->z_rule, rp->r_name) != 0)
                            continue;
                     zp->z_rules = rp;
                     zp->z_nrules = out - base;
              }
       }
       for (i = 0; i < nzones; ++i) {
              zp = &zones[i];
              if (zp->z_nrules == 0) {
                     /*
                     ** 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);
                     /*
                     ** 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"));
              }
       }
       if (errors)
              exit(EXIT_FAILURE);
}

Here is the call graph for this function:

Here is the caller graph for this function:

static int atcomp ( void *  avp,
const void *  bvp 
) const [static]

Definition at line 1448 of file zic.c.

{
       const zic_t   a = ((const struct attype *) avp)->at;
       const zic_t   b = ((const struct attype *) bvp)->at;

       return (a < b) ? -1 : (a > b);
}

Here is the caller graph for this function:

static struct lookup * byword ( const char *  string,
const struct lookup lp 
) [static, read, abstract]

Definition at line 2397 of file zic.c.

{
       register const struct lookup *     foundlp;
       register const struct lookup *     lp;

       if (word == NULL || table == NULL)
              return NULL;
       /*
       ** Look for exact match.
       */
       for (lp = table; lp->l_word != NULL; ++lp)
              if (ciequal(word, lp->l_word))
                     return lp;
       /*
       ** Look for inexact match.
       */
       foundlp = NULL;
       for (lp = table; lp->l_word != NULL; ++lp)
              if (itsabbr(word, lp->l_word)) {
                     if (foundlp == NULL)
                            foundlp = lp;
                     else   return NULL;  /* multiple inexact matches */
              }
       return foundlp;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static int ciequal ( const char *  ap,
const char *  bp 
) [static]

Definition at line 2370 of file zic.c.

{
       while (lowerit(*ap) == lowerit(*bp++))
              if (*ap++ == '\0')
                     return TRUE;
       return FALSE;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void convert ( long  val,
char *  buf 
) [static]
static void convert64 ( zic_t  val,
char *  buf 
) [static]

Definition at line 1414 of file zic.c.

{
       register int  i;
       register int  shift;

       for (i = 0, shift = 56; i < 8; ++i, shift -= 8)
              buf[i] = val >> shift;
}

Here is the caller graph for this function:

static void doabbr ( char *  abbr,
const char *  format,
const char *  letters,
int  isdst,
int  doquotes 
) [static]

Definition at line 1729 of file zic.c.

{
       register char *      cp;
       register char *      slashp;
       register int  len;

       slashp = strchr(format, '/');
       if (slashp == NULL) {
              if (letters == NULL)
                     (void) strcpy(abbr, format);
              else   (void) sprintf(abbr, format, letters);
       } else if (isdst) {
              (void) strcpy(abbr, slashp + 1);
       } else {
              if (slashp > format)
                     (void) strncpy(abbr, format,
                            (unsigned) (slashp - format));
              abbr[slashp - format] = '\0';
       }
       if (!doquotes)
              return;
       for (cp = abbr; *cp != '\0'; ++cp)
              if (strchr("ABCDEFGHIJKLMNOPQRSTUVWXYZ", *cp) == NULL &&
                     strchr("abcdefghijklmnopqrstuvwxyz", *cp) == NULL)
                            break;
       len = strlen(abbr);
       if (len > 0 && *cp == '\0')
              return;
       abbr[len + 2] = '\0';
       abbr[len + 1] = '>';
       for ( ; len > 0; --len)
              abbr[len] = abbr[len - 1];
       abbr[0] = '<';
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void dolink ( const char *  fromfield,
const char *  tofield 
) [static]

Here is the caller graph for this function:

static void dolink ( char * const  fromfield,
const char * const  tofield 
) const [static]

Definition at line 614 of file zic.c.

{
       register char *      fromname;
       register char *      toname;

       if (fromfield[0] == '/')
              fromname = ecpyalloc(fromfield);
       else {
              fromname = ecpyalloc(directory);
              fromname = ecatalloc(fromname, "/");
              fromname = ecatalloc(fromname, fromfield);
       }
       if (tofield[0] == '/')
              toname = ecpyalloc(tofield);
       else {
              toname = ecpyalloc(directory);
              toname = ecatalloc(toname, "/");
              toname = ecatalloc(toname, tofield);
       }
       /*
       ** We get to be careful here since
       ** there's a fair chance of root running us.
       */
       if (!itsdir(toname))
              (void) remove(toname);
       if (link(fromname, toname) != 0) {
              int    result;

              if (mkdirs(toname) != 0)
                     exit(EXIT_FAILURE);

              result = link(fromname, toname);
#if HAVE_SYMLINK
              if (result != 0 &&
                     access(fromname, F_OK) == 0 &&
                     !itsdir(fromname)) {
                            const char *s = tofield;
                            register char * symlinkcontents = NULL;

                            while ((s = strchr(s+1, '/')) != NULL)
                                   symlinkcontents =
                                          ecatalloc(symlinkcontents,
                                          "../");
                            symlinkcontents =
                                   ecatalloc(symlinkcontents,
                                   fromname);
                            result = symlink(symlinkcontents,
                                   toname);
                            if (result == 0)
warning(_("hard link failed, symbolic link used"));
                            ifree(symlinkcontents);
              }
#endif /* HAVE_SYMLINK */
              if (result != 0) {
                     const char *e = strerror(errno);

                     (void) fprintf(stderr,
                            _("%s: Can't link from %s to %s: %s\n"),
                            progname, fromname, toname, e);
                     exit(EXIT_FAILURE);
              }
       }
       ifree(fromname);
       ifree(toname);
}

Here is the call graph for this function:

static void eat ( const char *  name,
int  num 
) [static]

Here is the caller graph for this function:

static void eat ( char * const  name,
const int  num 
) const [static]

Definition at line 418 of file zic.c.

{
       eats(name, num, (char *) NULL, -1);
}

Here is the call graph for this function:

static void eats ( const char *  name,
int  num,
const char *  rname,
int  rnum 
) [static]

Here is the caller graph for this function:

static void eats ( char * const  name,
const int  num,
const char * const  rname,
const int  rnum 
) const [static]

Definition at line 405 of file zic.c.

{
       filename = name;
       linenum = num;
       rfilename = rname;
       rlinenum = rnum;
}
static long eitol ( int  i) [static]

Definition at line 2690 of file zic.c.

{
       long   l;

       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"),
                     progname, i);
              exit(EXIT_FAILURE);
       }
       return l;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void error ( const char *  message) [static]

Definition at line 275 of file rpc_util.c.

{
  printwhere ();
  f_print (stderr, "%s, line %d: ", infilename, linenum);
  f_print (stderr, "%s\n", msg);
  crash ();
}

Here is the call graph for this function:

static void error ( char * const  string) const [static]

Definition at line 426 of file zic.c.

{
       /*
       ** Match the format of "cc" to allow sh users to
       **     zic ... 2>&1 | error -t "*" -v
       ** on BSD systems.
       */
       (void) fprintf(stderr, _("\"%s\", line %d: %s"),
              filename, linenum, string);
       if (rfilename != NULL)
              (void) fprintf(stderr, _(" (rule from \"%s\", line %d)"),
                     rfilename, rlinenum);
       (void) fprintf(stderr, "\n");
       ++errors;
}

Here is the call graph for this function:

static char ** getfields ( char *  buf) [static]

Definition at line 2426 of file zic.c.

{
       register char *             dp;
       register char **     array;
       register int         nsubs;

       if (cp == NULL)
              return NULL;
       array = (char **) (void *)
              emalloc((int) ((strlen(cp) + 1) * sizeof *array));
       nsubs = 0;
       for ( ; ; ) {
              while (isascii((unsigned char) *cp) &&
                     isspace((unsigned char) *cp))
                            ++cp;
              if (*cp == '\0' || *cp == '#')
                     break;
              array[nsubs++] = dp = cp;
              do {
                     if ((*dp = *cp++) != '"')
                            ++dp;
                     else while ((*dp = *cp++) != '"')
                            if (*dp != '\0')
                                   ++dp;
                            else {
                                   error(_(
                                          "Odd number of quotation marks"
                                          ));
                                   exit(1);
                            }
              } while (*cp != '\0' && *cp != '#' &&
                     (!isascii(*cp) || !isspace((unsigned char) *cp)));
              if (isascii(*cp) && isspace((unsigned char) *cp))
                     ++cp;
              *dp = '\0';
       }
       array[nsubs] = NULL;
       return array;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static long gethms ( const char *  string,
const char *  errstrng,
int  signable 
) [static]

Here is the caller graph for this function:

static long gethms ( char *  string,
const char * const  errstring,
const int  signable 
) const [static]

Definition at line 907 of file zic.c.

{
       long   hh;
       int    mm, ss, sign;

       if (string == NULL || *string == '\0')
              return 0;
       if (!signable)
              sign = 1;
       else if (*string == '-') {
              sign = -1;
              ++string;
       } else sign = 1;
       if (sscanf(string, scheck(string, "%ld"), &hh) == 1)
              mm = ss = 0;
       else if (sscanf(string, scheck(string, "%ld:%d"), &hh, &mm) == 2)
              ss = 0;
       else if (sscanf(string, scheck(string, "%ld:%d:%d"),
              &hh, &mm, &ss) != 3) {
                     error(errstring);
                     return 0;
       }
       if (hh < 0 ||
              mm < 0 || mm >= MINSPERHOUR ||
              ss < 0 || ss > SECSPERMIN) {
                     error(errstring);
                     return 0;
       }
       if (LONG_MAX / SECSPERHOUR < hh) {
              error(_("time overflow"));
              return 0;
       }
       if (noise && hh == HOURSPERDAY && mm == 0 && ss == 0)
              warning(_("24:00 not handled by pre-1998 versions of zic"));
       if (noise && (hh > HOURSPERDAY ||
              (hh == HOURSPERDAY && (mm != 0 || ss != 0))))
warning(_("values over 24 hours not handled by pre-2007 versions of zic"));
       return oadd(eitol(sign) * hh * eitol(SECSPERHOUR),
                  eitol(sign) * (eitol(mm) * eitol(SECSPERMIN) + eitol(ss)));
}

Here is the call graph for this function:

int getopt ( int  argc,
char *const  argv[],
const char *  options 
)
static void infile ( const char *  filename) [static]

Here is the caller graph for this function:

static void infile ( char *  name) const [static]

Definition at line 803 of file zic.c.

{
       register FILE *                    fp;
       register char **            fields;
       register char *                    cp;
       register const struct lookup *     lp;
       register int                nfields;
       register int                wantcont;
       register int                num;
       char                        buf[BUFSIZ];

       if (strcmp(name, "-") == 0) {
              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);
              exit(EXIT_FAILURE);
       }
       wantcont = FALSE;
       for (num = 1; ; ++num) {
              eat(name, num);
              if (fgets(buf, (int) sizeof buf, fp) != buf)
                     break;
              cp = strchr(buf, '\n');
              if (cp == NULL) {
                     error(_("line too long"));
                     exit(EXIT_FAILURE);
              }
              *cp = '\0';
              fields = getfields(buf);
              nfields = 0;
              while (fields[nfields] != NULL) {
                     static char   nada;

                     if (strcmp(fields[nfields], "-") == 0)
                            fields[nfields] = &nada;
                     ++nfields;
              }
              if (nfields == 0) {
                     /* nothing to do */
              } else if (wantcont) {
                     wantcont = inzcont(fields, nfields);
              } else {
                     lp = byword(fields[0], line_codes);
                     if (lp == NULL)
                            error(_("input line of unknown type"));
                     else switch ((int) (lp->l_value)) {
                            case LC_RULE:
                                   inrule(fields, nfields);
                                   wantcont = FALSE;
                                   break;
                            case LC_ZONE:
                                   wantcont = inzone(fields, nfields);
                                   break;
                            case LC_LINK:
                                   inlink(fields, nfields);
                                   wantcont = FALSE;
                                   break;
                            case LC_LEAP:
                                   if (name != leapsec)
                                          (void) fprintf(stderr,
_("%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"),
                                          progname, lp->l_value);
                                   exit(EXIT_FAILURE);
                     }
              }
              ifree((char *) fields);
       }
       if (ferror(fp)) {
              (void) fprintf(stderr, _("%s: Error reading %s\n"),
                     progname, filename);
              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);
              exit(EXIT_FAILURE);
       }
       if (wantcont)
              error(_("expected continuation line not found"));
}

Here is the call graph for this function:

static void inleap ( char **  fields,
int  nfields 
) [static]

Definition at line 1119 of file zic.c.

{
       register const char *              cp;
       register const struct lookup *     lp;
       register int                i, j;
       int                         year, month, day;
       long                        dayoff, tod;
       zic_t                       t;

       if (nfields != LEAP_FIELDS) {
              error(_("wrong number of fields on Leap line"));
              return;
       }
       dayoff = 0;
       cp = fields[LP_YEAR];
       if (sscanf(cp, scheck(cp, "%d"), &year) != 1) {
              /*
              ** Leapin' Lizards!
              */
              error(_("invalid leaping year"));
              return;
       }
       if (!leapseen || leapmaxyear < year)
              leapmaxyear = year;
       if (!leapseen || leapminyear > year)
              leapminyear = year;
       leapseen = TRUE;
       j = EPOCH_YEAR;
       while (j != year) {
              if (year > j) {
                     i = len_years[isleap(j)];
                     ++j;
              } else {
                     --j;
                     i = -len_years[isleap(j)];
              }
              dayoff = oadd(dayoff, eitol(i));
       }
       if ((lp = byword(fields[LP_MONTH], mon_names)) == NULL) {
              error(_("invalid month name"));
              return;
       }
       month = lp->l_value;
       j = TM_JANUARY;
       while (j != month) {
              i = len_months[isleap(year)][j];
              dayoff = oadd(dayoff, eitol(i));
              ++j;
       }
       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"));
                     return;
       }
       dayoff = oadd(dayoff, eitol(day - 1));
       if (dayoff < 0 && !TYPE_SIGNED(zic_t)) {
              error(_("time before zero"));
              return;
       }
       if (dayoff < min_time / SECSPERDAY) {
              error(_("time too small"));
              return;
       }
       if (dayoff > max_time / SECSPERDAY) {
              error(_("time too large"));
              return;
       }
       t = (zic_t) dayoff * SECSPERDAY;
       tod = gethms(fields[LP_TIME], _("invalid time of day"), FALSE);
       cp = fields[LP_CORR];
       {
              register int  positive;
              int           count;

              if (strcmp(cp, "") == 0) { /* infile() turns "-" into "" */
                     positive = FALSE;
                     count = 1;
              } else if (strcmp(cp, "--") == 0) {
                     positive = FALSE;
                     count = 2;
              } else if (strcmp(cp, "+") == 0) {
                     positive = TRUE;
                     count = 1;
              } else if (strcmp(cp, "++") == 0) {
                     positive = TRUE;
                     count = 2;
              } 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;
              }
              leapadd(tadd(t, tod), positive, lp->l_value, count);
       }
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void inlink ( char **  fields,
int  nfields 
) [static]

Definition at line 1223 of file zic.c.

{
       struct link   l;

       if (nfields != LINK_FIELDS) {
              error(_("wrong number of fields on Link line"));
              return;
       }
       if (*fields[LF_FROM] == '\0') {
              error(_("blank FROM field on Link line"));
              return;
       }
       if (*fields[LF_TO] == '\0') {
              error(_("blank TO field on Link line"));
              return;
       }
       l.l_filename = filename;
       l.l_linenum = linenum;
       l.l_from = ecpyalloc(fields[LF_FROM]);
       l.l_to = ecpyalloc(fields[LF_TO]);
       links = (struct link *) (void *) erealloc((char *) links,
              (int) ((nlinks + 1) * sizeof *links));
       links[nlinks++] = l;
}

Here is the caller graph for this function:

static void inrule ( char **  fields,
int  nfields 
) [static]

Definition at line 952 of file zic.c.

{
       static struct rule   r;

       if (nfields != RULE_FIELDS) {
              error(_("wrong number of fields on Rule line"));
              return;
       }
       if (*fields[RF_NAME] == '\0') {
              error(_("nameless rule"));
              return;
       }
       r.r_filename = filename;
       r.r_linenum = linenum;
       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]);
       r.r_abbrvar = ecpyalloc(fields[RF_ABBRVAR]);
       if (max_abbrvar_len < strlen(r.r_abbrvar))
              max_abbrvar_len = strlen(r.r_abbrvar);
       rules = (struct rule *) (void *) erealloc((char *) rules,
              (int) ((nrules + 1) * sizeof *rules));
       rules[nrules++] = r;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static int inzcont ( char **  fields,
int  nfields 
) [static]

Definition at line 1026 of file zic.c.

{
       if (nfields < ZONEC_MINFIELDS || nfields > ZONEC_MAXFIELDS) {
              error(_("wrong number of fields on Zone continuation line"));
              return FALSE;
       }
       return inzsub(fields, nfields, TRUE);
}

Here is the call graph for this function:

Here is the caller graph for this function:

static int inzone ( char **  fields,
int  nfields 
) [static]

Definition at line 981 of file zic.c.

{
       register int  i;
       static char * buf;

       if (nfields < ZONE_MINFIELDS || nfields > ZONE_MAXFIELDS) {
              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"),
                     TZDEFAULT);
              error(buf);
              return FALSE;
       }
       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"),
                     TZDEFRULES);
              error(buf);
              return FALSE;
       }
       for (i = 0; i < nzones; ++i)
              if (zones[i].z_name != NULL &&
                     strcmp(zones[i].z_name, fields[ZF_NAME]) == 0) {
                            buf = erealloc(buf, (int) (132 +
                                   strlen(fields[ZF_NAME]) +
                                   strlen(zones[i].z_filename)));
                            (void) sprintf(buf,
_("duplicate zone name %s (file \"%s\", line %d)"),
                                   fields[ZF_NAME],
                                   zones[i].z_filename,
                                   zones[i].z_linenum);
                            error(buf);
                            return FALSE;
              }
       return inzsub(fields, nfields, FALSE);
}

Here is the call graph for this function:

Here is the caller graph for this function:

static int inzsub ( char **  fields,
int  nfields,
int  iscont 
) [static]

Definition at line 1038 of file zic.c.

{
       register char *             cp;
       static struct zone   z;
       register int         i_gmtoff, i_rule, i_format;
       register int         i_untilyear, i_untilmonth;
       register int         i_untilday, i_untiltime;
       register int         hasuntil;

       if (iscont) {
              i_gmtoff = ZFC_GMTOFF;
              i_rule = ZFC_RULE;
              i_format = ZFC_FORMAT;
              i_untilyear = ZFC_TILYEAR;
              i_untilmonth = ZFC_TILMONTH;
              i_untilday = ZFC_TILDAY;
              i_untiltime = ZFC_TILTIME;
              z.z_name = NULL;
       } else {
              i_gmtoff = ZF_GMTOFF;
              i_rule = ZF_RULE;
              i_format = ZF_FORMAT;
              i_untilyear = ZF_TILYEAR;
              i_untilmonth = ZF_TILMONTH;
              i_untilday = ZF_TILDAY;
              i_untiltime = ZF_TILTIME;
              z.z_name = ecpyalloc(fields[ZF_NAME]);
       }
       z.z_filename = filename;
       z.z_linenum = linenum;
       z.z_gmtoff = gethms(fields[i_gmtoff], _("invalid UTC offset"), TRUE);
       if ((cp = strchr(fields[i_format], '%')) != 0) {
              if (*++cp != 's' || strchr(cp, '%') != 0) {
                     error(_("invalid abbreviation format"));
                     return FALSE;
              }
       }
       z.z_rule = ecpyalloc(fields[i_rule]);
       z.z_format = ecpyalloc(fields[i_format]);
       if (max_format_len < strlen(z.z_format))
              max_format_len = strlen(z.z_format);
       hasuntil = nfields > i_untilyear;
       if (hasuntil) {
              z.z_untilrule.r_filename = filename;
              z.z_untilrule.r_linenum = linenum;
              rulesub(&z.z_untilrule,
                     fields[i_untilyear],
                     "only",
                     "",
                     (nfields > i_untilmonth) ?
                     fields[i_untilmonth] : "Jan",
                     (nfields > i_untilday) ? fields[i_untilday] : "1",
                     (nfields > i_untiltime) ? fields[i_untiltime] : "0");
              z.z_untiltime = rpytime(&z.z_untilrule,
                     z.z_untilrule.r_loyear);
              if (iscont && nzones > 0 &&
                     z.z_untiltime > min_time &&
                     z.z_untiltime < max_time &&
                     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"
                                   ));
                            return FALSE;
              }
       }
       zones = (struct zone *) (void *) erealloc((char *) zones,
              (int) ((nzones + 1) * sizeof *zones));
       zones[nzones++] = z;
       /*
       ** If there was an UNTIL field on this line,
       ** there's more information about the zone on the next line.
       */
       return hasuntil;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static int is32 ( zic_t  x) [static]

Definition at line 1459 of file zic.c.

{
       return INT32_MIN <= x && x <= INT32_MAX;
}

Here is the caller graph for this function:

static int itsabbr ( const char *  abbr,
const char *  word 
) [static]

Definition at line 2381 of file zic.c.

{
       if (lowerit(*abbr) != lowerit(*word))
              return FALSE;
       ++word;
       while (*++abbr != '\0')
              do {
                     if (*word == '\0')
                            return FALSE;
              } while (lowerit(*word++) != lowerit(*abbr));
       return TRUE;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static int itsdir ( const char *  name) [static]

Here is the caller graph for this function:

static int itsdir ( char * const  name) const [static]

Definition at line 696 of file zic.c.

{
       register char *      myname;
       register int  accres;

       myname = ecpyalloc(name);
       myname = ecatalloc(myname, "/.");
       accres = access(myname, F_OK);
       ifree(myname);
       return accres == 0;
}

Here is the call graph for this function:

static void leapadd ( zic_t  t,
int  positive,
int  rolling,
int  count 
) [static]

Definition at line 2287 of file zic.c.

{
       register int  i, j;

       if (leapcnt + (positive ? count : 1) > TZ_MAX_LEAPS) {
              error(_("too many leap seconds"));
              exit(EXIT_FAILURE);
       }
       for (i = 0; i < leapcnt; ++i)
              if (t <= trans[i]) {
                     if (t == trans[i]) {
                            error(_("repeated leap second moment"));
                            exit(EXIT_FAILURE);
                     }
                     break;
              }
       do {
              for (j = leapcnt; j > i; --j) {
                     trans[j] = trans[j - 1];
                     corr[j] = corr[j - 1];
                     roll[j] = roll[j - 1];
              }
              trans[i] = t;
              corr[i] = positive ? 1L : eitol(-count);
              roll[i] = rolling;
              ++leapcnt;
       } while (positive && --count != 0);
}

Here is the call graph for this function:

Here is the caller graph for this function:

int link ( const char *  fromname,
const char *  toname 
)
static int lowerit ( int  c) [static]

Definition at line 2362 of file zic.c.

{
       a = (unsigned char) a;
       return (isascii(a) && isupper(a)) ? tolower(a) : a;
}

Here is the call graph for this function:

Here is the caller graph for this function:

int main ( int  argc,
argv   
)

Definition at line 473 of file zic.c.

{
       register int  i;
       register int  j;
       register int  c;

#ifdef unix
       (void) umask(umask(S_IWGRP | S_IWOTH) | (S_IWGRP | S_IWOTH));
#endif /* defined unix */
#if HAVE_GETTEXT
       (void) setlocale(LC_ALL, "");
#ifdef TZ_DOMAINDIR
       (void) bindtextdomain(TZ_DOMAIN, TZ_DOMAINDIR);
#endif /* defined TEXTDOMAINDIR */
       (void) textdomain(TZ_DOMAIN);
#endif /* HAVE_GETTEXT */
       progname = argv[0];
       if (TYPE_BIT(zic_t) < 64) {
              (void) fprintf(stderr, "%s: %s\n", progname,
                     _("wild compilation-time specification of zic_t"));
              exit(EXIT_FAILURE);
       }
       for (i = 1; i < argc; ++i)
              if (strcmp(argv[i], "--version") == 0) {
                     (void) printf("%s\n", elsieid);
                     exit(EXIT_SUCCESS);
              }
       while ((c = getopt(argc, argv, "d:l:p:L:vsy:")) != EOF && c != -1)
              switch (c) {
                     default:
                            usage();
                     case 'd':
                            if (directory == NULL)
                                   directory = optarg;
                            else {
                                   (void) fprintf(stderr,
_("%s: More than one -d option specified\n"),
                                          progname);
                                   exit(EXIT_FAILURE);
                            }
                            break;
                     case 'l':
                            if (lcltime == NULL)
                                   lcltime = optarg;
                            else {
                                   (void) fprintf(stderr,
_("%s: More than one -l option specified\n"),
                                          progname);
                                   exit(EXIT_FAILURE);
                            }
                            break;
                     case 'p':
                            if (psxrules == NULL)
                                   psxrules = optarg;
                            else {
                                   (void) fprintf(stderr,
_("%s: More than one -p option specified\n"),
                                          progname);
                                   exit(EXIT_FAILURE);
                            }
                            break;
                     case 'y':
                            if (yitcommand == NULL)
                                   yitcommand = optarg;
                            else {
                                   (void) fprintf(stderr,
_("%s: More than one -y option specified\n"),
                                          progname);
                                   exit(EXIT_FAILURE);
                            }
                            break;
                     case 'L':
                            if (leapsec == NULL)
                                   leapsec = optarg;
                            else {
                                   (void) fprintf(stderr,
_("%s: More than one -L option specified\n"),
                                          progname);
                                   exit(EXIT_FAILURE);
                            }
                            break;
                     case 'v':
                            noise = TRUE;
                            break;
                     case 's':
                            (void) printf("%s: -s ignored\n", progname);
                            break;
              }
       if (optind == argc - 1 && strcmp(argv[optind], "=") == 0)
              usage();      /* usage message by request */
       if (directory == NULL)
              directory = TZDIR;
       if (yitcommand == NULL)
              yitcommand = "yearistype";

       setboundaries();

       if (optind < argc && leapsec != NULL) {
              infile(leapsec);
              adjleap();
       }

       for (i = optind; i < argc; ++i)
              infile(argv[i]);
       if (errors)
              exit(EXIT_FAILURE);
       associate();
       for (i = 0; i < nzones; i = j) {
              /*
              ** Find the next non-continuation zone entry.
              */
              for (j = i + 1; j < nzones && zones[j].z_name == NULL; ++j)
                     continue;
              outzone(&zones[i], j - i);
       }
       /*
       ** Make links.
       */
       for (i = 0; i < nlinks; ++i) {
              eat(links[i].l_filename, links[i].l_linenum);
              dolink(links[i].l_from, links[i].l_to);
              if (noise)
                     for (j = 0; j < nlinks; ++j)
                            if (strcmp(links[i].l_to,
                                   links[j].l_from) == 0)
                                          warning(_("link to link"));
       }
       if (lcltime != NULL) {
              eat("command line", 1);
              dolink(lcltime, TZDEFAULT);
       }
       if (psxrules != NULL) {
              eat("command line", 1);
              dolink(psxrules, TZDEFRULES);
       }
       return (errors == 0) ? EXIT_SUCCESS : EXIT_FAILURE;
}

Here is the call graph for this function:

static char * memcheck ( char *  tocheck) [static]

Definition at line 382 of file zic.c.

{
       if (ptr == NULL) {
              const char *e = strerror(errno);

              (void) fprintf(stderr, _("%s: Memory exhausted: %s\n"),
                     progname, e);
              exit(EXIT_FAILURE);
       }
       return ptr;
}

Here is the call graph for this function:

static int mkdirs ( char *  filename) [static]

Definition at line 2643 of file zic.c.

{
       register char *      name;
       register char *      cp;

       if (argname == NULL || *argname == '\0')
              return 0;
       cp = name = ecpyalloc(argname);
       while ((cp = strchr(cp + 1, '/')) != 0) {
              *cp = '\0';
#ifndef unix
              /*
              ** DOS drive specifier?
              */
              if (isalpha((unsigned char) name[0]) &&
                     name[1] == ':' && name[2] == '\0') {
                            *cp = '/';
                            continue;
              }
#endif /* !defined unix */
              if (!itsdir(name)) {
                     /*
                     ** It doesn't seem to exist, so we try to create it.
                     ** Creation may fail because of the directory being
                     ** created by some other multiprocessor, so we get
                     ** to do extra checking.
                     */
                     if (mkdir(name, MKDIR_UMASK) != 0) {
                            const char *e = strerror(errno);

                            if (errno != EEXIST || !itsdir(name)) {
                                   (void) fprintf(stderr,
_("%s: Can't create directory %s: %s\n"),
                                          progname, name, e);
                                   ifree(name);
                                   return -1;
                            }
                     }
              }
              *cp = '/';
       }
       ifree(name);
       return 0;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void newabbr ( const char *  abbr) [static]

Here is the caller graph for this function:

static void newabbr ( char * const  string) const [static]

Definition at line 2590 of file zic.c.

{
       register int  i;

       if (strcmp(string, GRANDPARENTED) != 0) {
              register const char *       cp;
              register char *             wp;

              /*
              ** Want one to ZIC_MAX_ABBR_LEN_WO_WARN alphabetics
              ** optionally followed by a + or - and a number from 1 to 14.
              */
              cp = string;
              wp = NULL;
              while (isascii((unsigned char) *cp) &&
                     isalpha((unsigned char) *cp))
                            ++cp;
              if (cp - string == 0)
wp = _("time zone abbreviation lacks alphabetic at start");
              if (noise && cp - string > 3)
wp = _("time zone abbreviation has more than 3 alphabetics");
              if (cp - string > ZIC_MAX_ABBR_LEN_WO_WARN)
wp = _("time zone abbreviation has too many alphabetics");
              if (wp == NULL && (*cp == '+' || *cp == '-')) {
                     ++cp;
                     if (isascii((unsigned char) *cp) &&
                            isdigit((unsigned char) *cp))
                                   if (*cp++ == '1' &&
                                          *cp >= '0' && *cp <= '4')
                                                 ++cp;
              }
              if (*cp != '\0')
wp = _("time zone abbreviation differs from POSIX standard");
              if (wp != NULL) {
                     wp = ecpyalloc(wp);
                     wp = ecatalloc(wp, " (");
                     wp = ecatalloc(wp, string);
                     wp = ecatalloc(wp, ")");
                     warning(wp);
                     ifree(wp);
              }
       }
       i = strlen(string) + 1;
       if (charcnt + i > TZ_MAX_CHARS) {
              error(_("too many, or too long, time zone abbreviations"));
              exit(EXIT_FAILURE);
       }
       (void) strcpy(&chars[charcnt], string);
       charcnt += eitol(i);
}

Here is the call graph for this function:

static long oadd ( long  t1,
long  t2 
) [static]

Definition at line 2468 of file zic.c.

{
       register long t;

       t = t1 + t2;
       if ((t2 > 0 && t <= t1) || (t2 < 0 && t >= t1)) {
              error(_("time overflow"));
              exit(EXIT_FAILURE);
       }
       return t;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void outzone ( const struct zone zp,
int  ntzones 
) [static]

Here is the caller graph for this function:

static void outzone ( struct zone * const  zpfirst,
const int  zonecount 
) const [static]

Definition at line 1950 of file zic.c.

{
       register const struct zone *       zp;
       register struct rule *             rp;
       register int                i, j;
       register int                usestart, useuntil;
       register zic_t                     starttime, untiltime;
       register long               gmtoff;
       register long               stdoff;
       register int                year;
       register long               startoff;
       register int                startttisstd;
       register int                startttisgmt;
       register int                type;
       register char *                    startbuf;
       register char *                    ab;
       register char *                    envvar;
       register int                max_abbr_len;
       register int                max_envvar_len;

       max_abbr_len = 2 + max_format_len + max_abbrvar_len;
       max_envvar_len = 2 * max_abbr_len + 5 * 9;
       startbuf = emalloc(max_abbr_len + 1);
       ab = emalloc(max_abbr_len + 1);
       envvar = emalloc(max_envvar_len + 1);
       INITIALIZE(untiltime);
       INITIALIZE(starttime);
       /*
       ** Now. . .finally. . .generate some useful data!
       */
       timecnt = 0;
       typecnt = 0;
       charcnt = 0;
       /*
       ** Thanks to Earl Chew
       ** for noting the need to unconditionally initialize startttisstd.
       */
       startttisstd = FALSE;
       startttisgmt = FALSE;
       min_year = max_year = EPOCH_YEAR;
       if (leapseen) {
              updateminmax(leapminyear);
              updateminmax(leapmaxyear);
       }
       for (i = 0; i < zonecount; ++i) {
              zp = &zpfirst[i];
              if (i < zonecount - 1)
                     updateminmax(zp->z_untilrule.r_loyear);
              for (j = 0; j < zp->z_nrules; ++j) {
                     rp = &zp->z_rules[j];
                     if (rp->r_lowasnum)
                            updateminmax(rp->r_loyear);
                     if (rp->r_hiwasnum)
                            updateminmax(rp->r_hiyear);
              }
       }
       /*
       ** Generate lots of data if a rule can't cover all future times.
       */
       stringzone(envvar, zpfirst, zonecount);
       if (noise && envvar[0] == '\0') {
              register char *      wp;

wp = ecpyalloc(_("no POSIX environment variable for zone"));
              wp = ecatalloc(wp, " ");
              wp = ecatalloc(wp, zpfirst->z_name);
              warning(wp);
              ifree(wp);
       }
       if (envvar[0] == '\0') {
              if (min_year >= INT_MIN + YEARSPERREPEAT)
                     min_year -= YEARSPERREPEAT;
              else   min_year = INT_MIN;
              if (max_year <= INT_MAX - YEARSPERREPEAT)
                     max_year += YEARSPERREPEAT;
              else   max_year = INT_MAX;
       }
       /*
       ** For the benefit of older systems,
       ** generate data from 1900 through 2037.
       */
       if (min_year > 1900)
              min_year = 1900;
       if (max_year < 2037)
              max_year = 2037;
       for (i = 0; i < zonecount; ++i) {
              /*
              ** A guess that may well be corrected later.
              */
              stdoff = 0;
              zp = &zpfirst[i];
              usestart = i > 0 && (zp - 1)->z_untiltime > min_time;
              useuntil = i < (zonecount - 1);
              if (useuntil && zp->z_untiltime <= min_time)
                     continue;
              gmtoff = zp->z_gmtoff;
              eat(zp->z_filename, zp->z_linenum);
              *startbuf = '\0';
              startoff = zp->z_gmtoff;
              if (zp->z_nrules == 0) {
                     stdoff = zp->z_stdoff;
                     doabbr(startbuf, zp->z_format,
                            (char *) NULL, stdoff != 0, FALSE);
                     type = addtype(oadd(zp->z_gmtoff, stdoff),
                            startbuf, stdoff != 0, startttisstd,
                            startttisgmt);
                     if (usestart) {
                            addtt(starttime, type);
                            usestart = FALSE;
                     } else if (stdoff != 0)
                            addtt(min_time, type);
              } else for (year = min_year; year <= max_year; ++year) {
                     if (useuntil && year > zp->z_untilrule.r_hiyear)
                            break;
                     /*
                     ** Mark which rules to do in the current year.
                     ** For those to do, calculate rpytime(rp, year);
                     */
                     for (j = 0; j < zp->z_nrules; ++j) {
                            rp = &zp->z_rules[j];
                            eats(zp->z_filename, zp->z_linenum,
                                   rp->r_filename, rp->r_linenum);
                            rp->r_todo = year >= rp->r_loyear &&
                                          year <= rp->r_hiyear &&
                                          yearistype(year, rp->r_yrtype);
                            if (rp->r_todo)
                                   rp->r_temp = rpytime(rp, year);
                     }
                     for ( ; ; ) {
                            register int  k;
                            register zic_t       jtime, ktime;
                            register long offset;

                            INITIALIZE(ktime);
                            if (useuntil) {
                                   /*
                                   ** Turn untiltime into UTC
                                   ** assuming the current gmtoff and
                                   ** stdoff values.
                                   */
                                   untiltime = zp->z_untiltime;
                                   if (!zp->z_untilrule.r_todisgmt)
                                          untiltime = tadd(untiltime,
                                                 -gmtoff);
                                   if (!zp->z_untilrule.r_todisstd)
                                          untiltime = tadd(untiltime,
                                                 -stdoff);
                            }
                            /*
                            ** Find the rule (of those to do, if any)
                            ** that takes effect earliest in the year.
                            */
                            k = -1;
                            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_todisgmt ? 0 : gmtoff;
                                   if (!rp->r_todisstd)
                                          offset = oadd(offset, stdoff);
                                   jtime = rp->r_temp;
                                   if (jtime == min_time ||
                                          jtime == max_time)
                                                 continue;
                                   jtime = tadd(jtime, -offset);
                                   if (k < 0 || jtime < ktime) {
                                          k = j;
                                          ktime = jtime;
                                   }
                            }
                            if (k < 0)
                                   break; /* go on to next year */
                            rp = &zp->z_rules[k];
                            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,
                                                 FALSE);
                                          continue;
                                   }
                                   if (*startbuf == '\0' &&
                                          startoff == oadd(zp->z_gmtoff,
                                          stdoff)) {
                                                 doabbr(startbuf,
                                                        zp->z_format,
                                                        rp->r_abbrvar,
                                                        rp->r_stdoff !=
                                                        0,
                                                        FALSE);
                                   }
                            }
                            eats(zp->z_filename, zp->z_linenum,
                                   rp->r_filename, rp->r_linenum);
                            doabbr(ab, zp->z_format, rp->r_abbrvar,
                                   rp->r_stdoff != 0, FALSE);
                            offset = oadd(zp->z_gmtoff, rp->r_stdoff);
                            type = addtype(offset, ab, rp->r_stdoff != 0,
                                   rp->r_todisstd, rp->r_todisgmt);
                            addtt(ktime, type);
                     }
              }
              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 abbreviation 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) {
                     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, envvar);
       ifree(startbuf);
       ifree(ab);
       ifree(envvar);
}

Here is the call graph for this function:

static void puttzcode ( long  code,
FILE fp 
) [static]

Definition at line 1426 of file zic.c.

{
       char   buf[4];

       convert(val, buf);
       (void) fwrite((void *) buf, (size_t) sizeof buf, (size_t) 1, fp);
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void puttzcode64 ( zic_t  code,
FILE fp 
) [static]

Definition at line 1437 of file zic.c.

{
       char   buf[8];

       convert64(val, buf);
       (void) fwrite((void *) buf, (size_t) sizeof buf, (size_t) 1, fp);
}

Here is the call graph for this function:

Here is the caller graph for this function:

static int rcomp ( const void *  leftp,
const void *  rightp 
) [static]

Here is the caller graph for this function:

static int rcomp ( void *  cp1,
const void *  cp2 
) const [static]

Definition at line 718 of file zic.c.

{
       return strcmp(((const struct rule *) cp1)->r_name,
              ((const struct rule *) cp2)->r_name);
}
static zic_t rpytime ( const struct rule rp,
int  wantedy 
) [static]

Definition at line 2507 of file zic.c.

{
       register int  y, m, i;
       register long dayoff;                     /* with a nod to Margaret O. */
       register zic_t       t;

       if (wantedy == INT_MIN)
              return min_time;
       if (wantedy == INT_MAX)
              return max_time;
       dayoff = 0;
       m = TM_JANUARY;
       y = EPOCH_YEAR;
       while (wantedy != y) {
              if (wantedy > y) {
                     i = len_years[isleap(y)];
                     ++y;
              } else {
                     --y;
                     i = -len_years[isleap(y)];
              }
              dayoff = oadd(dayoff, eitol(i));
       }
       while (m != rp->r_month) {
              i = len_months[isleap(y)][m];
              dayoff = oadd(dayoff, eitol(i));
              ++m;
       }
       i = rp->r_dayofmonth;
       if (m == TM_FEBRUARY && i == 29 && !isleap(y)) {
              if (rp->r_dycode == DC_DOWLEQ)
                     --i;
              else {
                     error(_("use of 2/29 in non leap-year"));
                     exit(EXIT_FAILURE);
              }
       }
       --i;
       dayoff = oadd(dayoff, eitol(i));
       if (rp->r_dycode == DC_DOWGEQ || rp->r_dycode == DC_DOWLEQ) {
              register long wday;

#define LDAYSPERWEEK ((long) DAYSPERWEEK)
              wday = eitol(EPOCH_WDAY);
              /*
              ** Don't trust mod of negative numbers.
              */
              if (dayoff >= 0)
                     wday = (wday + dayoff) % LDAYSPERWEEK;
              else {
                     wday -= ((-dayoff) % LDAYSPERWEEK);
                     if (wday < 0)
                            wday += LDAYSPERWEEK;
              }
              while (wday != eitol(rp->r_wday))
                     if (rp->r_dycode == DC_DOWGEQ) {
                            dayoff = oadd(dayoff, (long) 1);
                            if (++wday >= LDAYSPERWEEK)
                                   wday = 0;
                            ++i;
                     } else {
                            dayoff = oadd(dayoff, (long) -1);
                            if (--wday < 0)
                                   wday = LDAYSPERWEEK - 1;
                            --i;
                     }
              if (i < 0 || i >= len_months[isleap(y)][m]) {
                     if (noise)
                            warning(_("rule goes past start/end of month--\
will not work with pre-2004 versions of zic"));
              }
       }
       if (dayoff < min_time / SECSPERDAY)
              return min_time;
       if (dayoff > max_time / SECSPERDAY)
              return max_time;
       t = (zic_t) dayoff * SECSPERDAY;
       return tadd(t, rp->r_tod);
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void rulesub ( struct rule rp,
const char *  loyearp,
const char *  hiyearp,
const char *  typep,
const char *  monthp,
const char *  dayp,
const char *  timep 
) [static]

Definition at line 1251 of file zic.c.

{
       register const struct lookup *     lp;
       register const char *              cp;
       register char *                    dp;
       register char *                    ep;

       if ((lp = byword(monthp, mon_names)) == NULL) {
              error(_("invalid month name"));
              return;
       }
       rp->r_month = lp->l_value;
       rp->r_todisstd = 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_todisgmt = FALSE;
                            *ep = '\0';
                            break;
                     case 'w':     /* Wall */
                            rp->r_todisstd = FALSE;
                            rp->r_todisgmt = FALSE;
                            *ep = '\0';
                            break;
                     case 'g':     /* Greenwich */
                     case 'u':     /* Universal */
                     case 'z':     /* Zulu */
                            rp->r_todisstd = TRUE;
                            rp->r_todisgmt = TRUE;
                            *ep = '\0';
                            break;
              }
       }
       rp->r_tod = gethms(dp, _("invalid time of day"), FALSE);
       ifree(dp);
       /*
       ** Year work.
       */
       cp = loyearp;
       lp = byword(cp, begin_years);
       rp->r_lowasnum = lp == NULL;
       if (!rp->r_lowasnum) switch ((int) lp->l_value) {
              case YR_MINIMUM:
                     rp->r_loyear = INT_MIN;
                     break;
              case YR_MAXIMUM:
                     rp->r_loyear = INT_MAX;
                     break;
              default:      /* "cannot happen" */
                     (void) fprintf(stderr,
                            _("%s: panic: Invalid l_value %d\n"),
                            progname, lp->l_value);
                     exit(EXIT_FAILURE);
       } else if (sscanf(cp, scheck(cp, "%d"), &rp->r_loyear) != 1) {
              error(_("invalid starting year"));
              return;
       }
       cp = hiyearp;
       lp = byword(cp, end_years);
       rp->r_hiwasnum = lp == NULL;
       if (!rp->r_hiwasnum) switch ((int) lp->l_value) {
              case YR_MINIMUM:
                     rp->r_hiyear = INT_MIN;
                     break;
              case YR_MAXIMUM:
                     rp->r_hiyear = INT_MAX;
                     break;
              case YR_ONLY:
                     rp->r_hiyear = rp->r_loyear;
                     break;
              default:      /* "cannot happen" */
                     (void) fprintf(stderr,
                            _("%s: panic: Invalid l_value %d\n"),
                            progname, lp->l_value);
                     exit(EXIT_FAILURE);
       } else if (sscanf(cp, scheck(cp, "%d"), &rp->r_hiyear) != 1) {
              error(_("invalid ending year"));
              return;
       }
       if (rp->r_loyear > rp->r_hiyear) {
              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"));
                     return;
              }
              rp->r_yrtype = ecpyalloc(typep);
       }
       /*
       ** Day work.
       ** Accept things such as:
       **     1
       **     last-Sunday
       **     Sun<=20
       **     Sun>=7
       */
       dp = ecpyalloc(dayp);
       if ((lp = byword(dp, lasts)) != NULL) {
              rp->r_dycode = DC_DOWLEQ;
              rp->r_wday = lp->l_value;
              rp->r_dayofmonth = len_months[1][rp->r_month];
       } else {
              if ((ep = strchr(dp, '<')) != 0)
                     rp->r_dycode = DC_DOWLEQ;
              else if ((ep = strchr(dp, '>')) != 0)
                     rp->r_dycode = DC_DOWGEQ;
              else {
                     ep = dp;
                     rp->r_dycode = DC_DOM;
              }
              if (rp->r_dycode != DC_DOM) {
                     *ep++ = 0;
                     if (*ep++ != '=') {
                            error(_("invalid day of month"));
                            ifree(dp);
                            return;
                     }
                     if ((lp = byword(dp, wday_names)) == NULL) {
                            error(_("invalid weekday name"));
                            ifree(dp);
                            return;
                     }
                     rp->r_wday = lp->l_value;
              }
              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"));
                            ifree(dp);
                            return;
              }
       }
       ifree(dp);
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void setboundaries ( void  ) [static]

Definition at line 685 of file zic.c.

{
       register int  i;

       min_time = -1;
       for (i = 0; i < TIME_T_BITS_IN_FILE - 1; ++i)
              min_time *= 2;
       max_time = -(min_time + 1);
}

Here is the caller graph for this function:

static int stringoffset ( char *  result,
long  offset 
) [static]

Definition at line 1780 of file zic.c.

{
       register int  hours;
       register int  minutes;
       register int  seconds;

       result[0] = '\0';
       if (offset < 0) {
              (void) strcpy(result, "-");
              offset = -offset;
       }
       seconds = offset % SECSPERMIN;
       offset /= SECSPERMIN;
       minutes = offset % MINSPERHOUR;
       offset /= MINSPERHOUR;
       hours = offset;
       if (hours >= HOURSPERDAY) {
              result[0] = '\0';
              return -1;
       }
       (void) sprintf(end(result), "%d", hours);
       if (minutes != 0 || seconds != 0) {
              (void) sprintf(end(result), ":%02d", minutes);
              if (seconds != 0)
                     (void) sprintf(end(result), ":%02d", seconds);
       }
       return 0;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static int stringrule ( char *  result,
const struct rule rp,
long  dstoff,
long  gmtoff 
) [static]

Definition at line 1812 of file zic.c.

{
       register long tod;

       result = end(result);
       if (rp->r_dycode == DC_DOM) {
              register int  month, total;

              if (rp->r_dayofmonth == 29 && rp->r_month == TM_FEBRUARY)
                     return -1;
              total = 0;
              for (month = 0; month < rp->r_month; ++month)
                     total += len_months[0][month];
              (void) sprintf(result, "J%d", total + rp->r_dayofmonth);
       } else {
              register int  week;

              if (rp->r_dycode == DC_DOWGEQ) {
                     week = 1 + rp->r_dayofmonth / DAYSPERWEEK;
                     if ((week - 1) * DAYSPERWEEK + 1 != rp->r_dayofmonth)
                            return -1;
              } else if (rp->r_dycode == DC_DOWLEQ) {
                     if (rp->r_dayofmonth == len_months[1][rp->r_month])
                            week = 5;
                     else {
                            week = 1 + rp->r_dayofmonth / DAYSPERWEEK;
                            if (week * DAYSPERWEEK - 1 != rp->r_dayofmonth)
                                   return -1;
                     }
              } else return -1;    /* "cannot happen" */
              (void) sprintf(result, "M%d.%d.%d",
                     rp->r_month + 1, week, rp->r_wday);
       }
       tod = rp->r_tod;
       if (rp->r_todisgmt)
              tod += gmtoff;
       if (rp->r_todisstd && rp->r_stdoff == 0)
              tod += dstoff;
       if (tod < 0) {
              result[0] = '\0';
              return -1;
       }
       if (tod != 2 * SECSPERMIN * MINSPERHOUR) {
              (void) strcat(result, "/");
              if (stringoffset(end(result), tod) != 0)
                     return -1;
       }
       return 0;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void stringzone ( char *  result,
const struct zone zp,
int  ntzones 
) [static]

Definition at line 1867 of file zic.c.

{
       register const struct zone *       zp;
       register struct rule *             rp;
       register struct rule *             stdrp;
       register struct rule *             dstrp;
       register int                i;
       register const char *              abbrvar;

       result[0] = '\0';
       zp = zpfirst + zonecount - 1;
       stdrp = dstrp = NULL;
       for (i = 0; i < zp->z_nrules; ++i) {
              rp = &zp->z_rules[i];
              if (rp->r_hiwasnum || rp->r_hiyear != INT_MAX)
                     continue;
              if (rp->r_yrtype != NULL)
                     continue;
              if (rp->r_stdoff == 0) {
                     if (stdrp == NULL)
                            stdrp = rp;
                     else   return;
              } else {
                     if (dstrp == NULL)
                            dstrp = rp;
                     else   return;
              }
       }
       if (stdrp == NULL && dstrp == NULL) {
              /*
              ** There are no rules running through "max".
              ** Let's find the latest rule.
              */
              for (i = 0; i < zp->z_nrules; ++i) {
                     rp = &zp->z_rules[i];
                     if (stdrp == NULL || rp->r_hiyear > stdrp->r_hiyear ||
                            (rp->r_hiyear == stdrp->r_hiyear &&
                            rp->r_month > stdrp->r_month))
                                   stdrp = rp;
              }
              if (stdrp != NULL && stdrp->r_stdoff != 0)
                     return;       /* We end up in DST (a POSIX no-no). */
              /*
              ** Horrid special case: if year is 2037,
              ** presume this is a zone handled on a year-by-year basis;
              ** do not try to apply a rule to the zone.
              */
              if (stdrp != NULL && stdrp->r_hiyear == 2037)
                     return;
       }
       if (stdrp == NULL && zp->z_nrules != 0)
              return;
       abbrvar = (stdrp == NULL) ? "" : stdrp->r_abbrvar;
       doabbr(result, zp->z_format, abbrvar, FALSE, TRUE);
       if (stringoffset(end(result), -zp->z_gmtoff) != 0) {
              result[0] = '\0';
              return;
       }
       if (dstrp == NULL)
              return;
       doabbr(end(result), zp->z_format, dstrp->r_abbrvar, TRUE, TRUE);
       if (dstrp->r_stdoff != SECSPERMIN * MINSPERHOUR)
              if (stringoffset(end(result),
                     -(zp->z_gmtoff + dstrp->r_stdoff)) != 0) {
                            result[0] = '\0';
                            return;
              }
       (void) strcat(result, ",");
       if (stringrule(result, dstrp, dstrp->r_stdoff, zp->z_gmtoff) != 0) {
              result[0] = '\0';
              return;
       }
       (void) strcat(result, ",");
       if (stringrule(result, stdrp, dstrp->r_stdoff, zp->z_gmtoff) != 0) {
              result[0] = '\0';
              return;
       }
}

Here is the call graph for this function:

Here is the caller graph for this function:

static zic_t tadd ( zic_t  t1,
long  t2 
) [static]

Definition at line 2483 of file zic.c.

{
       register zic_t       t;

       if (t1 == max_time && t2 > 0)
              return max_time;
       if (t1 == min_time && t2 < 0)
              return min_time;
       t = t1 + t2;
       if ((t2 > 0 && t <= t1) || (t2 < 0 && t >= t1)) {
              error(_("time overflow"));
              exit(EXIT_FAILURE);
       }
       return t;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void updateminmax ( int  x) const [static]

Definition at line 1770 of file zic.c.

{
       if (min_year > x)
              min_year = x;
       if (max_year < x)
              max_year = x;
}

Here is the caller graph for this function:

static void usage ( void  ) [static]

Definition at line 457 of file zic.c.

{
       (void) fprintf(stderr, _("%s: usage is %s \
[ --version ] [ -v ] [ -l localtime ] [ -p posixrules ] \\\n\
\t[ -d directory ] [ -L leapseconds ] [ -y yearistype ] [ filename ... ]\n"),
              progname, progname);
       exit(EXIT_FAILURE);
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void warning ( char * const  string) const [static]

Definition at line 444 of file zic.c.

{
       char * cp;

       cp = ecpyalloc(_("warning: "));
       cp = ecatalloc(cp, string);
       error(cp);
       ifree(cp);
       --errors;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void writezone ( const char *  name,
const char *  string 
) [static]

Here is the caller graph for this function:

static void writezone ( char * const  name,
const char * const  string 
) const [static]

Definition at line 1466 of file zic.c.

{
       register FILE *                    fp;
       register int                i, j;
       register int                leapcnt32, leapi32;
       register int                timecnt32, timei32;
       register int                pass;
       static char *               fullname;
       static const struct tzhead  tzh0;
       static struct tzhead        tzh;
       zic_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;
              while (fromi < timecnt && attypes[fromi].at < min_time)
                     ++fromi;
              if (isdsts[0] == 0)
                     while (fromi < timecnt && 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;
       }
       /*
       ** Correct for leap seconds.
       */
       for (i = 0; i < timecnt; ++i) {
              j = leapcnt;
              while (--j >= 0)
                     if (ats[i] > trans[j] - corr[j]) {
                            ats[i] = tadd(ats[i], corr[j]);
                            break;
                     }
       }
       /*
       ** Figure out 32-bit-limited starts and counts.
       */
       timecnt32 = timecnt;
       timei32 = 0;
       leapcnt32 = leapcnt;
       leapi32 = 0;
       while (timecnt32 > 0 && !is32(ats[timecnt32 - 1]))
              --timecnt32;
       while (timecnt32 > 0 && !is32(ats[timei32])) {
              --timecnt32;
              ++timei32;
       }
       while (leapcnt32 > 0 && !is32(trans[leapcnt32 - 1]))
              --leapcnt32;
       while (leapcnt32 > 0 && !is32(trans[leapi32])) {
              --leapcnt32;
              ++leapi32;
       }
       fullname = erealloc(fullname,
              (int) (strlen(directory) + 1 + strlen(name) + 1));
       (void) sprintf(fullname, "%s/%s", directory, name);
       /*
       ** Remove old file, if any, to snap links.
       */
       if (!itsdir(fullname) && remove(fullname) != 0 && errno != ENOENT) {
              const char *e = strerror(errno);

              (void) fprintf(stderr, _("%s: Can't remove %s: %s\n"),
                     progname, fullname, e);
              exit(EXIT_FAILURE);
       }
       if ((fp = fopen(fullname, "wb")) == NULL) {
              if (mkdirs(fullname) != 0)
                     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);
                     exit(EXIT_FAILURE);
              }
       }
       for (pass = 1; pass <= 2; ++pass) {
              register int  thistimei, thistimecnt;
              register int  thisleapi, thisleapcnt;
              register int  thistimelim, thisleaplim;
              int           writetype[TZ_MAX_TIMES];
              int           typemap[TZ_MAX_TYPES];
              register int  thistypecnt;
              char          thischars[TZ_MAX_CHARS];
              char          thischarcnt;
              int           indmap[TZ_MAX_CHARS];

              if (pass == 1) {
                     thistimei = timei32;
                     thistimecnt = timecnt32;
                     thisleapi = leapi32;
                     thisleapcnt = leapcnt32;
              } else {
                     thistimei = 0;
                     thistimecnt = timecnt;
                     thisleapi = 0;
                     thisleapcnt = leapcnt;
              }
              thistimelim = thistimei + thistimecnt;
              thisleaplim = thisleapi + thisleapcnt;
              for (i = 0; i < typecnt; ++i)
                     writetype[i] = thistimecnt == timecnt;
              if (thistimecnt == 0) {
                     /*
                     ** No transition times fall in the current
                     ** (32- or 64-bit) window.
                     */
                     if (typecnt != 0)
                            writetype[typecnt - 1] = TRUE;
              } else {
                     for (i = thistimei - 1; i < thistimelim; ++i)
                            if (i >= 0)
                                   writetype[types[i]] = TRUE;
                     /*
                     ** For America/Godthab and Antarctica/Palmer
                     */
                     if (thistimei == 0)
                            writetype[0] = TRUE;
              }
              thistypecnt = 0;
              for (i = 0; i < typecnt; ++i)
                     typemap[i] = writetype[i] ?  thistypecnt++ : -1;
              for (i = 0; i < sizeof indmap / sizeof indmap[0]; ++i)
                     indmap[i] = -1;
              thischarcnt = 0;
              for (i = 0; i < typecnt; ++i) {
                     register char *      thisabbr;

                     if (!writetype[i])
                            continue;
                     if (indmap[abbrinds[i]] >= 0)
                            continue;
                     thisabbr = &chars[abbrinds[i]];
                     for (j = 0; j < thischarcnt; ++j)
                            if (strcmp(&thischars[j], thisabbr) == 0)
                                   break;
                     if (j == thischarcnt) {
                            (void) strcpy(&thischars[(int) thischarcnt],
                                   thisabbr);
                            thischarcnt += strlen(thisabbr) + 1;
                     }
                     indmap[abbrinds[i]] = j;
              }
#define DO(field)    (void) fwrite((void *) tzh.field, \
                            (size_t) sizeof tzh.field, (size_t) 1, fp)
              tzh = tzh0;
              (void) strncpy(tzh.tzh_magic, TZ_MAGIC, sizeof tzh.tzh_magic);
              tzh.tzh_version[0] = ZIC_VERSION;
              convert(eitol(thistypecnt), tzh.tzh_ttisgmtcnt);
              convert(eitol(thistypecnt), tzh.tzh_ttisstdcnt);
              convert(eitol(thisleapcnt), tzh.tzh_leapcnt);
              convert(eitol(thistimecnt), tzh.tzh_timecnt);
              convert(eitol(thistypecnt), tzh.tzh_typecnt);
              convert(eitol(thischarcnt), tzh.tzh_charcnt);
              DO(tzh_magic);
              DO(tzh_version);
              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 = thistimei; i < thistimelim; ++i)
                     if (pass == 1)
                            puttzcode((long) ats[i], fp);
                     else   puttzcode64(ats[i], fp);
              for (i = thistimei; i < thistimelim; ++i) {
                     unsigned char uc;

                     uc = typemap[types[i]];
                     (void) fwrite((void *) &uc,
                            (size_t) sizeof uc,
                            (size_t) 1,
                            fp);
              }
              for (i = 0; i < typecnt; ++i)
                     if (writetype[i]) {
                            puttzcode(gmtoffs[i], fp);
                            (void) putc(isdsts[i], fp);
                            (void) putc((unsigned char) indmap[abbrinds[i]], fp);
                     }
              if (thischarcnt != 0)
                     (void) fwrite((void *) thischars,
                            (size_t) sizeof thischars[0],
                            (size_t) thischarcnt, fp);
              for (i = thisleapi; i < thisleaplim; ++i) {
                     register zic_t       todo;

                     if (roll[i]) {
                            if (timecnt == 0 || trans[i] < ats[0]) {
                                   j = 0;
                                   while (isdsts[j])
                                          if (++j >= typecnt) {
                                                 j = 0;
                                                 break;
                                          }
                            } else {
                                   j = 1;
                                   while (j < timecnt &&
                                          trans[i] >= ats[j])
                                                 ++j;
                                   j = types[j - 1];
                            }
                            todo = tadd(trans[i], -gmtoffs[j]);
                     } else todo = trans[i];
                     if (pass == 1)
                            puttzcode((long) todo, fp);
                     else   puttzcode64(todo, fp);
                     puttzcode(corr[i], fp);
              }
              for (i = 0; i < typecnt; ++i)
                     if (writetype[i])
                            (void) putc(ttisstds[i], fp);
              for (i = 0; i < typecnt; ++i)
                     if (writetype[i])
                            (void) putc(ttisgmts[i], fp);
       }
       (void) fprintf(fp, "\n%s\n", string);
       if (ferror(fp) || fclose(fp)) {
              (void) fprintf(stderr, _("%s: Error writing %s\n"),
                     progname, fullname);
              exit(EXIT_FAILURE);
       }
}

Here is the call graph for this function:

static int yearistype ( int  year,
const char *  type 
) [static]

Definition at line 2336 of file zic.c.

{
       static char * buf;
       int           result;

       if (type == NULL || *type == '\0')
              return TRUE;
       buf = erealloc(buf, (int) (132 + strlen(yitcommand) + strlen(type)));
       (void) sprintf(buf, "%s %d %s", yitcommand, year, type);
       result = system(buf);
       if (WIFEXITED(result)) switch (WEXITSTATUS(result)) {
              case 0:
                     return TRUE;
              case 1:
                     return FALSE;
       }
       error(_("Wild result from command execution"));
       (void) fprintf(stderr, _("%s: command was '%s', result was %d\n"),
              progname, buf, result);
       for ( ; ; )
              exit(EXIT_FAILURE);
}

Here is the call graph for this function:

Here is the caller graph for this function:


Variable Documentation

unsigned char abbrinds[TZ_MAX_TYPES] [static]

Definition at line 369 of file zic.c.

struct attype attypes[TZ_MAX_TIMES] [static]
int charcnt [static]

Definition at line 163 of file zic.c.

char chars[TZ_MAX_CHARS] [static]

Definition at line 372 of file zic.c.

long corr[TZ_MAX_LEAPS] [static]

Definition at line 374 of file zic.c.

const char* directory [static]

Definition at line 468 of file zic.c.

char elsieid[] = "@(#)zic.c 8.17" [static]

Definition at line 6 of file zic.c.

int errors [static]

Definition at line 164 of file zic.c.

const char* filename [static]

Definition at line 165 of file zic.c.

long gmtoffs[TZ_MAX_TYPES] [static]

Definition at line 367 of file zic.c.

char isdsts[TZ_MAX_TYPES] [static]

Definition at line 368 of file zic.c.

const char* lcltime [static]

Definition at line 467 of file zic.c.

int leapcnt [static]

Definition at line 166 of file zic.c.

int leapmaxyear [static]

Definition at line 169 of file zic.c.

int leapminyear [static]

Definition at line 168 of file zic.c.

const char* leapsec [static]

Definition at line 469 of file zic.c.

int leapseen [static]

Definition at line 167 of file zic.c.

Initial value:
 {
       { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 },
       { 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }
}

Definition at line 354 of file zic.c.

const int len_years[2] [static]
Initial value:

Definition at line 359 of file zic.c.

int linenum [static]

Definition at line 170 of file zic.c.

struct link* links [static]

Definition at line 278 of file zic.c.

static struct lookup [static]
Initial value:
 {
       { "Rule",     LC_RULE },
       { "Zone",     LC_ZONE },
       { "Link",     LC_LINK },
       { "Leap",     LC_LEAP },
       { NULL,              0}
}

Definition at line 289 of file zic.c.

int max_abbrvar_len [static]

Definition at line 171 of file zic.c.

int max_format_len [static]

Definition at line 172 of file zic.c.

zic_t max_time [static]

Definition at line 173 of file zic.c.

int max_year [static]

Definition at line 174 of file zic.c.

zic_t min_time [static]

Definition at line 175 of file zic.c.

int min_year [static]

Definition at line 176 of file zic.c.

int nlinks [static]

Definition at line 279 of file zic.c.

int noise [static]

Definition at line 177 of file zic.c.

int nrules [static]

Definition at line 266 of file zic.c.

int nzones [static]

Definition at line 269 of file zic.c.

char* optarg

Definition at line 107 of file getopt.c.

Definition at line 122 of file getopt.c.

const char* progname [static]

Definition at line 180 of file zic.c.

const char* psxrules [static]

Definition at line 466 of file zic.c.

const char* rfilename [static]

Definition at line 178 of file zic.c.

int rlinenum [static]

Definition at line 179 of file zic.c.

char roll[TZ_MAX_LEAPS] [static]

Definition at line 375 of file zic.c.

struct rule* rules [static]

Definition at line 265 of file zic.c.

int timecnt [static]

Definition at line 181 of file zic.c.

Definition at line 373 of file zic.c.

char ttisgmts[TZ_MAX_TYPES] [static]

Definition at line 371 of file zic.c.

char ttisstds[TZ_MAX_TYPES] [static]

Definition at line 370 of file zic.c.

int typecnt [static]

Definition at line 182 of file zic.c.

const char* yitcommand [static]

Definition at line 470 of file zic.c.

struct zone* zones [static]

Definition at line 268 of file zic.c.