Diff for /embedaddon/rsync/util.c between versions 1.1.1.3 and 1.1.1.4

version 1.1.1.3, 2016/11/01 09:54:32 version 1.1.1.4, 2021/03/17 00:32:36
Line 4 Line 4
  * Copyright (C) 1996-2000 Andrew Tridgell   * Copyright (C) 1996-2000 Andrew Tridgell
  * Copyright (C) 1996 Paul Mackerras   * Copyright (C) 1996 Paul Mackerras
  * Copyright (C) 2001, 2002 Martin Pool <mbp@samba.org>   * Copyright (C) 2001, 2002 Martin Pool <mbp@samba.org>
 * Copyright (C) 2003-2015 Wayne Davison * Copyright (C) 2003-2020 Wayne Davison
  *   *
  * This program is free software; you can redistribute it and/or modify   * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by   * it under the terms of the GNU General Public License as published by
Line 27 Line 27
   
 extern int dry_run;  extern int dry_run;
 extern int module_id;  extern int module_id;
   extern int do_fsync;
 extern int protect_args;  extern int protect_args;
 extern int modify_window;  extern int modify_window;
 extern int relative_paths;  extern int relative_paths;
 extern int preserve_times;  extern int preserve_times;
 extern int preserve_xattrs;  extern int preserve_xattrs;
 extern int preallocate_files;  extern int preallocate_files;
   extern int force_change;
 extern char *module_dir;  extern char *module_dir;
 extern unsigned int module_dirlen;  extern unsigned int module_dirlen;
 extern char *partial_dir;  extern char *partial_dir;
Line 115  void print_child_argv(const char *prefix, char **cmd) Line 117  void print_child_argv(const char *prefix, char **cmd)
         rprintf(FCLIENT, " (%d args)\n", cnt);          rprintf(FCLIENT, " (%d args)\n", cnt);
 }  }
   
   #ifdef SUPPORT_FORCE_CHANGE
   static int try_a_force_change(const char *fname, STRUCT_STAT *stp)
   {
           uint32 fileflags = ST_FLAGS(*stp);
           if (fileflags == NO_FFLAGS) {
                   STRUCT_STAT st;
                   if (x_lstat(fname, &st, NULL) == 0)
                           fileflags = st.st_flags;
           }
           if (fileflags != NO_FFLAGS && make_mutable(fname, stp->st_mode, fileflags, force_change) > 0) {
                   int ret, save_force_change = force_change;
   
                   force_change = 0; /* Make certain we can't come back here. */
                   ret = set_times(fname, stp);
                   force_change = save_force_change;
   
                   undo_make_mutable(fname, fileflags);
   
                   return ret;
           }
   
           errno = EPERM;
   
           return -1;
   }
   #endif
   
 /* This returns 0 for success, 1 for a symlink if symlink time-setting  /* This returns 0 for success, 1 for a symlink if symlink time-setting
  * is not possible, or -1 for any other error. */   * is not possible, or -1 for any other error. */
int set_modtime(const char *fname, time_t modtime, uint32 mod_nsec, mode_t mode)int set_times(const char *fname, STRUCT_STAT *stp)
 {  {
         static int switch_step = 0;          static int switch_step = 0;
   
         if (DEBUG_GTE(TIME, 1)) {          if (DEBUG_GTE(TIME, 1)) {
                rprintf(FINFO, "set modtime of %s to (%ld) %s",                rprintf(FINFO,
                        fname, (long)modtime,                        "set modtime, atime of %s to (%ld) %s, (%ld) %s\n",
                        asctime(localtime(&modtime)));                        fname, (long)stp->st_mtime,
                         timestring(stp->st_mtime), (long)stp->st_atime, timestring(stp->st_atime));
         }          }
   
         switch (switch_step) {          switch (switch_step) {
   #ifdef HAVE_SETATTRLIST
   #include "case_N.h"
                   if (do_setattrlist_times(fname, stp) == 0)
                           break;
                   if (errno != ENOSYS)
                           return -1;
                   switch_step++;
   #endif
   
 #ifdef HAVE_UTIMENSAT  #ifdef HAVE_UTIMENSAT
 #include "case_N.h"  #include "case_N.h"
                if (do_utimensat(fname, modtime, mod_nsec) == 0)                if (do_utimensat(fname, stp) == 0)
                         break;                          break;
   #ifdef SUPPORT_FORCE_CHANGE
                   if (force_change && errno == EPERM && try_a_force_change(fname, stp) == 0)
                           break;
   #endif
                 if (errno != ENOSYS)                  if (errno != ENOSYS)
                         return -1;                          return -1;
                 switch_step++;                  switch_step++;
                 /* FALLTHROUGH */  
 #endif  #endif
   
 #ifdef HAVE_LUTIMES  #ifdef HAVE_LUTIMES
 #include "case_N.h"  #include "case_N.h"
                if (do_lutimes(fname, modtime, mod_nsec) == 0)                if (do_lutimes(fname, stp) == 0)
                         break;                          break;
   #ifdef SUPPORT_FORCE_CHANGE
                   if (force_change && errno == EPERM && try_a_force_change(fname, stp) == 0)
                           break;
   #endif
                 if (errno != ENOSYS)                  if (errno != ENOSYS)
                         return -1;                          return -1;
                 switch_step++;                  switch_step++;
                 /* FALLTHROUGH */  
 #endif  #endif
   
 #include "case_N.h"  #include "case_N.h"
                 switch_step++;                  switch_step++;
                 if (preserve_times & PRESERVE_LINK_TIMES) {                  if (preserve_times & PRESERVE_LINK_TIMES) {
                         preserve_times &= ~PRESERVE_LINK_TIMES;                          preserve_times &= ~PRESERVE_LINK_TIMES;
                        if (S_ISLNK(mode))                        if (S_ISLNK(stp->st_mode))
                                 return 1;                                  return 1;
                 }                  }
                 /* FALLTHROUGH */  
   
 #include "case_N.h"  #include "case_N.h"
 #ifdef HAVE_UTIMES  #ifdef HAVE_UTIMES
                if (do_utimes(fname, modtime, mod_nsec) == 0)                if (do_utimes(fname, stp) == 0)
                         break;                          break;
 #else  #else
                if (do_utime(fname, modtime, mod_nsec) == 0)                if (do_utime(fname, stp) == 0)
                         break;                          break;
 #endif  #endif
   #ifdef SUPPORT_FORCE_CHANGE
                   if (force_change && errno == EPERM && try_a_force_change(fname, stp) == 0)
                           break;
   #endif
   
                 return -1;                  return -1;
         }          }
Line 175  int set_modtime(const char *fname, time_t modtime, uin Line 223  int set_modtime(const char *fname, time_t modtime, uin
 /* Create any necessary directories in fname.  Any missing directories are  /* Create any necessary directories in fname.  Any missing directories are
  * created with default permissions.  Returns < 0 on error, or the number   * created with default permissions.  Returns < 0 on error, or the number
  * of directories created. */   * of directories created. */
int make_path(char *fname, int flags)int make_path(char *fname, mode_t mode, int flags)
 {  {
         char *end, *p;          char *end, *p;
         int ret = 0;          int ret = 0;
Line 206  int make_path(char *fname, int flags) Line 254  int make_path(char *fname, int flags)
                                 else                                  else
                                         errno = ENOTDIR;                                          errno = ENOTDIR;
                         }                          }
                } else if (do_mkdir(fname, ACCESSPERMS) == 0) {                } else if (do_mkdir(fname, mode) == 0) {
                         ret++;                          ret++;
                         break;                          break;
                 }                  }
Line 245  int make_path(char *fname, int flags) Line 293  int make_path(char *fname, int flags)
                 p += strlen(p);                  p += strlen(p);
                 if (ret < 0) /* Skip mkdir on error, but keep restoring the path. */                  if (ret < 0) /* Skip mkdir on error, but keep restoring the path. */
                         continue;                          continue;
                if (do_mkdir(fname, ACCESSPERMS) < 0)                if (do_mkdir(fname, mode) < 0)
                         ret = -ret - 1;                          ret = -ret - 1;
                 else                  else
                         ret++;                          ret++;
Line 323  int copy_file(const char *source, const char *dest, in Line 371  int copy_file(const char *source, const char *dest, in
         int ifd;          int ifd;
         char buf[1024 * 8];          char buf[1024 * 8];
         int len;   /* Number of bytes read into `buf'. */          int len;   /* Number of bytes read into `buf'. */
#ifdef PREALLOCATE_NEEDS_TRUNCATE        OFF_T prealloc_len = 0, offset = 0;
        OFF_T preallocated_len = 0, offset = 0; 
#endif 
   
         if ((ifd = do_open(source, O_RDONLY, 0)) < 0) {          if ((ifd = do_open(source, O_RDONLY, 0)) < 0) {
                 int save_errno = errno;                  int save_errno = errno;
Line 338  int copy_file(const char *source, const char *dest, in Line 384  int copy_file(const char *source, const char *dest, in
                 if (robust_unlink(dest) && errno != ENOENT) {                  if (robust_unlink(dest) && errno != ENOENT) {
                         int save_errno = errno;                          int save_errno = errno;
                         rsyserr(FERROR_XFER, errno, "unlink %s", full_fname(dest));                          rsyserr(FERROR_XFER, errno, "unlink %s", full_fname(dest));
                           close(ifd);
                         errno = save_errno;                          errno = save_errno;
                         return -1;                          return -1;
                 }                  }
Line 365  int copy_file(const char *source, const char *dest, in Line 412  int copy_file(const char *source, const char *dest, in
                 if (do_fstat(ifd, &srcst) < 0)                  if (do_fstat(ifd, &srcst) < 0)
                         rsyserr(FWARNING, errno, "fstat %s", full_fname(source));                          rsyserr(FWARNING, errno, "fstat %s", full_fname(source));
                 else if (srcst.st_size > 0) {                  else if (srcst.st_size > 0) {
                        if (do_fallocate(ofd, 0, srcst.st_size) == 0) {                        prealloc_len = do_fallocate(ofd, 0, srcst.st_size);
#ifdef PREALLOCATE_NEEDS_TRUNCATE                        if (prealloc_len < 0)
                                preallocated_len = srcst.st_size; 
#endif 
                        } else 
                                 rsyserr(FWARNING, errno, "do_fallocate %s", full_fname(dest));                                  rsyserr(FWARNING, errno, "do_fallocate %s", full_fname(dest));
                 }                  }
         }          }
Line 384  int copy_file(const char *source, const char *dest, in Line 428  int copy_file(const char *source, const char *dest, in
                         errno = save_errno;                          errno = save_errno;
                         return -1;                          return -1;
                 }                  }
 #ifdef PREALLOCATE_NEEDS_TRUNCATE  
                 offset += len;                  offset += len;
 #endif  
         }          }
   
         if (len < 0) {          if (len < 0) {
Line 403  int copy_file(const char *source, const char *dest, in Line 445  int copy_file(const char *source, const char *dest, in
                         full_fname(source));                          full_fname(source));
         }          }
   
 #ifdef PREALLOCATE_NEEDS_TRUNCATE  
         /* Source file might have shrunk since we fstatted it.          /* Source file might have shrunk since we fstatted it.
          * Cut off any extra preallocated zeros from dest file. */           * Cut off any extra preallocated zeros from dest file. */
        if (offset < preallocated_len && do_ftruncate(ofd, offset) < 0) {        if (offset < prealloc_len && do_ftruncate(ofd, offset) < 0) {
                 /* If we fail to truncate, the dest file may be wrong, so we                  /* If we fail to truncate, the dest file may be wrong, so we
                  * must trigger the "partial transfer" error. */                   * must trigger the "partial transfer" error. */
                 rsyserr(FERROR_XFER, errno, "ftruncate %s", full_fname(dest));                  rsyserr(FERROR_XFER, errno, "ftruncate %s", full_fname(dest));
         }          }
 #endif  
   
           if (do_fsync && fsync(ofd) < 0) {
                   rsyserr(FERROR, errno, "fsync failed on %s",
                           full_fname(dest));
                   close(ofd);
                   return -1;
           }
   
         if (close(ofd) < 0) {          if (close(ofd) < 0) {
                 int save_errno = errno;                  int save_errno = errno;
                 rsyserr(FERROR_XFER, errno, "close failed on %s",                  rsyserr(FERROR_XFER, errno, "close failed on %s",
Line 499  int robust_rename(const char *from, const char *to, co Line 546  int robust_rename(const char *from, const char *to, co
 {  {
         int tries = 4;          int tries = 4;
   
           /* A resumed in-place partial-dir transfer might call us with from and
            * to pointing to the same buf if the transfer failed yet again. */
           if (from == to)
                   return 0;
   
         while (tries--) {          while (tries--) {
                 if (do_rename(from, to) == 0)                  if (do_rename(from, to) == 0)
                         return 0;                          return 0;
Line 588  int lock_range(int fd, int offset, int len) Line 640  int lock_range(int fd, int offset, int len)
 }  }
   
 #define ENSURE_MEMSPACE(buf, type, sz, req) \  #define ENSURE_MEMSPACE(buf, type, sz, req) \
        if ((req) > sz && !(buf = realloc_array(buf, type, sz = MAX(sz * 2, req)))) \        do { if ((req) > sz) buf = realloc_array(buf, type, sz = MAX(sz * 2, req)); } while(0)
                out_of_memory("glob_expand") 
   
 static inline void call_glob_match(const char *name, int len, int from_glob,  static inline void call_glob_match(const char *name, int len, int from_glob,
                                    char *arg, int abpos, int fbpos);                                     char *arg, int abpos, int fbpos);
Line 691  static inline void call_glob_match(const char *name, i Line 742  static inline void call_glob_match(const char *name, i
                 glob_match(arg, abpos, fbpos);                  glob_match(arg, abpos, fbpos);
         } else {          } else {
                 ENSURE_MEMSPACE(glob.argv, char *, glob.maxargs, glob.argc + 1);                  ENSURE_MEMSPACE(glob.argv, char *, glob.maxargs, glob.argc + 1);
                if (!(glob.argv[glob.argc++] = strdup(glob.arg_buf)))                glob.argv[glob.argc++] = strdup(glob.arg_buf);
                        out_of_memory("glob_match"); 
         }          }
 }  }
   
Line 716  int glob_expand(const char *arg, char ***argv_p, int * Line 766  int glob_expand(const char *arg, char ***argv_p, int *
                 s = sanitize_path(NULL, arg, "", 0, SP_KEEP_DOT_DIRS);                  s = sanitize_path(NULL, arg, "", 0, SP_KEEP_DOT_DIRS);
         else {          else {
                 s = strdup(arg);                  s = strdup(arg);
                if (!s)                clean_fname(s, CFN_KEEP_DOT_DIRS | CFN_KEEP_TRAILING_SLASH | CFN_COLLAPSE_DOT_DOT_DIRS);
                        out_of_memory("glob_expand"); 
                clean_fname(s, CFN_KEEP_DOT_DIRS 
                             | CFN_KEEP_TRAILING_SLASH 
                             | CFN_COLLAPSE_DOT_DOT_DIRS); 
         }          }
   
         ENSURE_MEMSPACE(glob.arg_buf, char, glob.absize, MAXPATHLEN);          ENSURE_MEMSPACE(glob.arg_buf, char, glob.absize, MAXPATHLEN);
Line 769  void glob_expand_module(char *base1, char *arg, char * Line 815  void glob_expand_module(char *base1, char *arg, char *
                 return;                  return;
         }          }
   
        if (!(arg = strdup(arg)))        arg = strdup(arg);
                out_of_memory("glob_expand_module"); 
   
         if (asprintf(&base," %s/", base1) < 0)          if (asprintf(&base," %s/", base1) < 0)
                 out_of_memory("glob_expand_module");                  out_of_memory("glob_expand_module");
Line 800  void strlower(char *s) Line 845  void strlower(char *s)
         }          }
 }  }
   
   /**
    * Split a string into tokens based (usually) on whitespace & commas.  If the
    * string starts with a comma (after skipping any leading whitespace), then
    * splitting is done only on commas. No empty tokens are ever returned. */
   char *conf_strtok(char *str)
   {
           static int commas_only = 0;
   
           if (str) {
                   while (isSpace(str)) str++;
                   if (*str == ',') {
                           commas_only = 1;
                           str++;
                   } else
                           commas_only = 0;
           }
   
           while (commas_only) {
                   char *end, *tok = strtok(str, ",");
                   if (!tok)
                           return NULL;
                   /* Trim just leading and trailing whitespace. */
                   while (isSpace(tok))
                           tok++;
                   end = tok + strlen(tok);
                   while (end > tok && isSpace(end-1))
                           *--end = '\0';
                   if (*tok)
                           return tok;
                   str = NULL;
           }
   
           return strtok(str, " ,\t\r\n");
   }
   
 /* Join strings p1 & p2 into "dest" with a guaranteed '/' between them.  (If  /* Join strings p1 & p2 into "dest" with a guaranteed '/' between them.  (If
  * p1 ends with a '/', no extra '/' is inserted.)  Returns the length of both   * p1 ends with a '/', no extra '/' is inserted.)  Returns the length of both
  * strings + 1 (if '/' was inserted), regardless of whether the null-terminated   * strings + 1 (if '/' was inserted), regardless of whether the null-terminated
Line 852  size_t stringjoin(char *dest, size_t destsize, ...) Line 932  size_t stringjoin(char *dest, size_t destsize, ...)
         return ret;          return ret;
 }  }
   
   /* Append formatted text at *dest_ptr up to a maximum of sz (like snprintf).
    * On success, advance *dest_ptr and return True; on overflow, return False. */
   BOOL snappendf(char **dest_ptr, size_t sz, const char *format, ...)
   {
           va_list ap;
           size_t len;
   
           va_start(ap, format);
           len = vsnprintf(*dest_ptr, sz, format, ap);
           va_end(ap);
   
           if (len >= sz)
                   return False;
           else {
                   *dest_ptr += len;
                   return True;
           }
   }
   
 int count_dir_elements(const char *p)  int count_dir_elements(const char *p)
 {  {
         int cnt = 0, new_component = 1;          int cnt = 0, new_component = 1;
Line 966  int clean_fname(char *name, int flags) Line 1065  int clean_fname(char *name, int flags)
  * ALWAYS collapses ".." elements (except for those at the start of the   * ALWAYS collapses ".." elements (except for those at the start of the
  * string up to "depth" deep).  If the resulting name would be empty,   * string up to "depth" deep).  If the resulting name would be empty,
  * change it into a ".". */   * change it into a ".". */
char *sanitize_path(char *dest, const char *p, const char *rootdir, int depth,char *sanitize_path(char *dest, const char *p, const char *rootdir, int depth, int flags)
                    int flags) 
 {  {
         char *start, *sanp;          char *start, *sanp;
         int rlen = 0, drop_dot_dirs = !relative_paths || !(flags & SP_KEEP_DOT_DIRS);          int rlen = 0, drop_dot_dirs = !relative_paths || !(flags & SP_KEEP_DOT_DIRS);
   
         if (dest != p) {          if (dest != p) {
                int plen = strlen(p);                int plen = strlen(p); /* the path len INCLUDING any separating slash */
                 if (*p == '/') {                  if (*p == '/') {
                         if (!rootdir)                          if (!rootdir)
                                 rootdir = module_dir;                                  rootdir = module_dir;
Line 981  char *sanitize_path(char *dest, const char *p, const c Line 1079  char *sanitize_path(char *dest, const char *p, const c
                         depth = 0;                          depth = 0;
                         p++;                          p++;
                 }                  }
                if (dest) {                if (!dest)
                        if (rlen + plen + 1 >= MAXPATHLEN)                        dest = new_array(char, MAX(rlen + plen + 1, 2));
                                return NULL;                else if (rlen + plen + 1 >= MAXPATHLEN)
                } else if (!(dest = new_array(char, rlen + plen + 1)))                        return NULL;
                        out_of_memory("sanitize_path");                if (rlen) { /* only true if p previously started with a slash */
                if (rlen) { 
                         memcpy(dest, rootdir, rlen);                          memcpy(dest, rootdir, rlen);
                        if (rlen > 1)                        if (rlen > 1) /* a rootdir of len 1 is "/", so this avoids a 2nd slash */
                                 dest[rlen++] = '/';                                  dest[rlen++] = '/';
                 }                  }
         }          }
Line 1077  int change_dir(const char *dir, int set_path_only) Line 1174  int change_dir(const char *dir, int set_path_only)
                 skipped_chdir = set_path_only;                  skipped_chdir = set_path_only;
                 memcpy(curr_dir, dir, len + 1);                  memcpy(curr_dir, dir, len + 1);
         } else {          } else {
                   unsigned int save_dir_len = curr_dir_len;
                 if (curr_dir_len + 1 + len >= sizeof curr_dir) {                  if (curr_dir_len + 1 + len >= sizeof curr_dir) {
                         errno = ENAMETOOLONG;                          errno = ENAMETOOLONG;
                         return 0;                          return 0;
Line 1086  int change_dir(const char *dir, int set_path_only) Line 1184  int change_dir(const char *dir, int set_path_only)
                 memcpy(curr_dir + curr_dir_len, dir, len + 1);                  memcpy(curr_dir + curr_dir_len, dir, len + 1);
   
                 if (!set_path_only && chdir(curr_dir)) {                  if (!set_path_only && chdir(curr_dir)) {
                           curr_dir_len = save_dir_len;
                         curr_dir[curr_dir_len] = '\0';                          curr_dir[curr_dir_len] = '\0';
                         return 0;                          return 0;
                 }                  }
Line 1117  char *normalize_path(char *path, BOOL force_newbuf, un Line 1216  char *normalize_path(char *path, BOOL force_newbuf, un
                         return NULL;                          return NULL;
                 curr_dir[curr_dir_len] = '/';                  curr_dir[curr_dir_len] = '/';
                 memcpy(curr_dir + curr_dir_len + 1, path, len + 1);                  memcpy(curr_dir + curr_dir_len + 1, path, len + 1);
                if (!(path = strdup(curr_dir)))                path = strdup(curr_dir);
                        out_of_memory("normalize_path"); 
                 curr_dir[curr_dir_len] = '\0';                  curr_dir[curr_dir_len] = '\0';
        } else if (force_newbuf) {        } else if (force_newbuf)
                if (!(path = strdup(path)))                path = strdup(path);
                        out_of_memory("normalize_path"); 
        } 
   
         len = clean_fname(path, CFN_COLLAPSE_DOT_DOT_DIRS | CFN_DROP_TRAILING_DOT_DIR);          len = clean_fname(path, CFN_COLLAPSE_DOT_DOT_DIRS | CFN_DROP_TRAILING_DOT_DIR);
   
Line 1133  char *normalize_path(char *path, BOOL force_newbuf, un Line 1229  char *normalize_path(char *path, BOOL force_newbuf, un
         return path;          return path;
 }  }
   
   /* We need to supply our own strcmp function for file list comparisons
    * to ensure that signed/unsigned usage is consistent between machines. */
   int u_strcmp(const char *p1, const char *p2)
   {
           for ( ; *p1; p1++, p2++) {
                   if (*p1 != *p2)
                           break;
           }
   
           return (int)*(uchar*)p1 - (int)*(uchar*)p2;
   }
   
   /* We need a memcmp function compares unsigned-byte values. */
   int u_memcmp(const void *p1, const void *p2, size_t len)
   {
           const uchar *u1 = p1;
           const uchar *u2 = p2;
   
           while (len--) {
                   if (*u1 != *u2)
                           return (int)*u1 - (int)*u2;
           }
   
           return 0;
   }
   
 /**  /**
  * Return a quoted string with the full pathname of the indicated filename.   * Return a quoted string with the full pathname of the indicated filename.
  * The string " (in MODNAME)" may also be appended.  The returned pointer   * The string " (in MODNAME)" may also be appended.  The returned pointer
Line 1226  int handle_partial_dir(const char *fname, int create) Line 1348  int handle_partial_dir(const char *fname, int create)
                         }                          }
                         statret = -1;                          statret = -1;
                 }                  }
                if (statret < 0 && do_mkdir(dir, 0700) < 0) {                if (statret < 0 && make_path(dir, 0700, 0) < 0) {
                         *fn = '/';                          *fn = '/';
                         return 0;                          return 0;
                 }                  }
Line 1299  int unsafe_symlink(const char *dest, const char *src) Line 1421  int unsafe_symlink(const char *dest, const char *src)
 /* Return the date and time as a string.  Some callers tweak returned buf. */  /* Return the date and time as a string.  Some callers tweak returned buf. */
 char *timestring(time_t t)  char *timestring(time_t t)
 {  {
        static char TimeBuf[200];        static int ndx = 0;
         static char buffers[4][20]; /* We support 4 simultaneous timestring results. */
         char *TimeBuf = buffers[ndx = (ndx + 1) % 4];
         struct tm *tm = localtime(&t);          struct tm *tm = localtime(&t);
        char *p;        int len = snprintf(TimeBuf, sizeof buffers[0], "%4d/%02d/%02d %02d:%02d:%02d",
                  (int)tm->tm_year + 1900, (int)tm->tm_mon + 1, (int)tm->tm_mday,
                  (int)tm->tm_hour, (int)tm->tm_min, (int)tm->tm_sec);
         assert(len > 0); /* Silence gcc warning */
   
 #ifdef HAVE_STRFTIME  
         strftime(TimeBuf, sizeof TimeBuf - 1, "%Y/%m/%d %H:%M:%S", tm);  
 #else  
         strlcpy(TimeBuf, asctime(tm), sizeof TimeBuf);  
 #endif  
   
         if ((p = strchr(TimeBuf, '\n')) != NULL)  
                 *p = '\0';  
   
         return TimeBuf;          return TimeBuf;
 }  }
   
 /* Determine if two time_t values are equivalent (either exact, or in  /* Determine if two time_t values are equivalent (either exact, or in
  * the modification timestamp window established by --modify-window).   * the modification timestamp window established by --modify-window).
 * * Returns 1 if the times the "same", or 0 if they are different. */
 * @retval 0 if the times should be treated as the sameint same_time(time_t f1_sec, unsigned long f1_nsec, time_t f2_sec, unsigned long f2_nsec)
 * 
 * @retval +1 if the first is later 
 * 
 * @retval -1 if the 2nd is later 
 **/ 
int cmp_time(time_t file1, time_t file2) 
 {  {
        if (file2 > file1) {        if (modify_window == 0)
                /* The final comparison makes sure that modify_window doesn't overflow a                return f1_sec == f2_sec;
                 * time_t, which would mean that file2 must be in the equality window. */        if (modify_window < 0)
                if (!modify_window || (file2 > file1 + modify_window && file1 + modify_window > file1))                return f1_sec == f2_sec && f1_nsec == f2_nsec;
                        return -1;        /* The nano seconds doesn't figure into these checks -- time windows don't care about that. */
        } else if (file1 > file2) {        if (f2_sec > f1_sec)
                if (!modify_window || (file1 > file2 + modify_window && file2 + modify_window > file2))                return f2_sec - f1_sec <= modify_window;
                        return 1;        return f1_sec - f2_sec <= modify_window;
        } 
        return 0; 
 }  }
   
 #ifdef __INSURE__XX  #ifdef __INSURE__XX
Line 1409  const char *find_filename_suffix(const char *fn, int f Line 1519  const char *find_filename_suffix(const char *fn, int f
                 } else if (s_len == 5) {                  } else if (s_len == 5) {
                         if (strcmp(s+1, "orig") == 0)                          if (strcmp(s+1, "orig") == 0)
                                 continue;                                  continue;
                } else if (s_len > 2 && had_tilde                } else if (s_len > 2 && had_tilde && s[1] == '~' && isDigit(s + 2))
                    && s[1] == '~' && isDigit(s + 2)) 
                         continue;                          continue;
                 *len_ptr = s_len;                  *len_ptr = s_len;
                 suf = s;                  suf = s;
Line 1421  const char *find_filename_suffix(const char *fn, int f Line 1530  const char *find_filename_suffix(const char *fn, int f
                         if (!isDigit(s))                          if (!isDigit(s))
                                 return suf;                                  return suf;
                 }                  }
                /* An all-digit suffix may not be that signficant. */                /* An all-digit suffix may not be that significant. */
                 s = suf;                  s = suf;
         }          }
   
Line 1485  uint32 fuzzy_distance(const char *s1, unsigned len1, c Line 1594  uint32 fuzzy_distance(const char *s1, unsigned len1, c
 #define BB_PER_SLOT_INTS (BB_SLOT_SIZE / 4) /* Number of int32s per slot */  #define BB_PER_SLOT_INTS (BB_SLOT_SIZE / 4) /* Number of int32s per slot */
   
 struct bitbag {  struct bitbag {
    uint32 **bits;        uint32 **bits;
    int slot_cnt;        int slot_cnt;
 };  };
   
 struct bitbag *bitbag_create(int max_ndx)  struct bitbag *bitbag_create(int max_ndx)
Line 1494  struct bitbag *bitbag_create(int max_ndx) Line 1603  struct bitbag *bitbag_create(int max_ndx)
         struct bitbag *bb = new(struct bitbag);          struct bitbag *bb = new(struct bitbag);
         bb->slot_cnt = (max_ndx + BB_PER_SLOT_BITS - 1) / BB_PER_SLOT_BITS;          bb->slot_cnt = (max_ndx + BB_PER_SLOT_BITS - 1) / BB_PER_SLOT_BITS;
   
        if (!(bb->bits = (uint32**)calloc(bb->slot_cnt, sizeof (uint32*))))        bb->bits = new_array0(uint32*, bb->slot_cnt);
                out_of_memory("bitbag_create"); 
   
         return bb;          return bb;
 }  }
Line 1505  void bitbag_set_bit(struct bitbag *bb, int ndx) Line 1613  void bitbag_set_bit(struct bitbag *bb, int ndx)
         int slot = ndx / BB_PER_SLOT_BITS;          int slot = ndx / BB_PER_SLOT_BITS;
         ndx %= BB_PER_SLOT_BITS;          ndx %= BB_PER_SLOT_BITS;
   
        if (!bb->bits[slot]) {        if (!bb->bits[slot])
                if (!(bb->bits[slot] = (uint32*)calloc(BB_PER_SLOT_INTS, 4)))                bb->bits[slot] = new_array0(uint32, BB_PER_SLOT_INTS);
                        out_of_memory("bitbag_set_bit"); 
        } 
   
         bb->bits[slot][ndx/32] |= 1u << (ndx % 32);          bb->bits[slot][ndx/32] |= 1u << (ndx % 32);
 }  }
Line 1576  void flist_ndx_push(flist_ndx_list *lp, int ndx) Line 1682  void flist_ndx_push(flist_ndx_list *lp, int ndx)
 {  {
         struct flist_ndx_item *item;          struct flist_ndx_item *item;
   
        if (!(item = new(struct flist_ndx_item)))        item = new(struct flist_ndx_item);
                out_of_memory("flist_ndx_push"); 
         item->next = NULL;          item->next = NULL;
         item->ndx = ndx;          item->ndx = ndx;
         if (lp->tail)          if (lp->tail)
Line 1613  int flist_ndx_pop(flist_ndx_list *lp) Line 1718  int flist_ndx_pop(flist_ndx_list *lp)
  * After the size check, the list's count is incremented by 1 and a pointer   * After the size check, the list's count is incremented by 1 and a pointer
  * to the "new" list item is returned.   * to the "new" list item is returned.
  */   */
void *expand_item_list(item_list *lp, size_t item_size,void *expand_item_list(item_list *lp, size_t item_size, const char *desc, int incr)
                       const char *desc, int incr) 
 {  {
         /* First time through, 0 <= 0, so list is expanded. */          /* First time through, 0 <= 0, so list is expanded. */
         if (lp->malloced <= lp->count) {          if (lp->malloced <= lp->count) {
                 void *new_ptr;                  void *new_ptr;
                size_t new_size = lp->malloced;                size_t expand_size;
                 if (incr < 0)                  if (incr < 0)
                        new_size += -incr; /* increase slowly */                        expand_size = -incr; /* increase slowly */
                else if (new_size < (size_t)incr)                else if (lp->malloced < (size_t)incr)
                        new_size = incr;                        expand_size = incr - lp->malloced;
                else if (new_size)                else if (lp->malloced)
                        new_size *= 2;                        expand_size = lp->malloced; /* double in size */
                 else                  else
                        new_size = 1;                        expand_size = 1;
                if (new_size <= lp->malloced)                if (SIZE_MAX/item_size - expand_size < lp->malloced)
                         overflow_exit("expand_item_list");                          overflow_exit("expand_item_list");
                /* Using _realloc_array() lets us pass the size, not a type. */                expand_size += lp->malloced;
                new_ptr = _realloc_array(lp->items, item_size, new_size);                new_ptr = realloc_buf(lp->items, expand_size * item_size);
                 if (DEBUG_GTE(FLIST, 3)) {                  if (DEBUG_GTE(FLIST, 3)) {
                         rprintf(FINFO, "[%s] expand %s to %s bytes, did%s move\n",                          rprintf(FINFO, "[%s] expand %s to %s bytes, did%s move\n",
                                who_am_i(), desc, big_num(new_size * item_size),                                who_am_i(), desc, big_num(expand_size * item_size),
                                 new_ptr == lp->items ? " not" : "");                                  new_ptr == lp->items ? " not" : "");
                 }                  }
                 if (!new_ptr)  
                         out_of_memory("expand_item_list");  
   
                 lp->items = new_ptr;                  lp->items = new_ptr;
                lp->malloced = new_size;                lp->malloced = expand_size;
         }          }
         return (char*)lp->items + (lp->count++ * item_size);          return (char*)lp->items + (lp->count++ * item_size);
   }
   
   /* This zeroing of memory won't be optimized away by the compiler. */
   void force_memzero(void *buf, size_t len)
   {
           volatile uchar *z = buf;
           while (len-- > 0)
                   *z++ = '\0';
 }  }

Removed from v.1.1.1.3  
changed lines
  Added in v.1.1.1.4


FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>