[BACK]Return to zic.c CVS log [TXT][DIR] Up to [cvs.NetBSD.org] / src / lib / libc / time

Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.

Diff for /src/lib/libc/time/zic.c between version 1.76 and 1.77

version 1.76, 2020/05/25 14:52:48 version 1.77, 2020/10/09 18:38:48
Line 91  struct rule {
Line 91  struct rule {
   
         zic_t           r_loyear;       /* for example, 1986 */          zic_t           r_loyear;       /* for example, 1986 */
         zic_t           r_hiyear;       /* for example, 1986 */          zic_t           r_hiyear;       /* for example, 1986 */
         const char *    r_yrtype;  
         bool            r_lowasnum;          bool            r_lowasnum;
         bool            r_hiwasnum;          bool            r_hiwasnum;
   
Line 143  struct zone {
Line 142  struct zone {
 #if !HAVE_POSIX_DECLS  #if !HAVE_POSIX_DECLS
 extern int      getopt(int argc, char * const argv[],  extern int      getopt(int argc, char * const argv[],
                         const char * options);                          const char * options);
 extern int      link(const char * fromname, const char * toname);  extern int      link(const char * target, const char * linkname);
 extern char *   optarg;  extern char *   optarg;
 extern int      optind;  extern int      optind;
 #endif  #endif
   
 #if ! HAVE_LINK  #if ! HAVE_LINK
 # define link(from, to) (errno = ENOTSUP, -1)  # define link(target, linkname) (errno = ENOTSUP, -1)
 #endif  #endif
 #if ! HAVE_SYMLINK  #if ! HAVE_SYMLINK
 # define readlink(file, buf, size) (errno = ENOTSUP, -1)  # define readlink(file, buf, size) (errno = ENOTSUP, -1)
 # define symlink(from, to) (errno = ENOTSUP, -1)  # define symlink(target, linkname) (errno = ENOTSUP, -1)
 # define S_ISLNK(m) 0  # define S_ISLNK(m) 0
 #endif  #endif
 #ifndef AT_SYMLINK_FOLLOW  #ifndef AT_SYMLINK_FOLLOW
 # define linkat(fromdir, from, todir, to, flag) \  # define linkat(targetdir, target, linknamedir, linkname, flag) \
     (itssymlink(from) ? (errno = ENOTSUP, -1) : link(from, to))      (itssymlink(target) ? (errno = ENOTSUP, -1) : link(target, linkname))
 #endif  #endif
   
 static void     addtt(zic_t starttime, int type);  static void     addtt(zic_t starttime, int type);
Line 192  static void rulesub(struct rule * rp,
Line 191  static void rulesub(struct rule * rp,
                         const char * typep, const char * monthp,                          const char * typep, const char * monthp,
                         const char * dayp, const char * timep);                          const char * dayp, const char * timep);
 static zic_t    tadd(zic_t t1, zic_t t2);  static zic_t    tadd(zic_t t1, zic_t t2);
 static bool     yearistype(zic_t year, const char * type);  
   
 /* Bound on length of what %z can expand to.  */  /* Bound on length of what %z can expand to.  */
 enum { PERCENT_Z_LEN_BOUND = sizeof "+995959" - 1 };  enum { PERCENT_Z_LEN_BOUND = sizeof "+995959" - 1 };
Line 285  static int  typecnt;
Line 283  static int  typecnt;
 ** Which fields are which on a Link line.  ** Which fields are which on a Link line.
 */  */
   
 #define LF_FROM         1  #define LF_TARGET       1
 #define LF_TO           2  #define LF_LINKNAME     2
 #define LINK_FIELDS     3  #define LINK_FIELDS     3
   
 /*  /*
Line 323  static ptrdiff_t nzones_alloc;
Line 321  static ptrdiff_t nzones_alloc;
 struct link {  struct link {
         const char *    l_filename;          const char *    l_filename;
         lineno          l_linenum;          lineno          l_linenum;
         const char *    l_from;          const char *    l_target;
         const char *    l_to;          const char *    l_linkname;
 };  };
   
 static struct link *    links;  static struct link *    links;
Line 669  static const char * lcltime;
Line 667  static const char * lcltime;
 static const char *     directory;  static const char *     directory;
 static const char *     leapsec;  static const char *     leapsec;
 static const char *     tzdefault;  static const char *     tzdefault;
 static const char *     yitcommand;  
   
 /* -1 if the TZif output file should be slim, 0 if default, 1 if the  /* -1 if the TZif output file should be slim, 0 if default, 1 if the
    output should be fat for backward compatibility.  Currently the     output should be fat for backward compatibility.  The default is slim.  */
    default is fat, although this may change.  */  
 static int bloat;  static int bloat;
   
 static bool  static bool
Line 683  want_bloat(void)
Line 679  want_bloat(void)
 }  }
   
 #ifndef ZIC_BLOAT_DEFAULT  #ifndef ZIC_BLOAT_DEFAULT
 # define ZIC_BLOAT_DEFAULT "fat"  # define ZIC_BLOAT_DEFAULT "slim"
 #endif  #endif
   
 int  int
Line 774  _("%s: More than one -p option specified
Line 770  _("%s: More than one -p option specified
                                 tzdefault = optarg;                                  tzdefault = optarg;
                                 break;                                  break;
                         case 'y':                          case 'y':
                                 if (yitcommand == NULL) {                                  warning(_("-y ignored"));
                                         warning(_("-y is obsolescent"));  
                                         yitcommand = optarg;  
                                 } else {  
                                         fprintf(stderr,  
 _("%s: More than one -y option specified\n"),  
                                                 progname);  
                                         return EXIT_FAILURE;  
                                 }  
                                 break;                                  break;
                         case 'L':                          case 'L':
                                 if (leapsec == NULL)                                  if (leapsec == NULL)
Line 824  _("%s: invalid time range: %s\n"),
Line 812  _("%s: invalid time range: %s\n"),
                 directory = TZDIR;                  directory = TZDIR;
         if (tzdefault == NULL)          if (tzdefault == NULL)
                 tzdefault = TZDEFAULT;                  tzdefault = TZDEFAULT;
         if (yitcommand == NULL)  
                 yitcommand = "yearistype";  
   
         if (optind < argc && leapsec != NULL) {          if (optind < argc && leapsec != NULL) {
                 infile(leapsec);                  infile(leapsec);
Line 851  _("%s: invalid time range: %s\n"),
Line 837  _("%s: invalid time range: %s\n"),
         */          */
         for (i = 0; i < nlinks; ++i) {          for (i = 0; i < nlinks; ++i) {
                 eat(links[i].l_filename, links[i].l_linenum);                  eat(links[i].l_filename, links[i].l_linenum);
                 dolink(links[i].l_from, links[i].l_to, false);                  dolink(links[i].l_target, links[i].l_linkname, false);
                 if (noise)                  if (noise)
                         for (j = 0; j < nlinks; ++j)                          for (j = 0; j < nlinks; ++j)
                                 if (strcmp(links[i].l_to,                                  if (strcmp(links[i].l_linkname,
                                         links[j].l_from) == 0)                                          links[j].l_target) == 0)
                                                 warning(_("link to link"));                                                  warning(_("link to link"));
         }          }
         if (lcltime != NULL) {          if (lcltime != NULL) {
Line 947  namecheck(const char *name)
Line 933  namecheck(const char *name)
    is relative to the global variable DIRECTORY.  TO can be either     is relative to the global variable DIRECTORY.  TO can be either
    relative or absolute.  */     relative or absolute.  */
 static char *  static char *
 relname(char const *from, char const *to)  relname(char const *target, char const *linkname)
 {  {
   size_t i, taillen, dotdotetcsize;    size_t i, taillen, dotdotetcsize;
   size_t dir_len = 0, dotdots = 0, linksize = SIZE_MAX;    size_t dir_len = 0, dotdots = 0, linksize = SIZE_MAX;
   char const *f = from;    char const *f = target;
   char *result = NULL;    char *result = NULL;
   if (*to == '/') {    if (*linkname == '/') {
     /* Make F absolute too.  */      /* Make F absolute too.  */
     size_t len = strlen(directory);      size_t len = strlen(directory);
     bool needslash = len && directory[len - 1] != '/';      bool needslash = len && directory[len - 1] != '/';
     linksize = len + needslash + strlen(from) + 1;      linksize = len + needslash + strlen(target) + 1;
     f = result = emalloc(linksize);      f = result = emalloc(linksize);
     strcpy(result, directory);      strcpy(result, directory);
     result[len] = '/';      result[len] = '/';
     strcpy(result + len + needslash, from);      strcpy(result + len + needslash, target);
   }    }
   for (i = 0; f[i] && f[i] == to[i]; i++)    for (i = 0; f[i] && f[i] == linkname[i]; i++)
     if (f[i] == '/')      if (f[i] == '/')
       dir_len = i + 1;        dir_len = i + 1;
   for (; to[i]; i++)    for (; linkname[i]; i++)
     dotdots += to[i] == '/' && to[i - 1] != '/';      dotdots += linkname[i] == '/' && linkname[i - 1] != '/';
   taillen = strlen(f + dir_len);    taillen = strlen(f + dir_len);
   dotdotetcsize = 3 * dotdots + taillen + 1;    dotdotetcsize = 3 * dotdots + taillen + 1;
   if (dotdotetcsize <= linksize) {    if (dotdotetcsize <= linksize) {
Line 983  relname(char const *from, char const *to
Line 969  relname(char const *from, char const *to
 /* Hard link FROM to TO, following any symbolic links.  /* Hard link FROM to TO, following any symbolic links.
    Return 0 if successful, an error number otherwise.  */     Return 0 if successful, an error number otherwise.  */
 static int  static int
 hardlinkerr(char const *from, char const *to)  hardlinkerr(char const *target, char const *linkname)
 {  {
   int r = linkat(AT_FDCWD, from, AT_FDCWD, to, AT_SYMLINK_FOLLOW);    int r = linkat(AT_FDCWD, target, AT_FDCWD, linkname, AT_SYMLINK_FOLLOW);
   return r == 0 ? 0 : errno;    return r == 0 ? 0 : errno;
 }  }
   
 static void  static void
 dolink(char const *fromfield, char const *tofield, bool staysymlink)  dolink(char const *target, char const *linkname, bool staysymlink)
 {  {
         bool todirs_made = false;          bool remove_only = strcmp(target, "-") == 0;
           bool linkdirs_made = false;
         int link_errno;          int link_errno;
   
         /*          /*
         ** We get to be careful here since          ** We get to be careful here since
         ** there's a fair chance of root running us.          ** there's a fair chance of root running us.
         */          */
         if (itsdir(fromfield)) {          if (!remove_only && itsdir(target)) {
                 fprintf(stderr, _("%s: link from %s/%s failed: %s\n"),                  fprintf(stderr, _("%s: linking target %s/%s failed: %s\n"),
                         progname, directory, fromfield, strerror(EPERM));                          progname, directory, target, strerror(EPERM));
                 exit(EXIT_FAILURE);                  exit(EXIT_FAILURE);
         }          }
         if (staysymlink)          if (staysymlink)
           staysymlink = itssymlink(tofield);            staysymlink = itssymlink(linkname);
         if (remove(tofield) == 0)          if (remove(linkname) == 0)
           todirs_made = true;            linkdirs_made = true;
         else if (errno != ENOENT) {          else if (errno != ENOENT) {
           char const *e = strerror(errno);            char const *e = strerror(errno);
           fprintf(stderr, _("%s: Can't remove %s/%s: %s\n"),            fprintf(stderr, _("%s: Can't remove %s/%s: %s\n"),
             progname, directory, tofield, e);                    progname, directory, linkname, e);
           exit(EXIT_FAILURE);            exit(EXIT_FAILURE);
         }          }
         link_errno = staysymlink ? ENOTSUP : hardlinkerr(fromfield, tofield);          if (remove_only)
         if (link_errno == ENOENT && !todirs_made) {            return;
           mkdirs(tofield, true);          link_errno = staysymlink ? ENOTSUP : hardlinkerr(target, linkname);
           todirs_made = true;          if (link_errno == ENOENT && !linkdirs_made) {
           link_errno = hardlinkerr(fromfield, tofield);            mkdirs(linkname, true);
             linkdirs_made = true;
             link_errno = hardlinkerr(target, linkname);
         }          }
         if (link_errno != 0) {          if (link_errno != 0) {
           bool absolute = *fromfield == '/';            bool absolute = *target == '/';
           char *linkalloc = absolute ? NULL : relname(fromfield, tofield);            char *linkalloc = absolute ? NULL : relname(target, linkname);
           char const *contents = absolute ? fromfield : linkalloc;            char const *contents = absolute ? target : linkalloc;
           int symlink_errno = symlink(contents, tofield) == 0 ? 0 : errno;            int symlink_errno = symlink(contents, linkname) == 0 ? 0 : errno;
           if (!todirs_made            if (!linkdirs_made
               && (symlink_errno == ENOENT || symlink_errno == ENOTSUP)) {                && (symlink_errno == ENOENT || symlink_errno == ENOTSUP)) {
             mkdirs(tofield, true);              mkdirs(linkname, true);
             if (symlink_errno == ENOENT)              if (symlink_errno == ENOENT)
               symlink_errno = symlink(contents, tofield) == 0 ? 0 : errno;                symlink_errno = symlink(contents, linkname) == 0 ? 0 : errno;
           }            }
           free(linkalloc);            free(linkalloc);
           if (symlink_errno == 0) {            if (symlink_errno == 0) {
Line 1039  dolink(char const *fromfield, char const
Line 1028  dolink(char const *fromfield, char const
           } else {            } else {
             FILE *fp, *tp;              FILE *fp, *tp;
             int c;              int c;
             fp = fopen(fromfield, "rb");              fp = fopen(target, "rb");
             if (!fp) {              if (!fp) {
               char const *e = strerror(errno);                char const *e = strerror(errno);
               fprintf(stderr, _("%s: Can't read %s/%s: %s\n"),                fprintf(stderr, _("%s: Can't read %s/%s: %s\n"),
                       progname, directory, fromfield, e);                        progname, directory, target, e);
               exit(EXIT_FAILURE);                exit(EXIT_FAILURE);
             }              }
             tp = fopen(tofield, "wb");              tp = fopen(linkname, "wb");
             if (!tp) {              if (!tp) {
               char const *e = strerror(errno);                char const *e = strerror(errno);
               fprintf(stderr, _("%s: Can't create %s/%s: %s\n"),                fprintf(stderr, _("%s: Can't create %s/%s: %s\n"),
                       progname, directory, tofield, e);                        progname, directory, linkname, e);
               exit(EXIT_FAILURE);                exit(EXIT_FAILURE);
             }              }
             while ((c = getc(fp)) != EOF)              while ((c = getc(fp)) != EOF)
               putc(c, tp);                putc(c, tp);
             close_file(fp, directory, fromfield);              close_file(fp, directory, target);
             close_file(tp, directory, tofield);              close_file(tp, directory, linkname);
             if (link_errno != ENOTSUP)              if (link_errno != ENOTSUP)
               warning(_("copy used because hard link failed: %s"),                warning(_("copy used because hard link failed: %s"),
                       strerror(link_errno));                        strerror(link_errno));
Line 1635  inlink(char **fields, int nfields)
Line 1624  inlink(char **fields, int nfields)
                 error(_("wrong number of fields on Link line"));                  error(_("wrong number of fields on Link line"));
                 return;                  return;
         }          }
         if (*fields[LF_FROM] == '\0') {          if (*fields[LF_TARGET] == '\0') {
                 error(_("blank FROM field on Link line"));                  error(_("blank TARGET field on Link line"));
                 return;                  return;
         }          }
         if (! namecheck(fields[LF_TO]))          if (! namecheck(fields[LF_LINKNAME]))
           return;            return;
         l.l_filename = filename;          l.l_filename = filename;
         l.l_linenum = linenum;          l.l_linenum = linenum;
         l.l_from = ecpyalloc(fields[LF_FROM]);          l.l_target = ecpyalloc(fields[LF_TARGET]);
         l.l_to = ecpyalloc(fields[LF_TO]);          l.l_linkname = ecpyalloc(fields[LF_LINKNAME]);
         links = growalloc(links, sizeof *links, nlinks, &nlinks_alloc);          links = growalloc(links, sizeof *links, nlinks, &nlinks_alloc);
         links[nlinks++] = l;          links[nlinks++] = l;
 }  }
Line 1740  rulesub(struct rule *rp, const char *loy
Line 1729  rulesub(struct rule *rp, const char *loy
                 error(_("starting year greater than ending year"));                  error(_("starting year greater than ending year"));
                 return;                  return;
         }          }
         if (*typep == '\0')          if (*typep != '\0') {
                 rp->r_yrtype = NULL;                  error(_("year type \"%s\" is unsupported; use \"-\" instead"),
         else {  
                 if (rp->r_loyear == rp->r_hiyear) {  
                         error(_("typed single year"));  
                         return;  
                 }  
                 warning(_("year type \"%s\" is obsolete; use \"-\" instead"),  
                         typep);                          typep);
                 rp->r_yrtype = ecpyalloc(typep);                  return;
         }          }
         /*          /*
         ** Day work.          ** Day work.
Line 2512  stringzone(char *result, int resultlen, 
Line 2495  stringzone(char *result, int resultlen, 
                 rp = &zp->z_rules[i];                  rp = &zp->z_rules[i];
                 if (rp->r_hiwasnum || rp->r_hiyear != ZIC_MAX)                  if (rp->r_hiwasnum || rp->r_hiyear != ZIC_MAX)
                         continue;                          continue;
                 if (rp->r_yrtype != NULL)  
                         continue;  
                 if (!rp->r_isdst) {                  if (!rp->r_isdst) {
                         if (stdrp == NULL)                          if (stdrp == NULL)
                                 stdrp = rp;                                  stdrp = rp;
Line 2769  outzone(const struct zone *zpfirst, ptrd
Line 2750  outzone(const struct zone *zpfirst, ptrd
                         /*                          /*
                         ** Mark which rules to do in the current year.                          ** Mark which rules to do in the current year.
                         ** For those to do, calculate rpytime(rp, year);                          ** For those to do, calculate rpytime(rp, year);
                           ** The former TYPE field was also considered here.
                         */                          */
                         for (j = 0; j < zp->z_nrules; ++j) {                          for (j = 0; j < zp->z_nrules; ++j) {
                                 rp = &zp->z_rules[j];                                  rp = &zp->z_rules[j];
                                 eats(zp->z_filename, zp->z_linenum,                                  eats(zp->z_filename, zp->z_linenum,
                                         rp->r_filename, rp->r_linenum);                                          rp->r_filename, rp->r_linenum);
                                 rp->r_todo = year >= rp->r_loyear &&                                  rp->r_todo = year >= rp->r_loyear &&
                                                 year <= rp->r_hiyear &&                                                  year <= rp->r_hiyear;
                                                 yearistype(year, rp->r_yrtype);  
                                 if (rp->r_todo) {                                  if (rp->r_todo) {
                                         rp->r_temp = rpytime(rp, year);                                          rp->r_temp = rpytime(rp, year);
                                         rp->r_todo                                          rp->r_todo
Line 3072  adjleap(void)
Line 3053  adjleap(void)
         }          }
 }  }
   
 static char *  
 shellquote(char *b, char const *s)  
 {  
   *b++ = '\'';  
   while (*s) {  
     if (*s == '\'')  
       *b++ = '\'', *b++ = '\\', *b++ = '\'';  
     *b++ = *s++;  
   }  
   *b++ = '\'';  
   return b;  
 }  
   
 static bool  
 yearistype(zic_t year, const char *type)  
 {  
         char *buf;  
         char *b;  
         int result;  
         size_t len;  
   
         if (type == NULL || *type == '\0')  
                 return true;  
         buf = zic_malloc(len = 1 + 4 * strlen(yitcommand) + 2  
                       + INT_STRLEN_MAXIMUM(zic_t) + 2 + 4 * strlen(type) + 2);  
         b = shellquote(buf, yitcommand);  
         *b++ = ' ';  
         b += snprintf(b, len - (b - buf), "%"PRIdZIC, year);  
         *b++ = ' ';  
         b = shellquote(b, type);  
         *b = '\0';  
         result = system(buf);  
         if (WIFEXITED(result)) {  
                 int status = WEXITSTATUS(result);  
                 if (status <= 1) {  
                         free(buf);  
                         return status == 0;  
                 }  
         }  
         error(_("Wild result from command execution"));  
         fprintf(stderr, _("%s: command was '%s', result was %d\n"),  
                 progname, buf, result);  
         exit(EXIT_FAILURE);  
 }  
   
 /* Is A a space character in the C locale?  */  /* Is A a space character in the C locale?  */
 static bool  static bool
 is_space(char a)  is_space(char a)

Legend:
Removed from v.1.76  
changed lines
  Added in v.1.77

CVSweb <webmaster@jp.NetBSD.org>