Fixed failing hunks.
authorWayne Davison <wayned@samba.org>
Sun, 3 Dec 2006 09:35:26 +0000 (09:35 +0000)
committerWayne Davison <wayned@samba.org>
Sun, 3 Dec 2006 09:35:26 +0000 (09:35 +0000)
acls.diff
atimes.diff
backup-dir-dels.diff
detect-renamed.diff
early-checksum.diff
fake-super.diff
flags.diff
omit-dir-changes.diff
time-limit.diff
xattrs.diff

index e36c1d7..f74d403 100644 (file)
--- a/acls.diff
+++ b/acls.diff
@@ -31,7 +31,7 @@ latest ACL-enabling patch to send files to an older ACL-enabled rsync.
  popt_OBJS=popt/findme.o  popt/popt.o  popt/poptconfig.o \
 --- old/acls.c
 +++ new/acls.c
-@@ -0,0 +1,1098 @@
+@@ -0,0 +1,1096 @@
 +/*
 + * Handle passing Access Control Lists between systems.
 + *
@@ -64,6 +64,7 @@ latest ACL-enabling patch to send files to an older ACL-enabled rsync.
 +extern int list_only;
 +extern int orig_umask;
 +extern int preserve_acls;
++extern int flist_extra_ndx;
 +extern unsigned int file_struct_len;
 +
 +/* === ACL structures === */
@@ -549,7 +550,7 @@ latest ACL-enabling patch to send files to an older ACL-enabled rsync.
 +                              free_acl(sxp);
 +                              return -1;
 +                      }
-+              } else if (errno == ENOTSUP) {
++              } else if (errno == ENOTSUP || errno == ENOSYS) {
 +                      /* ACLs are not supported, so pretend we have a basic ACL. */
 +                      if (type == SMB_ACL_TYPE_ACCESS)
 +                              rsync_acl_fake_perms(racl, sxp->st.st_mode);
@@ -645,10 +646,8 @@ latest ACL-enabling patch to send files to an older ACL-enabled rsync.
 +                              sxp->def_acl = racl;
 +              }
 +
-+              /* Avoid sending values that can be inferred from other data,
-+               * but only when preserve_acls == 1 (it is 2 when we must be
-+               * backward compatible with older acls.diff versions). */
-+              if (type == SMB_ACL_TYPE_ACCESS && preserve_acls == 1)
++              /* Avoid sending values that can be inferred from other data. */
++              if (type == SMB_ACL_TYPE_ACCESS)
 +                      rsync_acl_strip_perms(racl);
 +              if ((ndx = find_matching_rsync_acl(type, racl_list, racl)) != -1) {
 +                      write_byte(f, type == SMB_ACL_TYPE_ACCESS ? 'a' : 'd');
@@ -767,14 +766,12 @@ latest ACL-enabling patch to send files to an older ACL-enabled rsync.
 +{
 +      SMB_ACL_TYPE_T type;
 +      item_list *racl_list;
-+      char *ndx_ptr;
 +
 +      if (S_ISLNK(file->mode))
 +              return;
 +
 +      type = SMB_ACL_TYPE_ACCESS;
 +      racl_list = &access_acl_list;
-+      ndx_ptr = (char*)file + file_struct_len;
 +      do {
 +              char tag = read_byte(f);
 +              int ndx;
@@ -811,9 +808,11 @@ latest ACL-enabling patch to send files to an older ACL-enabled rsync.
 +                              exit_cleanup(RERR_STREAMIO);
 +                      }
 +              }
-+              SIVAL(ndx_ptr, 0, ndx);
++              if (type == SMB_ACL_TYPE_ACCESS)
++                      F_ACL(file) = ndx;
++              else
++                      F_DEFACL(file) = ndx;
 +              racl_list = &default_acl_list;
-+              ndx_ptr += 4;
 +      } while (BUMP_TYPE(type) && S_ISDIR(file->mode));
 +}
 +
@@ -824,7 +823,6 @@ latest ACL-enabling patch to send files to an older ACL-enabled rsync.
 +      SMB_ACL_TYPE_T type;
 +      rsync_acl *racl;
 +      item_list *racl_list;
-+      char *ndx_ptr;
 +      int ndx;
 +
 +      if (S_ISLNK(file->mode))
@@ -833,7 +831,6 @@ latest ACL-enabling patch to send files to an older ACL-enabled rsync.
 +      type = SMB_ACL_TYPE_ACCESS;
 +      racl = sxp->acc_acl;
 +      racl_list = &access_acl_list;
-+      ndx_ptr = (char*)file + file_struct_len;
 +      do {
 +              if (!racl)
 +                      ndx = -1;
@@ -845,10 +842,12 @@ latest ACL-enabling patch to send files to an older ACL-enabled rsync.
 +                      new_duo->sacl = NULL;
 +                      *racl = empty_rsync_acl;
 +              }
-+              SIVAL(ndx_ptr, 0, ndx);
++              if (type == SMB_ACL_TYPE_ACCESS)
++                      F_ACL(file) = ndx;
++              else
++                      F_DEFACL(file) = ndx;
 +              racl = sxp->def_acl;
 +              racl_list = &default_acl_list;
-+              ndx_ptr += 4;
 +      } while (BUMP_TYPE(type) && S_ISDIR(sxp->st.st_mode));
 +
 +      free_acl(sxp);
@@ -942,7 +941,6 @@ latest ACL-enabling patch to send files to an older ACL-enabled rsync.
 +{
 +      int unchanged = 1;
 +      SMB_ACL_TYPE_T type;
-+      char *ndx_ptr;
 +
 +      if (!dry_run && (read_only || list_only)) {
 +              errno = EROFS;
@@ -953,15 +951,13 @@ latest ACL-enabling patch to send files to an older ACL-enabled rsync.
 +              return 1;
 +
 +      type = SMB_ACL_TYPE_ACCESS;
-+      ndx_ptr = (char*)file + file_struct_len;
 +      do {
 +              acl_duo *duo_item;
++              int32 ndx;
 +              BOOL eq;
-+              int32 ndx = IVAL(ndx_ptr, 0);
-+
-+              ndx_ptr += 4;
 +
 +              if (type == SMB_ACL_TYPE_ACCESS) {
++                      ndx = F_ACL(file);
 +                      if (ndx < 0 || (size_t)ndx >= access_acl_list.count)
 +                              continue;
 +                      duo_item = access_acl_list.items;
@@ -969,6 +965,7 @@ latest ACL-enabling patch to send files to an older ACL-enabled rsync.
 +                      eq = sxp->acc_acl
 +                          && rsync_acl_equal_enough(sxp->acc_acl, &duo_item->racl, file->mode);
 +              } else {
++                      ndx = F_DEFACL(file);
 +                      if (ndx < 0 || (size_t)ndx >= default_acl_list.count)
 +                              continue;
 +                      duo_item = default_acl_list.items;
@@ -1093,7 +1090,8 @@ latest ACL-enabling patch to send files to an older ACL-enabled rsync.
 +              /* Couldn't get an ACL.  Darn. */
 +              switch (errno) {
 +              case ENOTSUP:
-+                      /* ACLs are disabled.  We could yell at the user to turn them on, but... */
++              case ENOSYS:
++                      /* No ACLs are available. */
 +                      break;
 +              case ENOENT:
 +                      if (dry_run) {
@@ -1132,15 +1130,15 @@ latest ACL-enabling patch to send files to an older ACL-enabled rsync.
 +#endif /* SUPPORT_ACLS */
 --- old/backup.c
 +++ new/backup.c
-@@ -29,6 +29,7 @@ extern char *backup_suffix;
- extern char *backup_dir;
+@@ -23,6 +23,7 @@
  
+ extern int verbose;
  extern int am_root;
 +extern int preserve_acls;
  extern int preserve_devices;
  extern int preserve_specials;
  extern int preserve_links;
-@@ -94,7 +95,8 @@ path
+@@ -95,7 +96,8 @@ path
  ****************************************************************************/
  static int make_bak_dir(char *fullpath)
  {
@@ -1150,7 +1148,7 @@ latest ACL-enabling patch to send files to an older ACL-enabled rsync.
        char *rel = fullpath + backup_dir_len;
        char *end = rel + strlen(rel);
        char *p = end;
-@@ -126,15 +128,24 @@ static int make_bak_dir(char *fullpath)
+@@ -127,15 +129,24 @@ static int make_bak_dir(char *fullpath)
                if (p >= rel) {
                        /* Try to transfer the directory settings of the
                         * actual dir that the files are coming from. */
@@ -1179,7 +1177,7 @@ latest ACL-enabling patch to send files to an older ACL-enabled rsync.
                        }
                }
                *p = '/';
-@@ -172,15 +183,18 @@ static int robust_move(const char *src, 
+@@ -173,15 +184,18 @@ static int robust_move(const char *src, 
   * We will move the file to be deleted into a parallel directory tree. */
  static int keep_backup(const char *fname)
  {
@@ -1200,9 +1198,9 @@ latest ACL-enabling patch to send files to an older ACL-enabled rsync.
  
        if (!(file = make_file(fname, NULL, NULL, 0, NO_FILTERS)))
                return 1; /* the file could have disappeared */
-@@ -188,6 +202,13 @@ static int keep_backup(const char *fname
-       if (!(buf = get_backup_name(fname)))
+@@ -191,6 +205,13 @@ static int keep_backup(const char *fname
                return 0;
+       }
  
 +#ifdef SUPPORT_ACLS
 +      if (preserve_acls) {
@@ -1214,7 +1212,7 @@ latest ACL-enabling patch to send files to an older ACL-enabled rsync.
        /* Check to see if this is a device file, or link */
        if ((am_root && preserve_devices && IS_DEVICE(file->mode))
         || (preserve_specials && IS_SPECIAL(file->mode))) {
-@@ -256,7 +277,7 @@ static int keep_backup(const char *fname
+@@ -261,7 +282,7 @@ static int keep_backup(const char *fname
                if (robust_move(fname, buf) != 0) {
                        rsyserr(FERROR, errno, "keep_backup failed: %s -> \"%s\"",
                                full_fname(fname), buf);
@@ -1326,7 +1324,7 @@ latest ACL-enabling patch to send files to an older ACL-enabled rsync.
  extern int preserve_links;
  extern int preserve_hard_links;
  extern int preserve_devices;
-@@ -135,6 +136,8 @@ static void list_file_entry(struct file_
+@@ -143,6 +144,8 @@ static void list_file_entry(struct file_
  
        permstring(permbuf, f->mode);
  
@@ -1335,46 +1333,21 @@ latest ACL-enabling patch to send files to an older ACL-enabled rsync.
  #ifdef SUPPORT_LINKS
        if (preserve_links && S_ISLNK(f->mode)) {
                rprintf(FINFO, "%s %11.0f %s %s -> %s\n",
-@@ -496,6 +499,9 @@ static struct file_struct *receive_file_
-       char thisname[MAXPATHLEN];
-       unsigned int l1 = 0, l2 = 0;
-       int alloc_len, basename_len, dirname_len, linkname_len, sum_len;
-+#ifdef SUPPORT_ACLS
-+      int xtra_len;
-+#endif
-       OFF_T file_length;
-       char *basename, *dirname, *bp;
-       struct file_struct *file;
-@@ -599,13 +605,27 @@ static struct file_struct *receive_file_
-       sum_len = always_checksum && S_ISREG(mode) ? MD4_SUM_LENGTH : 0;
+@@ -621,6 +624,12 @@ static struct file_struct *recv_file_ent
+       }
+ #endif
  
 +#ifdef SUPPORT_ACLS
 +      /* We need one or two index int32s when we're preserving ACLs. */
 +      if (preserve_acls)
-+              xtra_len = (S_ISDIR(mode) ? 2 : 1) * 4;
-+      else
-+              xtra_len = 0;
++              extra_len += (S_ISDIR(mode) ? 2 : 1) * sizeof (union flist_extras);
 +#endif
 +
-       alloc_len = file_struct_len + dirname_len + basename_len
-+#ifdef SUPPORT_ACLS
-+                + xtra_len
-+#endif
-                 + linkname_len + sum_len;
-       bp = pool_alloc(flist->file_pool, alloc_len, "receive_file_entry");
-       file = (struct file_struct *)bp;
-       memset(bp, 0, file_struct_len);
-       bp += file_struct_len;
-+#ifdef SUPPORT_ACLS
-+      bp += xtra_len;
-+#endif
+       sum_len = always_checksum && S_ISREG(mode) ? MD4_SUM_LENGTH : 0;
  
-       file->modtime = modtime;
-       file->length = file_length;
-@@ -700,6 +720,11 @@ static struct file_struct *receive_file_
-               read_buf(f, sum, checksum_len);
+       alloc_len = file_struct_len + dirname_len + basename_len
+@@ -725,6 +734,11 @@ static struct file_struct *recv_file_ent
+               read_buf(f, bp, checksum_len);
        }
  
 +#ifdef SUPPORT_ACLS
@@ -1385,7 +1358,7 @@ latest ACL-enabling patch to send files to an older ACL-enabled rsync.
        return file;
  }
  
-@@ -957,6 +982,9 @@ static struct file_struct *send_file_nam
+@@ -977,6 +991,9 @@ static struct file_struct *send_file_nam
                                          unsigned short flags)
  {
        struct file_struct *file;
@@ -1395,7 +1368,7 @@ latest ACL-enabling patch to send files to an older ACL-enabled rsync.
  
        file = make_file(fname, flist, stp, flags,
                         f == -2 ? SERVER_FILTERS : ALL_FILTERS);
-@@ -966,6 +994,15 @@ static struct file_struct *send_file_nam
+@@ -986,11 +1003,24 @@ static struct file_struct *send_file_nam
        if (chmod_modes && !S_ISLNK(file->mode))
                file->mode = tweak_mode(file->mode, chmod_modes);
  
@@ -1411,22 +1384,15 @@ latest ACL-enabling patch to send files to an older ACL-enabled rsync.
        maybe_emit_filelist_progress(flist->count + flist_count_offset);
  
        flist_expand(flist);
-@@ -973,6 +1010,15 @@ static struct file_struct *send_file_nam
-       if (file->basename[0]) {
-               flist->files[flist->count++] = file;
-               send_file_entry(file, f);
-+#ifdef SUPPORT_ACLS
-+              if (preserve_acls && f >= 0)
-+                      send_acl(&sx, f);
-+#endif
-+      } else {
+       flist->files[flist->count++] = file;
+       send_file_entry(file, f);
 +#ifdef SUPPORT_ACLS
-+              if (preserve_acls && f >= 0)
-+                      free_acl(&sx);
++      if (preserve_acls && f >= 0)
++              send_acl(&sx, f);
 +#endif
-       }
        return file;
  }
 --- old/generator.c
 +++ new/generator.c
 @@ -35,6 +35,7 @@ extern int do_progress;
@@ -1437,15 +1403,15 @@ latest ACL-enabling patch to send files to an older ACL-enabled rsync.
  extern int preserve_links;
  extern int preserve_devices;
  extern int preserve_specials;
-@@ -85,6 +86,7 @@ extern long block_size; /* "long" becaus
- extern int max_delete;
- extern int force_delete;
- extern int one_file_system;
-+extern mode_t orig_umask;
+@@ -89,6 +90,7 @@ extern int one_file_system;
+ extern int file_struct_len;
  extern struct stats stats;
  extern dev_t filesystem_dev;
++extern mode_t orig_umask;
  extern char *backup_dir;
-@@ -445,22 +447,27 @@ static void do_delete_pass(struct file_l
+ extern char *backup_suffix;
+ extern int backup_suffix_len;
+@@ -447,22 +449,27 @@ static void do_delete_pass(struct file_l
                rprintf(FINFO, "                    \r");
  }
  
@@ -1457,12 +1423,12 @@ latest ACL-enabling patch to send files to an older ACL-enabled rsync.
 +       && (sxp->st.st_mode & CHMOD_BITS) != (file->mode & CHMOD_BITS))
                return 0;
  
--      if (am_root && preserve_uid && st->st_uid != file->uid)
-+      if (am_root && preserve_uid && sxp->st.st_uid != file->uid)
+-      if (am_root && preserve_uid && st->st_uid != F_UID(file))
++      if (am_root && preserve_uid && sxp->st.st_uid != F_UID(file))
                return 0;
  
--      if (preserve_gid && file->gid != GID_NONE && st->st_gid != file->gid)
-+      if (preserve_gid && file->gid != GID_NONE && sxp->st.st_gid != file->gid)
+-      if (preserve_gid && F_GID(file) != GID_NONE && st->st_gid != F_GID(file))
++      if (preserve_gid && F_GID(file) != GID_NONE && sxp->st.st_gid != F_GID(file))
                return 0;
  
 +#ifdef SUPPORT_ACLS
@@ -1478,7 +1444,7 @@ latest ACL-enabling patch to send files to an older ACL-enabled rsync.
             int32 iflags, uchar fnamecmp_type, const char *xname)
  {
        if (statret >= 0) { /* A from-dest-dir statret can == 1! */
-@@ -468,20 +475,24 @@ void itemize(struct file_struct *file, i
+@@ -470,20 +477,24 @@ void itemize(struct file_struct *file, i
                    : S_ISDIR(file->mode) ? !omit_dir_times
                    : !S_ISLNK(file->mode);
  
@@ -1494,12 +1460,12 @@ latest ACL-enabling patch to send files to an older ACL-enabled rsync.
 -              if ((file->mode & CHMOD_BITS) != (st->st_mode & CHMOD_BITS))
 +              if ((file->mode & CHMOD_BITS) != (sxp->st.st_mode & CHMOD_BITS))
                        iflags |= ITEM_REPORT_PERMS;
--              if (preserve_uid && am_root && file->uid != st->st_uid)
-+              if (preserve_uid && am_root && file->uid != sxp->st.st_uid)
+-              if (preserve_uid && am_root && F_UID(file) != st->st_uid)
++              if (preserve_uid && am_root && F_UID(file) != sxp->st.st_uid)
                        iflags |= ITEM_REPORT_OWNER;
-               if (preserve_gid && file->gid != GID_NONE
--                  && st->st_gid != file->gid)
-+                  && sxp->st.st_gid != file->gid)
+               if (preserve_gid && F_GID(file) != GID_NONE
+-                  && st->st_gid != F_GID(file))
++                  && sxp->st.st_gid != F_GID(file))
                        iflags |= ITEM_REPORT_GROUP;
 +#ifdef SUPPORT_ACLS
 +              if (preserve_acls && set_acl(NULL, file, sxp) == 0)
@@ -1508,7 +1474,7 @@ latest ACL-enabling patch to send files to an older ACL-enabled rsync.
        } else
                iflags |= ITEM_IS_NEW;
  
-@@ -734,7 +745,7 @@ void check_for_finished_hlinks(int itemi
+@@ -735,7 +746,7 @@ void check_for_finished_hlinks(int itemi
   * handling the file, -1 if no dest-linking occurred, or a non-negative
   * value if we found an alternate basis file. */
  static int try_dests_reg(struct file_struct *file, char *fname, int ndx,
@@ -1517,7 +1483,7 @@ latest ACL-enabling patch to send files to an older ACL-enabled rsync.
                         int maybe_ATTRS_REPORT, enum logcode code)
  {
        int best_match = -1;
-@@ -743,7 +754,7 @@ static int try_dests_reg(struct file_str
+@@ -744,7 +755,7 @@ static int try_dests_reg(struct file_str
  
        do {
                pathjoin(cmpbuf, MAXPATHLEN, basis_dir[j], fname);
@@ -1526,7 +1492,7 @@ latest ACL-enabling patch to send files to an older ACL-enabled rsync.
                        continue;
                switch (match_level) {
                case 0:
-@@ -751,16 +762,20 @@ static int try_dests_reg(struct file_str
+@@ -752,16 +763,20 @@ static int try_dests_reg(struct file_str
                        match_level = 1;
                        /* FALL THROUGH */
                case 1:
@@ -1550,7 +1516,7 @@ latest ACL-enabling patch to send files to an older ACL-enabled rsync.
                                continue;
                        best_match = j;
                        match_level = 3;
-@@ -775,7 +790,7 @@ static int try_dests_reg(struct file_str
+@@ -776,7 +791,7 @@ static int try_dests_reg(struct file_str
        if (j != best_match) {
                j = best_match;
                pathjoin(cmpbuf, MAXPATHLEN, basis_dir[j], fname);
@@ -1559,7 +1525,7 @@ latest ACL-enabling patch to send files to an older ACL-enabled rsync.
                        return -1;
        }
  
-@@ -783,7 +798,7 @@ static int try_dests_reg(struct file_str
+@@ -784,15 +799,20 @@ static int try_dests_reg(struct file_str
  #ifdef SUPPORT_HARD_LINKS
                if (link_dest) {
                        int i = itemizing && (verbose > 1 || stdout_format_has_i > 1);
@@ -1567,9 +1533,8 @@ latest ACL-enabling patch to send files to an older ACL-enabled rsync.
 +                      if (hard_link_one(file, ndx, fname, 0, sxp,
                                          cmpbuf, 1, i, code) < 0)
                                goto try_a_copy;
-                       if (preserve_hard_links && file->link_u.links) {
-@@ -793,8 +808,13 @@ static int try_dests_reg(struct file_str
-                       }
+                       if (preserve_hard_links && IS_HLINKED(file))
+                               hard_link_cluster(file, ndx, itemizing, code, j);
                } else
  #endif
 -              if (itemizing)
@@ -1584,7 +1549,7 @@ latest ACL-enabling patch to send files to an older ACL-enabled rsync.
                if (verbose > 1 && maybe_ATTRS_REPORT) {
                        rprintf(FCLIENT, "%s is uptodate\n", fname);
                }
-@@ -810,8 +830,13 @@ static int try_dests_reg(struct file_str
+@@ -808,8 +828,13 @@ static int try_dests_reg(struct file_str
                        }
                        return -1;
                }
@@ -1600,7 +1565,7 @@ latest ACL-enabling patch to send files to an older ACL-enabled rsync.
                set_file_attrs(fname, file, NULL, 0);
                if (maybe_ATTRS_REPORT
                 && ((!itemizing && verbose && match_level == 2)
-@@ -832,7 +857,7 @@ static int try_dests_reg(struct file_str
+@@ -830,7 +855,7 @@ static int try_dests_reg(struct file_str
   * handling the file, or -1 if no dest-linking occurred, or a non-negative
   * value if we found an alternate basis file. */
  static int try_dests_non(struct file_struct *file, char *fname, int ndx,
@@ -1609,7 +1574,7 @@ latest ACL-enabling patch to send files to an older ACL-enabled rsync.
                         int maybe_ATTRS_REPORT, enum logcode code)
  {
        char lnk[MAXPATHLEN];
-@@ -864,24 +889,24 @@ static int try_dests_non(struct file_str
+@@ -862,24 +887,24 @@ static int try_dests_non(struct file_str
  
        do {
                pathjoin(cmpbuf, MAXPATHLEN, basis_dir[j], fname);
@@ -1639,16 +1604,16 @@ latest ACL-enabling patch to send files to an older ACL-enabled rsync.
                                continue;
                        break;
  #endif
-@@ -895,7 +920,7 @@ static int try_dests_non(struct file_str
+@@ -893,7 +918,7 @@ static int try_dests_non(struct file_str
                        break;
                case TYPE_SPECIAL:
                case TYPE_DEVICE:
--                      if (stp->st_rdev != file->u.rdev)
-+                      if (sxp->st.st_rdev != file->u.rdev)
+-                      if (stp->st_rdev != MAKEDEV(F_DMAJOR(file), F_DMINOR(file)))
++                      if (sxp->st.st_rdev != MAKEDEV(F_DMAJOR(file), F_DMINOR(file)))
                                continue;
                        break;
  #ifdef SUPPORT_LINKS
-@@ -912,7 +937,11 @@ static int try_dests_non(struct file_str
+@@ -910,7 +935,11 @@ static int try_dests_non(struct file_str
                        match_level = 2;
                        best_match = j;
                }
@@ -1661,7 +1626,7 @@ latest ACL-enabling patch to send files to an older ACL-enabled rsync.
                        match_level = 3;
                        best_match = j;
                        break;
-@@ -925,7 +954,7 @@ static int try_dests_non(struct file_str
+@@ -923,7 +952,7 @@ static int try_dests_non(struct file_str
        if (j != best_match) {
                j = best_match;
                pathjoin(cmpbuf, MAXPATHLEN, basis_dir[j], fname);
@@ -1670,7 +1635,7 @@ latest ACL-enabling patch to send files to an older ACL-enabled rsync.
                        return -1;
        }
  
-@@ -956,7 +985,15 @@ static int try_dests_non(struct file_str
+@@ -954,7 +983,15 @@ static int try_dests_non(struct file_str
                            : ITEM_LOCAL_CHANGE
                             + (match_level == 3 ? ITEM_XNAME_FOLLOWS : 0);
                        char *lp = match_level == 3 ? "" : NULL;
@@ -1687,7 +1652,7 @@ latest ACL-enabling patch to send files to an older ACL-enabled rsync.
                }
                if (verbose > 1 && maybe_ATTRS_REPORT) {
                        rprintf(FCLIENT, "%s%s is uptodate\n",
-@@ -969,6 +1006,7 @@ static int try_dests_non(struct file_str
+@@ -967,6 +1004,7 @@ static int try_dests_non(struct file_str
  }
  
  static int phase = 0;
@@ -1695,7 +1660,7 @@ latest ACL-enabling patch to send files to an older ACL-enabled rsync.
  
  /* Acts on the_file_list->file's ndx'th item, whose name is fname.  If a dir,
   * make sure it exists, and has the right permissions/timestamp info.  For
-@@ -990,7 +1028,8 @@ static void recv_generator(char *fname, 
+@@ -988,7 +1026,8 @@ static void recv_generator(char *fname, 
        static int need_fuzzy_dirlist = 0;
        struct file_struct *fuzzy_file = NULL;
        int fd = -1, f_copy = -1;
@@ -1705,7 +1670,7 @@ latest ACL-enabling patch to send files to an older ACL-enabled rsync.
        struct file_struct *back_file = NULL;
        int statret, real_ret, stat_errno;
        char *fnamecmp, *partialptr, *backupptr = NULL;
-@@ -1046,6 +1085,9 @@ static void recv_generator(char *fname, 
+@@ -1044,6 +1083,9 @@ static void recv_generator(char *fname, 
                } else if (!dry_run)
                        return;
        }
@@ -1715,7 +1680,7 @@ latest ACL-enabling patch to send files to an older ACL-enabled rsync.
        if (dry_run > 1) {
                statret = -1;
                stat_errno = ENOENT;
-@@ -1053,7 +1095,7 @@ static void recv_generator(char *fname, 
+@@ -1051,7 +1093,7 @@ static void recv_generator(char *fname, 
                const char *dn = file->dirname ? file->dirname : ".";
                if (parent_dirname != dn && strcmp(parent_dirname, dn) != 0) {
                        if (relative_paths && !implied_dirs
@@ -1724,7 +1689,7 @@ latest ACL-enabling patch to send files to an older ACL-enabled rsync.
                         && create_directory_path(fname) < 0) {
                                rsyserr(FERROR, errno,
                                        "recv_generator: mkdir %s failed",
-@@ -1065,6 +1107,10 @@ static void recv_generator(char *fname, 
+@@ -1063,6 +1105,10 @@ static void recv_generator(char *fname, 
                        }
                        if (fuzzy_basis)
                                need_fuzzy_dirlist = 1;
@@ -1735,7 +1700,7 @@ latest ACL-enabling patch to send files to an older ACL-enabled rsync.
                }
                parent_dirname = dn;
  
-@@ -1074,7 +1120,7 @@ static void recv_generator(char *fname, 
+@@ -1072,7 +1118,7 @@ static void recv_generator(char *fname, 
                        need_fuzzy_dirlist = 0;
                }
  
@@ -1744,7 +1709,7 @@ latest ACL-enabling patch to send files to an older ACL-enabled rsync.
                                    keep_dirlinks && S_ISDIR(file->mode));
                stat_errno = errno;
        }
-@@ -1092,8 +1138,9 @@ static void recv_generator(char *fname, 
+@@ -1090,8 +1136,9 @@ static void recv_generator(char *fname, 
         * mode based on the local permissions and some heuristics. */
        if (!preserve_perms) {
                int exists = statret == 0
@@ -1756,7 +1721,7 @@ latest ACL-enabling patch to send files to an older ACL-enabled rsync.
        }
  
        if (S_ISDIR(file->mode)) {
-@@ -1102,8 +1149,8 @@ static void recv_generator(char *fname, 
+@@ -1100,8 +1147,8 @@ static void recv_generator(char *fname, 
                 * file of that name and it is *not* a directory, then
                 * we need to delete it.  If it doesn't exist, then
                 * (perhaps recursively) create it. */
@@ -1767,7 +1732,7 @@ latest ACL-enabling patch to send files to an older ACL-enabled rsync.
                                return;
                        statret = -1;
                }
-@@ -1112,14 +1159,14 @@ static void recv_generator(char *fname, 
+@@ -1110,14 +1157,14 @@ static void recv_generator(char *fname, 
                        dry_run++;
                }
                real_ret = statret;
@@ -1784,7 +1749,7 @@ latest ACL-enabling patch to send files to an older ACL-enabled rsync.
                                              itemizing, maybe_ATTRS_REPORT, code);
                        if (j == -2) {
                                itemizing = 0;
-@@ -1128,7 +1175,11 @@ static void recv_generator(char *fname, 
+@@ -1126,7 +1173,11 @@ static void recv_generator(char *fname, 
                                statret = 1;
                }
                if (itemizing && f_out != -1) {
@@ -1797,7 +1762,7 @@ latest ACL-enabling patch to send files to an older ACL-enabled rsync.
                                statret ? ITEM_LOCAL_CHANGE : 0, 0, NULL);
                }
                if (real_ret != 0 && do_mkdir(fname,file->mode) < 0 && errno != EEXIST) {
-@@ -1148,21 +1199,21 @@ static void recv_generator(char *fname, 
+@@ -1146,21 +1197,21 @@ static void recv_generator(char *fname, 
                                return;
                        }
                }
@@ -1809,14 +1774,14 @@ latest ACL-enabling patch to send files to an older ACL-enabled rsync.
 -                      real_st.st_dev = filesystem_dev;
 +                      real_sx.st.st_dev = filesystem_dev;
                if (delete_during && f_out != -1 && !phase && dry_run < 2
-                   && (file->flags & FLAG_DEL_HERE))
+                   && (file->flags & FLAG_XFER_DIR))
 -                      delete_in_dir(the_file_list, fname, file, &real_st);
 -              return;
 +                      delete_in_dir(the_file_list, fname, file, &real_sx.st);
 +              goto cleanup;
        }
  
-       if (preserve_hard_links && file->link_u.links
+       if (preserve_hard_links && IS_HLINKED(file)
 -          && hard_link_check(file, ndx, fname, statret, &st,
 +          && hard_link_check(file, ndx, fname, statret, &sx,
                               itemizing, code, HL_CHECK_MASTER))
@@ -1825,7 +1790,7 @@ latest ACL-enabling patch to send files to an older ACL-enabled rsync.
  
        if (preserve_links && S_ISLNK(file->mode)) {
  #ifdef SUPPORT_LINKS
-@@ -1180,15 +1231,15 @@ static void recv_generator(char *fname, 
+@@ -1179,14 +1230,14 @@ static void recv_generator(char *fname, 
                        char lnk[MAXPATHLEN];
                        int len;
  
@@ -1833,18 +1798,17 @@ latest ACL-enabling patch to send files to an older ACL-enabled rsync.
 +                      if (!S_ISLNK(sx.st.st_mode))
                                statret = -1;
                        else if ((len = readlink(fname, lnk, MAXPATHLEN-1)) > 0
-                             && strncmp(lnk, file->u.link, len) == 0
-                             && file->u.link[len] == '\0') {
+                             && strncmp(lnk, sl, len) == 0 && sl[len] == '\0') {
                                /* The link is pointing to the right place. */
                                if (itemizing)
 -                                      itemize(file, ndx, 0, &st, 0, 0, NULL);
 -                              set_file_attrs(fname, file, &st, maybe_ATTRS_REPORT);
 +                                      itemize(file, ndx, 0, &sx, 0, 0, NULL);
 +                              set_file_attrs(fname, file, &sx, maybe_ATTRS_REPORT);
-                               if (preserve_hard_links && file->link_u.links)
-                                       hard_link_cluster(file, ndx, itemizing, code);
+                               if (preserve_hard_links && IS_HLINKED(file))
+                                       hard_link_cluster(file, ndx, itemizing, code, -1);
                                if (remove_source_files == 1)
-@@ -1197,10 +1248,10 @@ static void recv_generator(char *fname, 
+@@ -1195,10 +1246,10 @@ static void recv_generator(char *fname, 
                        }
                        /* Not the right symlink (or not a symlink), so
                         * delete it. */
@@ -1857,16 +1821,16 @@ latest ACL-enabling patch to send files to an older ACL-enabled rsync.
                                              itemizing, maybe_ATTRS_REPORT, code);
                        if (j == -2) {
  #ifndef CAN_HARDLINK_SYMLINK
-@@ -1216,7 +1267,7 @@ static void recv_generator(char *fname, 
+@@ -1214,7 +1265,7 @@ static void recv_generator(char *fname, 
                                statret = 1;
                }
-               if (preserve_hard_links && file->link_u.links
+               if (preserve_hard_links && IS_HLINKED(file)
 -                  && hard_link_check(file, ndx, fname, -1, &st,
 +                  && hard_link_check(file, ndx, fname, -1, &sx,
                                       itemizing, code, HL_SKIP))
                        return;
-               if (do_symlink(file->u.link, fname) != 0) {
-@@ -1225,7 +1276,7 @@ static void recv_generator(char *fname, 
+               if (do_symlink(sl, fname) != 0) {
+@@ -1223,7 +1274,7 @@ static void recv_generator(char *fname, 
                } else {
                        set_file_attrs(fname, file, NULL, 0);
                        if (itemizing) {
@@ -1875,7 +1839,7 @@ latest ACL-enabling patch to send files to an older ACL-enabled rsync.
                                        ITEM_LOCAL_CHANGE, 0, NULL);
                        }
                        if (code != FNONE && verbose)
-@@ -1247,31 +1298,36 @@ static void recv_generator(char *fname, 
+@@ -1246,31 +1297,36 @@ static void recv_generator(char *fname, 
                if (statret == 0) {
                        char *t;
                        if (IS_DEVICE(file->mode)) {
@@ -1891,9 +1855,9 @@ latest ACL-enabling patch to send files to an older ACL-enabled rsync.
                        }
                        if (statret == 0
 -                       && (st.st_mode & ~CHMOD_BITS) == (file->mode & ~CHMOD_BITS)
--                       && st.st_rdev == file->u.rdev) {
+-                       && st.st_rdev == rdev) {
 +                       && (sx.st.st_mode & ~CHMOD_BITS) == (file->mode & ~CHMOD_BITS)
-+                       && sx.st.st_rdev == file->u.rdev) {
++                       && sx.st.st_rdev == rdev) {
                                /* The device or special file is identical. */
 -                              if (itemizing)
 -                                      itemize(file, ndx, 0, &st, 0, 0, NULL);
@@ -1906,8 +1870,8 @@ latest ACL-enabling patch to send files to an older ACL-enabled rsync.
 +                                      itemize(file, ndx, 0, &sx, 0, 0, NULL);
 +                              }
 +                              set_file_attrs(fname, file, &sx, maybe_ATTRS_REPORT);
-                               if (preserve_hard_links && file->link_u.links)
-                                       hard_link_cluster(file, ndx, itemizing, code);
+                               if (preserve_hard_links && IS_HLINKED(file))
+                                       hard_link_cluster(file, ndx, itemizing, code, -1);
                                if (remove_source_files == 1)
                                        goto return_with_success;
 -                              return;
@@ -1922,16 +1886,16 @@ latest ACL-enabling patch to send files to an older ACL-enabled rsync.
                                              itemizing, maybe_ATTRS_REPORT, code);
                        if (j == -2) {
  #ifndef CAN_HARDLINK_SPECIAL
-@@ -1287,7 +1343,7 @@ static void recv_generator(char *fname, 
+@@ -1286,7 +1342,7 @@ static void recv_generator(char *fname, 
                                statret = 1;
                }
-               if (preserve_hard_links && file->link_u.links
+               if (preserve_hard_links && IS_HLINKED(file)
 -                  && hard_link_check(file, ndx, fname, -1, &st,
 +                  && hard_link_check(file, ndx, fname, -1, &sx,
                                       itemizing, code, HL_SKIP))
                        return;
                if (verbose > 2) {
-@@ -1300,7 +1356,11 @@ static void recv_generator(char *fname, 
+@@ -1299,7 +1355,11 @@ static void recv_generator(char *fname, 
                } else {
                        set_file_attrs(fname, file, NULL, 0);
                        if (itemizing) {
@@ -1944,7 +1908,7 @@ latest ACL-enabling patch to send files to an older ACL-enabled rsync.
                                        ITEM_LOCAL_CHANGE, 0, NULL);
                        }
                        if (code != FNONE && verbose)
-@@ -1310,7 +1370,7 @@ static void recv_generator(char *fname, 
+@@ -1309,7 +1369,7 @@ static void recv_generator(char *fname, 
                        if (remove_source_files == 1)
                                goto return_with_success;
                }
@@ -1953,7 +1917,7 @@ latest ACL-enabling patch to send files to an older ACL-enabled rsync.
        }
  
        if (!S_ISREG(file->mode)) {
-@@ -1344,7 +1404,7 @@ static void recv_generator(char *fname, 
+@@ -1343,7 +1403,7 @@ static void recv_generator(char *fname, 
        }
  
        if (update_only && statret == 0
@@ -1962,7 +1926,7 @@ latest ACL-enabling patch to send files to an older ACL-enabled rsync.
                if (verbose > 1)
                        rprintf(FINFO, "%s is newer\n", fname);
                return;
-@@ -1353,20 +1413,20 @@ static void recv_generator(char *fname, 
+@@ -1352,20 +1412,20 @@ static void recv_generator(char *fname, 
        fnamecmp = fname;
        fnamecmp_type = FNAMECMP_FNAME;
  
@@ -1987,7 +1951,7 @@ latest ACL-enabling patch to send files to an older ACL-enabled rsync.
                }
                if (j >= 0) {
                        fnamecmp = fnamecmpbuf;
-@@ -1376,7 +1436,7 @@ static void recv_generator(char *fname, 
+@@ -1375,7 +1435,7 @@ static void recv_generator(char *fname, 
        }
  
        real_ret = statret;
@@ -1996,7 +1960,7 @@ latest ACL-enabling patch to send files to an older ACL-enabled rsync.
  
        if (partial_dir && (partialptr = partial_dir_fname(fname)) != NULL
            && link_stat(partialptr, &partial_st, 0) == 0
-@@ -1395,7 +1455,7 @@ static void recv_generator(char *fname, 
+@@ -1394,7 +1454,7 @@ static void recv_generator(char *fname, 
                                rprintf(FINFO, "fuzzy basis selected for %s: %s\n",
                                        fname, fnamecmpbuf);
                        }
@@ -2005,16 +1969,16 @@ latest ACL-enabling patch to send files to an older ACL-enabled rsync.
                        statret = 0;
                        fnamecmp = fnamecmpbuf;
                        fnamecmp_type = FNAMECMP_FUZZY;
-@@ -1404,7 +1464,7 @@ static void recv_generator(char *fname, 
+@@ -1403,7 +1463,7 @@ static void recv_generator(char *fname, 
  
        if (statret != 0) {
-               if (preserve_hard_links && file->link_u.links
+               if (preserve_hard_links && IS_HLINKED(file)
 -                  && hard_link_check(file, ndx, fname, statret, &st,
 +                  && hard_link_check(file, ndx, fname, statret, &sx,
                                       itemizing, code, HL_SKIP))
                        return;
                if (stat_errno == ENOENT)
-@@ -1414,39 +1474,52 @@ static void recv_generator(char *fname, 
+@@ -1413,39 +1473,52 @@ static void recv_generator(char *fname, 
                return;
        }
  
@@ -2052,8 +2016,8 @@ latest ACL-enabling patch to send files to an older ACL-enabled rsync.
                }
 -              set_file_attrs(fname, file, &st, maybe_ATTRS_REPORT);
 +              set_file_attrs(fname, file, &sx, maybe_ATTRS_REPORT);
-               if (preserve_hard_links && file->link_u.links)
-                       hard_link_cluster(file, ndx, itemizing, code);
+               if (preserve_hard_links && IS_HLINKED(file))
+                       hard_link_cluster(file, ndx, itemizing, code, -1);
                if (remove_source_files != 1)
 -                      return;
 +                      goto cleanup;
@@ -2074,10 +2038,10 @@ latest ACL-enabling patch to send files to an older ACL-enabled rsync.
                fnamecmp = partialptr;
                fnamecmp_type = FNAMECMP_PARTIAL_DIR;
                statret = 0;
-@@ -1470,17 +1543,21 @@ static void recv_generator(char *fname, 
+@@ -1469,17 +1542,21 @@ static void recv_generator(char *fname, 
          pretend_missing:
                /* pretend the file didn't exist */
-               if (preserve_hard_links && file->link_u.links
+               if (preserve_hard_links && IS_HLINKED(file)
 -                  && hard_link_check(file, ndx, fname, statret, &st,
 +                  && hard_link_check(file, ndx, fname, statret, &sx,
                                       itemizing, code, HL_SKIP))
@@ -2099,18 +2063,18 @@ latest ACL-enabling patch to send files to an older ACL-enabled rsync.
                }
                if (!(back_file = make_file(fname, NULL, NULL, 0, NO_FILTERS))) {
                        close(fd);
-@@ -1491,7 +1568,7 @@ static void recv_generator(char *fname, 
+@@ -1490,7 +1567,7 @@ static void recv_generator(char *fname, 
                                full_fname(backupptr));
-                       free(back_file);
+                       unmake_file(back_file);
                        close(fd);
 -                      return;
 +                      goto cleanup;
                }
                if ((f_copy = do_open(backupptr,
                    O_WRONLY | O_CREAT | O_TRUNC | O_EXCL, 0600)) < 0) {
-@@ -1499,14 +1576,14 @@ static void recv_generator(char *fname, 
+@@ -1498,14 +1575,14 @@ static void recv_generator(char *fname, 
                                full_fname(backupptr));
-                       free(back_file);
+                       unmake_file(back_file);
                        close(fd);
 -                      return;
 +                      goto cleanup;
@@ -2125,7 +2089,7 @@ latest ACL-enabling patch to send files to an older ACL-enabled rsync.
        }
  
        if (verbose > 2)
-@@ -1524,24 +1601,32 @@ static void recv_generator(char *fname, 
+@@ -1523,24 +1600,32 @@ static void recv_generator(char *fname, 
                        iflags |= ITEM_BASIS_TYPE_FOLLOWS;
                if (fnamecmp_type == FNAMECMP_FUZZY)
                        iflags |= ITEM_XNAME_FOLLOWS;
@@ -2143,8 +2107,8 @@ latest ACL-enabling patch to send files to an older ACL-enabled rsync.
        }
  
        if (!do_xfers) {
-               if (preserve_hard_links && file->link_u.links)
-                       hard_link_cluster(file, ndx, itemizing, code);
+               if (preserve_hard_links && IS_HLINKED(file))
+                       hard_link_cluster(file, ndx, itemizing, code, -1);
 -              return;
 +              goto cleanup;
        }
@@ -2163,7 +2127,7 @@ latest ACL-enabling patch to send files to an older ACL-enabled rsync.
  
        if (f_copy >= 0) {
                close(f_copy);
-@@ -1554,6 +1639,13 @@ static void recv_generator(char *fname, 
+@@ -1553,6 +1638,13 @@ static void recv_generator(char *fname, 
        }
  
        close(fd);
@@ -2177,7 +2141,7 @@ latest ACL-enabling patch to send files to an older ACL-enabled rsync.
  }
  
  void generate_files(int f_out, struct file_list *flist, char *local_name)
-@@ -1615,6 +1707,8 @@ void generate_files(int f_out, struct fi
+@@ -1614,6 +1706,8 @@ void generate_files(int f_out, struct fi
         * notice that and let us know via the redo pipe (or its closing). */
        ignore_timeout = 1;
  
@@ -2188,15 +2152,15 @@ latest ACL-enabling patch to send files to an older ACL-enabled rsync.
  
 --- old/hlink.c
 +++ new/hlink.c
-@@ -26,6 +26,7 @@
- extern int verbose;
+@@ -27,6 +27,7 @@ extern int verbose;
+ extern int dry_run;
  extern int do_xfers;
  extern int link_dest;
 +extern int preserve_acls;
  extern int make_backups;
+ extern int flist_extra_ndx;
  extern int remove_source_files;
- extern int stdout_format_has_i;
-@@ -146,15 +147,19 @@ void init_hard_links(void)
+@@ -155,15 +156,19 @@ void init_hard_links(void)
  
  #ifdef SUPPORT_HARD_LINKS
  static int maybe_hard_link(struct file_struct *file, int ndx,
@@ -2220,7 +2184,7 @@ latest ACL-enabling patch to send files to an older ACL-enabled rsync.
                                        ITEM_LOCAL_CHANGE | ITEM_XNAME_FOLLOWS,
                                        0, "");
                        }
-@@ -169,13 +174,13 @@ static int maybe_hard_link(struct file_s
+@@ -178,13 +183,13 @@ static int maybe_hard_link(struct file_s
                        return -1;
                }
        }
@@ -2236,7 +2200,7 @@ latest ACL-enabling patch to send files to an older ACL-enabled rsync.
                    enum logcode code, int skip)
  {
  #ifdef SUPPORT_HARD_LINKS
-@@ -216,7 +221,7 @@ int hard_link_check(struct file_struct *
+@@ -228,7 +233,7 @@ int hard_link_check(struct file_struct *
                                                 || st2.st_ino != st3.st_ino)
                                                        continue;
                                                statret = 1;
@@ -2245,7 +2209,7 @@ latest ACL-enabling patch to send files to an older ACL-enabled rsync.
                                                if (verbose < 2 || !stdout_format_has_i) {
                                                        itemizing = 0;
                                                        code = FNONE;
-@@ -226,12 +231,16 @@ int hard_link_check(struct file_struct *
+@@ -238,12 +243,16 @@ int hard_link_check(struct file_struct *
                                        if (!unchanged_file(cmpbuf, file, &st3))
                                                continue;
                                        statret = 1;
@@ -2265,7 +2229,7 @@ latest ACL-enabling patch to send files to an older ACL-enabled rsync.
                                        toname, &st2, itemizing, code);
                        if (remove_source_files == 1 && do_xfers) {
                                char numbuf[4];
-@@ -249,7 +258,7 @@ int hard_link_check(struct file_struct *
+@@ -261,7 +270,7 @@ int hard_link_check(struct file_struct *
  
  #ifdef SUPPORT_HARD_LINKS
  int hard_link_one(struct file_struct *file, int ndx, char *fname,
@@ -2274,7 +2238,7 @@ latest ACL-enabling patch to send files to an older ACL-enabled rsync.
                  int itemizing, enum logcode code)
  {
        if (do_link(toname, fname)) {
-@@ -265,7 +274,11 @@ int hard_link_one(struct file_struct *fi
+@@ -277,7 +286,11 @@ int hard_link_one(struct file_struct *fi
        }
  
        if (itemizing) {
@@ -2287,7 +2251,7 @@ latest ACL-enabling patch to send files to an older ACL-enabled rsync.
                        ITEM_LOCAL_CHANGE | ITEM_XNAME_FOLLOWS, 0,
                        terse ? "" : toname);
        }
-@@ -282,11 +295,12 @@ void hard_link_cluster(struct file_struc
+@@ -294,14 +307,15 @@ void hard_link_cluster(struct file_struc
  #ifdef SUPPORT_HARD_LINKS
        char hlink1[MAXPATHLEN];
        char *hlink2;
@@ -2295,15 +2259,18 @@ latest ACL-enabling patch to send files to an older ACL-enabled rsync.
 +      statx sx;
 +      STRUCT_STAT st;
        int statret, ndx = master;
+       struct hlist *hl = F_HLIST(file);
  
-       file->F_HLINDEX = FINISHED_LINK;
+       hl->hlindex = FINISHED_LINK;
+       if (dry_run)
+               hl->dest_used = dest_used + 1;
 -      if (link_stat(f_name(file, hlink1), &st1, 0) < 0)
 +      if (link_stat(f_name(file, hlink1), &st, 0) < 0)
                return;
-       if (!(file->flags & FLAG_HLINK_TOL)) {
-               while (!(file->flags & FLAG_HLINK_EOL)) {
-@@ -300,9 +314,13 @@ void hard_link_cluster(struct file_struc
-               if (file->F_HLINDEX != SKIPPED_LINK)
+       if (!(file->flags & FLAG_HLINK_FIRST)) {
+               while (!(file->flags & FLAG_HLINK_LAST)) {
+@@ -317,9 +331,13 @@ void hard_link_cluster(struct file_struc
+               if (hl->hlindex != SKIPPED_LINK)
                        continue;
                hlink2 = f_name(file, NULL);
 -              statret = link_stat(hlink2, &st2, 0);
@@ -5618,7 +5585,7 @@ latest ACL-enabling patch to send files to an older ACL-enabled rsync.
 +#endif /* SUPPORT_ACLS */
 --- old/log.c
 +++ new/log.c
-@@ -614,8 +614,10 @@ static void log_formatted(enum logcode c
+@@ -618,8 +618,10 @@ static void log_formatted(enum logcode c
                        c[5] = !(iflags & ITEM_REPORT_PERMS) ? '.' : 'p';
                        c[6] = !(iflags & ITEM_REPORT_OWNER) ? '.' : 'o';
                        c[7] = !(iflags & ITEM_REPORT_GROUP) ? '.' : 'g';
@@ -5706,7 +5673,7 @@ latest ACL-enabling patch to send files to an older ACL-enabled rsync.
  
 +              case 'A':
 +#ifdef SUPPORT_ACLS
-+                      preserve_acls++;
++                      preserve_acls = 1;
 +                      preserve_perms = 1;
 +                      break;
 +#else
@@ -5725,7 +5692,16 @@ latest ACL-enabling patch to send files to an older ACL-enabled rsync.
                default:
                        /* A large opt value means that set_refuse_options()
                         * turned this option off. */
-@@ -1529,6 +1559,10 @@ void server_options(char **args,int *arg
+@@ -1223,6 +1253,8 @@ int parse_arguments(int *argc, const cha
+               preserve_uid = flist_extra_ndx++;
+       if (preserve_gid)
+               preserve_gid = flist_extra_ndx++;
++      if (preserve_acls)
++              preserve_acls = flist_extra_ndx++;
+       *argv = poptGetArgs(pc);
+       *argc = count_args(*argv);
+@@ -1534,6 +1566,10 @@ void server_options(char **args,int *arg
  
        if (preserve_hard_links)
                argstr[x++] = 'H';
@@ -5738,7 +5714,7 @@ latest ACL-enabling patch to send files to an older ACL-enabled rsync.
        if (preserve_gid)
 --- old/receiver.c
 +++ new/receiver.c
-@@ -47,6 +47,7 @@ extern int keep_partial;
+@@ -48,6 +48,7 @@ extern int keep_partial;
  extern int checksum_seed;
  extern int inplace;
  extern int delay_updates;
@@ -5785,15 +5761,15 @@ latest ACL-enabling patch to send files to an older ACL-enabled rsync.
  extern int preserve_perms;
  extern int preserve_executability;
  extern int preserve_times;
-@@ -47,7 +48,6 @@ extern int preserve_gid;
+@@ -48,7 +49,6 @@ extern int preserve_gid;
  extern int inplace;
  extern int keep_dirlinks;
  extern int make_backups;
 -extern mode_t orig_umask;
  extern struct stats stats;
+ extern struct file_list *the_file_list;
  extern struct chmod_mode_struct *daemon_chmod_modes;
-@@ -100,7 +100,8 @@ void free_sums(struct sum_struct *s)
+@@ -153,7 +153,8 @@ void free_sums(struct sum_struct *s)
  
  /* This is only called when we aren't preserving permissions.  Figure out what
   * the permissions should be and return them merged back into the mode. */
@@ -5803,7 +5779,7 @@ latest ACL-enabling patch to send files to an older ACL-enabled rsync.
  {
        int new_mode;
        /* If the file already exists, we'll return the local permissions,
-@@ -117,56 +118,65 @@ mode_t dest_mode(mode_t flist_mode, mode
+@@ -170,56 +171,65 @@ mode_t dest_mode(mode_t flist_mode, mode
                                new_mode |= (new_mode & 0444) >> 2;
                }
        } else {
@@ -5873,37 +5849,37 @@ latest ACL-enabling patch to send files to an older ACL-enabled rsync.
                        updated = 1;
        }
  
--      change_uid = am_root && preserve_uid && st->st_uid != file->uid;
-+      change_uid = am_root && preserve_uid && sxp->st.st_uid != file->uid;
-       change_gid = preserve_gid && file->gid != GID_NONE
--              && st->st_gid != file->gid;
-+              && sxp->st.st_gid != file->gid;
+-      change_uid = am_root && preserve_uid && st->st_uid != F_UID(file);
++      change_uid = am_root && preserve_uid && sxp->st.st_uid != F_UID(file);
+       change_gid = preserve_gid && F_GID(file) != GID_NONE
+-              && st->st_gid != F_GID(file);
++              && sxp->st.st_gid != F_GID(file);
  #if !defined HAVE_LCHOWN && !defined CHOWN_MODIFIES_SYMLINK
 -      if (S_ISLNK(st->st_mode))
 +      if (S_ISLNK(sxp->st.st_mode))
                ;
        else
  #endif
-@@ -176,45 +186,57 @@ int set_file_attrs(char *fname, struct f
+@@ -229,45 +239,57 @@ int set_file_attrs(char *fname, struct f
                                rprintf(FINFO,
                                        "set uid of %s from %ld to %ld\n",
                                        fname,
--                                      (long)st->st_uid, (long)file->uid);
-+                                      (long)sxp->st.st_uid, (long)file->uid);
+-                                      (long)st->st_uid, (long)F_UID(file));
++                                      (long)sxp->st.st_uid, (long)F_UID(file));
                        }
                        if (change_gid) {
                                rprintf(FINFO,
                                        "set gid of %s from %ld to %ld\n",
                                        fname,
--                                      (long)st->st_gid, (long)file->gid);
-+                                      (long)sxp->st.st_gid, (long)file->gid);
+-                                      (long)st->st_gid, (long)F_GID(file));
++                                      (long)sxp->st.st_gid, (long)F_GID(file));
                        }
                }
                if (do_lchown(fname,
--                  change_uid ? file->uid : st->st_uid,
--                  change_gid ? file->gid : st->st_gid) != 0) {
-+                  change_uid ? file->uid : sxp->st.st_uid,
-+                  change_gid ? file->gid : sxp->st.st_gid) != 0) {
+-                  change_uid ? F_UID(file) : st->st_uid,
+-                  change_gid ? F_GID(file) : st->st_gid) != 0) {
++                  change_uid ? F_UID(file) : sxp->st.st_uid,
++                  change_gid ? F_GID(file) : sxp->st.st_gid) != 0) {
                        /* shouldn't have attempted to change uid or gid
                         * unless have the privilege */
                        rsyserr(FERROR, errno, "%s %s failed",
@@ -5952,7 +5928,7 @@ latest ACL-enabling patch to send files to an older ACL-enabled rsync.
                }
                if (ret == 0) /* ret == 1 if symlink could not be set */
                        updated = 1;
-@@ -227,6 +249,11 @@ int set_file_attrs(char *fname, struct f
+@@ -280,6 +302,11 @@ int set_file_attrs(char *fname, struct f
                else
                        rprintf(FCLIENT, "%s is uptodate\n", fname);
        }
@@ -5966,7 +5942,7 @@ latest ACL-enabling patch to send files to an older ACL-enabled rsync.
  
 --- old/rsync.h
 +++ new/rsync.h
-@@ -493,6 +493,14 @@ struct idev {
+@@ -495,6 +495,14 @@ struct idev {
  #define IN_LOOPBACKNET 127
  #endif
  
@@ -5981,7 +5957,20 @@ latest ACL-enabling patch to send files to an older ACL-enabled rsync.
  #define GID_NONE ((gid_t)-1)
  
  #define HL_CHECK_MASTER       0
-@@ -656,6 +664,17 @@ struct stats {
+@@ -540,10 +548,12 @@ union flist_extras {
+ /* When enabled, all entries have these: */
+ #define F_UID(f) FLIST_EXTRA(f, preserve_uid).uid
+ #define F_GID(f) FLIST_EXTRA(f, preserve_gid).gid
++#define F_ACL(f) FLIST_EXTRA(f, preserve_acls).num
+ /* These are per-entry optional and mutally exclusive: */
+ #define F_IDEV(f) FLIST_EXTRA(f, flist_extra_ndx).idev
+ #define F_HLIST(f) FLIST_EXTRA(f, flist_extra_ndx).hlist
++#define F_DEFACL(f) FLIST_EXTRA(f, flist_extra_ndx).num
+ /* These are per-entry optional, but always both or neither: */
+ #define F_DMAJOR(f) FLIST_EXTRA(f, flist_extra_ndx + (IS_HLINKED(f)? 1 : 0)).num
+@@ -667,6 +677,17 @@ struct stats {
  
  struct chmod_mode_struct;
  
@@ -5999,7 +5988,7 @@ latest ACL-enabling patch to send files to an older ACL-enabled rsync.
  #include "byteorder.h"
  #include "lib/mdfour.h"
  #include "lib/wildmatch.h"
-@@ -674,6 +693,16 @@ struct chmod_mode_struct;
+@@ -685,6 +706,16 @@ struct chmod_mode_struct;
  #define NORETURN __attribute__((__noreturn__))
  #endif
  
@@ -6755,16 +6744,16 @@ latest ACL-enabling patch to send files to an older ACL-enabled rsync.
  extern int numeric_ids;
  extern int am_root;
  
-@@ -273,7 +274,7 @@ void send_uid_list(int f)
-       if (numeric_ids)
-               return;
+@@ -270,7 +271,7 @@ void send_uid_list(int f)
+ {
+       struct idlist *list;
  
 -      if (preserve_uid) {
 +      if (preserve_uid || preserve_acls) {
                int len;
                /* we send sequences of uid/byte-length/name */
                for (list = uidlist; list; list = list->next) {
-@@ -290,7 +291,7 @@ void send_uid_list(int f)
+@@ -287,7 +288,7 @@ void send_uid_list(int f)
                write_int(f, 0);
        }
  
@@ -6773,7 +6762,7 @@ latest ACL-enabling patch to send files to an older ACL-enabled rsync.
                int len;
                for (list = gidlist; list; list = list->next) {
                        if (!list->name)
-@@ -311,7 +312,7 @@ void recv_uid_list(int f, struct file_li
+@@ -308,7 +309,7 @@ void recv_uid_list(int f, struct file_li
        int id, i;
        char *name;
  
@@ -6782,7 +6771,7 @@ latest ACL-enabling patch to send files to an older ACL-enabled rsync.
                /* read the uid list */
                while ((id = read_int(f)) != 0) {
                        int len = read_byte(f);
-@@ -323,7 +324,7 @@ void recv_uid_list(int f, struct file_li
+@@ -320,7 +321,7 @@ void recv_uid_list(int f, struct file_li
                }
        }
  
@@ -6791,7 +6780,7 @@ latest ACL-enabling patch to send files to an older ACL-enabled rsync.
                /* read the gid list */
                while ((id = read_int(f)) != 0) {
                        int len = read_byte(f);
-@@ -335,6 +336,16 @@ void recv_uid_list(int f, struct file_li
+@@ -332,6 +333,16 @@ void recv_uid_list(int f, struct file_li
                }
        }
  
index 06a961a..68b77bb 100644 (file)
@@ -15,16 +15,16 @@ To use this patch, run these commands for a successful build:
 +extern int preserve_atimes;
  extern int relative_paths;
  extern int implied_dirs;
- extern int ignore_perishable;
-@@ -127,6 +128,7 @@ void show_flist_stats(void)
+ extern int flist_extra_ndx;
+@@ -135,6 +136,7 @@ void show_flist_stats(void)
  static void list_file_entry(struct file_struct *f)
  {
        char permbuf[PERMSTRING_SIZE];
-+      time_t atime = preserve_atimes ? IVAL(ATIME_PTR(f), 0) : 0;
++      time_t atime = preserve_atimes ? F_ATIME(f) : 0;
  
        if (!f->basename) {
                /* this can happen if duplicate names were removed */
-@@ -137,16 +139,18 @@ static void list_file_entry(struct file_
+@@ -145,16 +147,18 @@ static void list_file_entry(struct file_
  
  #ifdef SUPPORT_LINKS
        if (preserve_links && S_ISLNK(f->mode)) {
@@ -33,7 +33,7 @@ To use this patch, run these commands for a successful build:
                        permbuf,
                        (double)f->length, timestring(f->modtime),
 +                      preserve_atimes ? timestring(atime) : "",
-                       f_name(f, NULL), f->u.link);
+                       f_name(f, NULL), F_SYMLINK(f));
        } else
  #endif
        {
@@ -45,7 +45,7 @@ To use this patch, run these commands for a successful build:
                        f_name(f, NULL));
        }
  }
-@@ -304,6 +308,7 @@ static void send_file_entry(struct file_
+@@ -312,6 +316,7 @@ static void send_file_entry(struct file_
  {
        unsigned short flags;
        static time_t modtime;
@@ -53,7 +53,7 @@ To use this patch, run these commands for a successful build:
        static mode_t mode;
        static int64 dev;
        static dev_t rdev;
-@@ -319,7 +324,7 @@ static void send_file_entry(struct file_
+@@ -327,7 +332,7 @@ static void send_file_entry(struct file_
  
        if (!file) {
                write_byte(f, 0);
@@ -62,12 +62,12 @@ To use this patch, run these commands for a successful build:
                dev = 0, rdev = MAKEDEV(0, 0);
                rdev_major = 0;
                uid = 0, gid = 0;
-@@ -365,6 +370,13 @@ static void send_file_entry(struct file_
+@@ -377,6 +382,13 @@ static void send_file_entry(struct file_
                flags |= XMIT_SAME_TIME;
        else
                modtime = file->modtime;
 +      if (preserve_atimes && !S_ISDIR(mode)) {
-+              time_t file_atime = IVAL(ATIME_PTR(file), 0);
++              time_t file_atime = F_ATIME(file);
 +              if (file_atime == atime)
 +                      flags |= XMIT_SAME_ATIME;
 +              else
@@ -75,8 +75,8 @@ To use this patch, run these commands for a successful build:
 +      }
  
  #ifdef SUPPORT_HARD_LINKS
-       if (file->link_u.idev) {
-@@ -418,6 +430,8 @@ static void send_file_entry(struct file_
+       if (tmp_idev.dev != 0) {
+@@ -429,6 +441,8 @@ static void send_file_entry(struct file_
                write_int(f, modtime);
        if (!(flags & XMIT_SAME_MODE))
                write_int(f, to_wire_mode(mode));
@@ -85,21 +85,16 @@ To use this patch, run these commands for a successful build:
        if (preserve_uid && !(flags & XMIT_SAME_UID)) {
                if (!numeric_ids)
                        add_uid(uid);
-@@ -484,6 +498,7 @@ static struct file_struct *receive_file_
-                                             unsigned short flags, int f)
+@@ -495,7 +509,7 @@ static void send_file_entry(struct file_
+ static struct file_struct *recv_file_entry(struct file_list *flist,
+                                          unsigned short flags, int f)
  {
-       static time_t modtime;
-+      static time_t atime;
+-      static time_t modtime;
++      static time_t modtime, atime;
        static mode_t mode;
        static int64 dev;
        static dev_t rdev;
-@@ -497,12 +512,13 @@ static struct file_struct *receive_file_
-       char thisname[MAXPATHLEN];
-       unsigned int l1 = 0, l2 = 0;
-       int alloc_len, basename_len, dirname_len, linkname_len, sum_len;
-+      int atime_len;
-       OFF_T file_length;
-       char *basename, *dirname, *bp;
+@@ -515,7 +529,7 @@ static struct file_struct *recv_file_ent
        struct file_struct *file;
  
        if (!flist) {
@@ -108,7 +103,7 @@ To use this patch, run these commands for a successful build:
                dev = 0, rdev = MAKEDEV(0, 0);
                rdev_major = 0;
                uid = 0, gid = 0;
-@@ -558,6 +574,8 @@ static struct file_struct *receive_file_
+@@ -571,6 +585,8 @@ static struct file_struct *recv_file_ent
                modtime = (time_t)read_int(f);
        if (!(flags & XMIT_SAME_MODE))
                mode = from_wire_mode(read_int(f));
@@ -117,82 +112,24 @@ To use this patch, run these commands for a successful build:
  
        if (chmod_modes && !S_ISLNK(mode))
                mode = tweak_mode(mode, chmod_modes);
-@@ -600,19 +618,23 @@ static struct file_struct *receive_file_
-       sum_len = always_checksum && S_ISREG(mode) ? MD4_SUM_LENGTH : 0;
-+      atime_len = preserve_atimes ? 4 : 0;
-+
-       alloc_len = file_struct_len + dirname_len + basename_len
--                + linkname_len + sum_len;
-+                + atime_len + linkname_len + sum_len;
-       bp = pool_alloc(flist->file_pool, alloc_len, "receive_file_entry");
-       file = (struct file_struct *)bp;
-       memset(bp, 0, file_struct_len);
--      bp += file_struct_len;
-+      bp += file_struct_len + atime_len;
-       file->modtime = modtime;
-       file->length = file_length;
-       file->mode = mode;
-       file->uid = uid;
-       file->gid = gid;
+@@ -643,6 +659,8 @@ static struct file_struct *recv_file_ent
+               F_UID(file) = uid;
+       if (preserve_gid)
+               F_GID(file) = gid;
 +      if (preserve_atimes)
-+              SIVAL(ATIME_PTR(file), 0, atime);
++              F_ATIME(file) = atime;
  
        if (dirname_len) {
                file->dirname = lastdir = bp;
-@@ -731,6 +753,7 @@ struct file_struct *make_file(char *fnam
-       char thisname[MAXPATHLEN];
-       char linkname[MAXPATHLEN];
-       int alloc_len, basename_len, dirname_len, linkname_len, sum_len;
-+      int atime_len;
-       char *basename, *dirname, *bp;
-       if (!flist || !flist->count)    /* Ignore lastdir when invalid. */
-@@ -854,8 +877,10 @@ struct file_struct *make_file(char *fnam
-       sum_len = always_checksum && am_sender && S_ISREG(st.st_mode)
-               ? MD4_SUM_LENGTH : 0;
-+      atime_len = preserve_atimes ? 4 : 0;
-+
-       alloc_len = file_struct_len + dirname_len + basename_len
--                + linkname_len + sum_len;
-+                + atime_len + linkname_len + sum_len;
-       if (flist)
-               bp = pool_alloc(flist->file_pool, alloc_len, "make_file");
-       else {
-@@ -865,7 +890,7 @@ struct file_struct *make_file(char *fnam
-       file = (struct file_struct *)bp;
-       memset(bp, 0, file_struct_len);
--      bp += file_struct_len;
-+      bp += file_struct_len + atime_len;
-       file->flags = flags;
-       file->modtime = st.st_mtime;
-@@ -873,6 +898,8 @@ struct file_struct *make_file(char *fnam
-       file->mode = st.st_mode;
-       file->uid = st.st_uid;
-       file->gid = st.st_gid;
+@@ -906,6 +924,8 @@ struct file_struct *make_file(const char
+               F_UID(file) = st.st_uid;
+       if (preserve_gid)
+               F_GID(file) = st.st_gid;
 +      if (preserve_atimes)
-+              SIVAL(ATIME_PTR(file), 0, st.st_atime);
- #ifdef SUPPORT_HARD_LINKS
-       if (flist && flist->hlink_pool) {
-@@ -1594,8 +1621,9 @@ static void clean_flist(struct file_list
-                       }
-                       /* Make sure we don't lose track of a user-specified
-                        * top directory. */
--                      flist->files[keep]->flags |= flist->files[drop]->flags
--                                                 & (FLAG_TOP_DIR|FLAG_DEL_HERE);
-+                      flist->files[keep]->flags
-+                          |= flist->files[drop]->flags
-+                           & (FLAG_TOP_DIR|FLAG_DEL_HERE);
-                       clear_file(flist->files[drop], flist);
++              F_ATIME(file) = st.st_atime;
  
+       if (dirname_len) {
+               file->dirname = lastdir = bp;
 --- old/generator.c
 +++ new/generator.c
 @@ -43,6 +43,7 @@ extern int preserve_perms;
@@ -203,33 +140,25 @@ To use this patch, run these commands for a successful build:
  extern int omit_dir_times;
  extern int delete_mode;
  extern int delete_before;
-@@ -90,6 +91,7 @@ extern dev_t filesystem_dev;
- extern char *backup_dir;
- extern char *backup_suffix;
- extern int backup_suffix_len;
-+extern unsigned int file_struct_len;
- extern struct file_list *the_file_list;
- extern struct filter_list_struct server_filter_list;
-@@ -409,6 +411,9 @@ void itemize(struct file_struct *file, i
+@@ -477,6 +478,9 @@ void itemize(struct file_struct *file, i
                  && (!(iflags & ITEM_XNAME_FOLLOWS) || *xname))
                 || (keep_time && cmp_time(file->modtime, st->st_mtime) != 0))
                        iflags |= ITEM_REPORT_TIME;
 +              if (preserve_atimes && !S_ISDIR(file->mode) && !S_ISLNK(file->mode)
-+               && cmp_time(IVAL(ATIME_PTR(file), 0), st->st_atime) != 0)
++               && cmp_time(F_ATIME(file), st->st_atime) != 0)
 +                      iflags |= ITEM_REPORT_ATIME;
                if ((file->mode & CHMOD_BITS) != (st->st_mode & CHMOD_BITS))
                        iflags |= ITEM_REPORT_PERMS;
-               if (preserve_uid && am_root && file->uid != st->st_uid)
-@@ -720,6 +725,8 @@ static int try_dests_reg(struct file_str
+               if (preserve_uid && am_root && F_UID(file) != st->st_uid)
+@@ -787,6 +791,8 @@ static int try_dests_reg(struct file_str
                        if (hard_link_one(file, ndx, fname, 0, stp,
                                          cmpbuf, 1, i, code) < 0)
                                goto try_a_copy;
 +                      if (preserve_atimes)
 +                              set_file_attrs(fname, file, stp, 0);
-                       if (preserve_hard_links && file->link_u.links) {
-                               if (dry_run)
-                                       file->link_u.links->link_dest_used = j + 1;
+                       if (preserve_hard_links && IS_HLINKED(file))
+                               hard_link_cluster(file, ndx, itemizing, code, j);
+               } else
 --- old/log.c
 +++ new/log.c
 @@ -37,6 +37,7 @@ extern int msg_fd_out;
@@ -237,10 +166,10 @@ To use this patch, run these commands for a successful build:
  extern int protocol_version;
  extern int preserve_times;
 +extern int preserve_atimes;
- extern int stdout_format_has_i;
- extern int stdout_format_has_o_or_i;
- extern int logfile_format_has_i;
-@@ -611,7 +612,8 @@ static void log_formatted(enum logcode c
+ extern int preserve_uid;
+ extern int preserve_gid;
+ extern int flist_extra_ndx;
+@@ -618,7 +619,8 @@ static void log_formatted(enum logcode c
                        c[5] = !(iflags & ITEM_REPORT_PERMS) ? '.' : 'p';
                        c[6] = !(iflags & ITEM_REPORT_OWNER) ? '.' : 'o';
                        c[7] = !(iflags & ITEM_REPORT_GROUP) ? '.' : 'g';
@@ -260,7 +189,7 @@ To use this patch, run these commands for a successful build:
  int update_only = 0;
  int cvs_exclude = 0;
  int dry_run = 0;
-@@ -311,8 +312,9 @@ void usage(enum logcode F)
+@@ -307,8 +308,9 @@ void usage(enum logcode F)
    rprintf(F,"     --devices               preserve device files (super-user only)\n");
    rprintf(F,"     --specials              preserve special files\n");
    rprintf(F," -D                          same as --devices --specials\n");
@@ -272,17 +201,26 @@ To use this patch, run these commands for a successful build:
    rprintf(F,"     --super                 receiver attempts super-user activities\n");
    rprintf(F," -S, --sparse                handle sparse files efficiently\n");
    rprintf(F," -n, --dry-run               show what would have been transferred\n");
-@@ -428,6 +430,9 @@ static struct poptOption long_options[] 
+@@ -425,6 +427,9 @@ static struct poptOption long_options[] 
    {"times",           't', POPT_ARG_VAL,    &preserve_times, 1, 0, 0 },
    {"no-times",         0,  POPT_ARG_VAL,    &preserve_times, 0, 0, 0 },
    {"no-t",             0,  POPT_ARG_VAL,    &preserve_times, 0, 0, 0 },
 +  {"atimes",          'U', POPT_ARG_VAL,    &preserve_atimes, 1, 0, 0 },
 +  {"no-atimes",        0,  POPT_ARG_VAL,    &preserve_atimes, 0, 0, 0 },
-+  {"no-k",             0,  POPT_ARG_VAL,    &preserve_atimes, 0, 0, 0 },
++  {"no-U",             0,  POPT_ARG_VAL,    &preserve_atimes, 0, 0, 0 },
    {"omit-dir-times",  'O', POPT_ARG_VAL,    &omit_dir_times, 2, 0, 0 },
    {"modify-window",    0,  POPT_ARG_INT,    &modify_window, OPT_MODIFY_WINDOW, 0, 0 },
    {"super",            0,  POPT_ARG_VAL,    &am_root, 2, 0, 0 },
-@@ -1538,6 +1543,8 @@ void server_options(char **args,int *arg
+@@ -1223,6 +1228,8 @@ int parse_arguments(int *argc, const cha
+               preserve_uid = flist_extra_ndx++;
+       if (preserve_gid)
+               preserve_gid = flist_extra_ndx++;
++      if (preserve_atimes)
++              preserve_atimes = flist_extra_ndx++;
+       *argv = poptGetArgs(pc);
+       *argc = count_args(*argv);
+@@ -1542,6 +1549,8 @@ void server_options(char **args,int *arg
                argstr[x++] = 'D';
        if (preserve_times)
                argstr[x++] = 't';
@@ -301,15 +239,7 @@ To use this patch, run these commands for a successful build:
  extern int preserve_times;
  extern int omit_dir_times;
  extern int am_root;
-@@ -49,6 +50,7 @@ extern int keep_dirlinks;
- extern int make_backups;
- extern mode_t orig_umask;
- extern struct stats stats;
-+extern unsigned int file_struct_len;
- extern struct chmod_mode_struct *daemon_chmod_modes;
- #if defined HAVE_ICONV_OPEN && defined HAVE_ICONV_H
-@@ -129,6 +131,7 @@ int set_file_attrs(char *fname, struct f
+@@ -182,6 +183,7 @@ int set_file_attrs(char *fname, struct f
        int updated = 0;
        STRUCT_STAT st2;
        int change_uid, change_gid;
@@ -317,7 +247,7 @@ To use this patch, run these commands for a successful build:
        mode_t new_mode = file->mode;
  
        if (!st) {
-@@ -148,18 +151,36 @@ int set_file_attrs(char *fname, struct f
+@@ -201,18 +203,36 @@ int set_file_attrs(char *fname, struct f
                }
        }
  
@@ -335,7 +265,7 @@ To use this patch, run these commands for a successful build:
 +      } else
 +              mtime = st->st_mtime;
 +      if (!(flags & ATTRS_SKIP_ATIME)) {
-+              time_t file_atime = IVAL(ATIME_PTR(file), 0);
++              time_t file_atime = F_ATIME(file);
 +              if (cmp_time(st->st_atime, file_atime) != 0) {
 +                      atime = file_atime;
 +                      updated = 1;
@@ -356,7 +286,7 @@ To use this patch, run these commands for a successful build:
 +                      updated = 0;
        }
  
-       change_uid = am_root && preserve_uid && st->st_uid != file->uid;
+       change_uid = am_root && preserve_uid && st->st_uid != F_UID(file);
 --- old/rsync.h
 +++ new/rsync.h
 @@ -54,6 +54,7 @@
@@ -375,15 +305,22 @@ To use this patch, run these commands for a successful build:
  
  #define FULL_FLUSH    1
  #define NORMAL_FLUSH  0
-@@ -534,6 +536,8 @@ struct file_struct {
-       uchar flags;    /* this item MUST remain last */
+@@ -532,6 +534,7 @@ union flist_extras {
+       struct idev *idev;      /* The hard-link info during matching */
+       struct hlist *hlist;    /* The hard-link info after matching */
+       int32 num;              /* A general-purpose number */
++      time_t time;            /* A time value */
  };
  
-+#define ATIME_PTR(f) (((uchar*)(f))+file_struct_len)
-+
- /*
-  * Start the flist array at FLIST_START entries and grow it
-  * by doubling until FLIST_LINEAR then grow by FLIST_LINEAR
+ #define FLIST_EXTRA(f,j) ((union flist_extras *)(f))[-(j)]
+@@ -540,6 +543,7 @@ union flist_extras {
+ /* When enabled, all entries have these: */
+ #define F_UID(f) FLIST_EXTRA(f, preserve_uid).uid
+ #define F_GID(f) FLIST_EXTRA(f, preserve_gid).gid
++#define F_ATIME(f) FLIST_EXTRA(f, preserve_atimes).time
+ /* These are per-entry optional and mutally exclusive: */
+ #define F_IDEV(f) FLIST_EXTRA(f, flist_extra_ndx).idev
 --- old/rsync.yo
 +++ new/rsync.yo
 @@ -328,8 +328,9 @@ to the detailed description below for a 
@@ -398,7 +335,7 @@ To use this patch, run these commands for a successful build:
       --super                 receiver attempts super-user activities
   -S, --sparse                handle sparse files efficiently
   -n, --dry-run               show what would have been transferred
-@@ -869,6 +870,12 @@ it is preserving modification times (see
+@@ -870,6 +871,12 @@ it is preserving modification times (see
  the directories on the receiving side, it is a good idea to use bf(-O).
  This option is inferred if you use bf(--backup) without bf(--backup-dir).
  
@@ -411,7 +348,7 @@ To use this patch, run these commands for a successful build:
  dit(bf(--super)) This tells the receiving side to attempt super-user
  activities even if the receiving rsync wasn't run by the super-user.  These
  activities include: preserving users via the bf(--owner) option, preserving
-@@ -1396,7 +1403,7 @@ with older versions of rsync, but that a
+@@ -1403,7 +1410,7 @@ with older versions of rsync, but that a
  verbose messages).
  
  The "%i" escape has a cryptic output that is 9 letters long.  The general
@@ -420,7 +357,7 @@ To use this patch, run these commands for a successful build:
  type of update being done, bf(X) is replaced by the file-type, and the
  other letters represent attributes that may be output if they are being
  modified.
-@@ -1436,7 +1443,7 @@ quote(itemization(
+@@ -1443,7 +1450,7 @@ quote(itemization(
    by the file transfer.
    it() A bf(t) means the modification time is different and is being updated
    to the sender's value (requires bf(--times)).  An alternate value of bf(T)
@@ -429,7 +366,7 @@ To use this patch, run these commands for a successful build:
    anytime a symlink is transferred, or when a file or device is transferred
    without bf(--times).
    it() A bf(p) means the permissions are different and are being updated to
-@@ -1445,7 +1452,10 @@ quote(itemization(
+@@ -1452,7 +1459,10 @@ quote(itemization(
    sender's value (requires bf(--owner) and super-user privileges).
    it() A bf(g) means the group is different and is being updated to the
    sender's value (requires bf(--group) and the authority to set the group).
index 29fb760..14842a2 100644 (file)
@@ -21,9 +21,9 @@ To use this patch, run these commands for a successful build:
 
 --- old/backup.c
 +++ new/backup.c
-@@ -23,10 +23,15 @@
- extern int verbose;
+@@ -30,10 +30,17 @@ extern int safe_symlinks;
+ extern int flist_extra_ndx;
+ extern int file_struct_len;
  extern int backup_dir_len;
 +extern int backup_dir_dels_len;
  extern unsigned int backup_dir_remainder;
@@ -34,19 +34,12 @@ To use this patch, run these commands for a successful build:
 +extern char *backup_suffix_dels;
  extern char *backup_dir;
 +extern char *backup_dir_dels;
- extern int am_root;
- extern int preserve_devices;
-@@ -34,6 +39,8 @@ extern int preserve_specials;
- extern int preserve_links;
- extern int safe_symlinks;
-+static int deleting;
 +
++static int deleting;
  /* make a complete pathname for backup file */
  char *get_backup_name(const char *fname)
- {
-@@ -51,11 +58,28 @@ char *get_backup_name(const char *fname)
+@@ -52,11 +59,28 @@ char *get_backup_name(const char *fname)
        return NULL;
  }
  
@@ -76,7 +69,7 @@ To use this patch, run these commands for a successful build:
  
        if (!fnamebak)
                return 0;
-@@ -95,7 +119,8 @@ path
+@@ -96,7 +120,8 @@ path
  static int make_bak_dir(char *fullpath)
  {
        STRUCT_STAT st;
@@ -86,17 +79,17 @@ To use this patch, run these commands for a successful build:
        char *end = rel + strlen(rel);
        char *p = end;
  
-@@ -185,7 +210,8 @@ static int keep_backup(const char *fname
+@@ -186,7 +211,8 @@ static int keep_backup(const char *fname
        if (!(file = make_file(fname, NULL, NULL, 0, NO_FILTERS)))
                return 1; /* the file could have disappeared */
  
--      if (!(buf = get_backup_name(fname)))
+-      if (!(buf = get_backup_name(fname))) {
 +      buf = deleting ? get_delete_name(fname) : get_backup_name(fname);
-+      if (!buf)
++      if (!buf) {
+               unmake_file(file);
                return 0;
-       /* Check to see if this is a device file, or link */
-@@ -280,3 +306,13 @@ int make_backup(const char *fname)
+       }
+@@ -285,3 +311,13 @@ int make_backup(const char *fname)
                return keep_backup(fname);
        return make_simple_backup(fname);
  }
@@ -112,7 +105,7 @@ To use this patch, run these commands for a successful build:
 +}
 --- old/generator.c
 +++ new/generator.c
-@@ -90,6 +90,9 @@ extern dev_t filesystem_dev;
+@@ -92,6 +92,9 @@ extern dev_t filesystem_dev;
  extern char *backup_dir;
  extern char *backup_suffix;
  extern int backup_suffix_len;
@@ -122,7 +115,7 @@ To use this patch, run these commands for a successful build:
  extern struct file_list *the_file_list;
  extern struct filter_list_struct server_filter_list;
  
-@@ -115,10 +118,14 @@ enum delret {
+@@ -117,10 +120,14 @@ enum delret {
  static enum delret delete_dir_contents(char *fname, int flags);
  
  
@@ -138,7 +131,7 @@ To use this patch, run these commands for a successful build:
  }
  
  /* Delete a file or directory.  If DEL_RECURSE is set in the flags, this will
-@@ -154,9 +161,9 @@ static enum delret delete_item(char *fbu
+@@ -156,9 +163,9 @@ static enum delret delete_item(char *fbu
        if (S_ISDIR(mode)) {
                what = "rmdir";
                ok = do_rmdir(fbuf) == 0;
@@ -196,7 +189,7 @@ To use this patch, run these commands for a successful build:
    {"list-only",        0,  POPT_ARG_VAL,    &list_only, 2, 0, 0 },
    {"read-batch",       0,  POPT_ARG_STRING, &batch_name, OPT_READ_BATCH, 0, 0 },
    {"write-batch",      0,  POPT_ARG_STRING, &batch_name, OPT_WRITE_BATCH, 0, 0 },
-@@ -1230,6 +1240,8 @@ int parse_arguments(int *argc, const cha
+@@ -1235,6 +1245,8 @@ int parse_arguments(int *argc, const cha
                        tmpdir = sanitize_path(NULL, tmpdir, NULL, 0, NULL);
                if (backup_dir)
                        backup_dir = sanitize_path(NULL, backup_dir, NULL, 0, NULL);
@@ -205,7 +198,7 @@ To use this patch, run these commands for a successful build:
        }
        if (server_filter_list.head && !am_sender) {
                struct filter_list_struct *elp = &server_filter_list;
-@@ -1247,6 +1259,14 @@ int parse_arguments(int *argc, const cha
+@@ -1252,6 +1264,14 @@ int parse_arguments(int *argc, const cha
                        if (check_filter(elp, backup_dir, 1) < 0)
                                goto options_rejected;
                }
@@ -220,7 +213,7 @@ To use this patch, run these commands for a successful build:
        }
  
        if (!backup_suffix)
-@@ -1258,6 +1278,16 @@ int parse_arguments(int *argc, const cha
+@@ -1263,6 +1283,16 @@ int parse_arguments(int *argc, const cha
                        backup_suffix);
                return 0;
        }
@@ -237,7 +230,7 @@ To use this patch, run these commands for a successful build:
        if (backup_dir) {
                backup_dir_len = strlcpy(backup_dir_buf, backup_dir, sizeof backup_dir_buf);
                backup_dir_remainder = sizeof backup_dir_buf - backup_dir_len;
-@@ -1281,6 +1311,31 @@ int parse_arguments(int *argc, const cha
+@@ -1286,6 +1316,31 @@ int parse_arguments(int *argc, const cha
                        "P *%s", backup_suffix);
                parse_rule(&filter_list, backup_dir_buf, 0, 0);
        }
@@ -269,7 +262,7 @@ To use this patch, run these commands for a successful build:
        if (make_backups && !backup_dir)
                omit_dir_times = 1;
  
-@@ -1645,6 +1700,10 @@ void server_options(char **args,int *arg
+@@ -1650,6 +1705,10 @@ void server_options(char **args,int *arg
                args[ac++] = "--backup-dir";
                args[ac++] = backup_dir;
        }
@@ -280,7 +273,7 @@ To use this patch, run these commands for a successful build:
  
        /* Only send --suffix if it specifies a non-default value. */
        if (strcmp(backup_suffix, backup_dir ? "" : BACKUP_SUFFIX) != 0) {
-@@ -1653,7 +1712,13 @@ void server_options(char **args,int *arg
+@@ -1658,7 +1717,13 @@ void server_options(char **args,int *arg
                        goto oom;
                args[ac++] = arg;
        }
index c190b33..458d142 100644 (file)
@@ -34,7 +34,7 @@ TODO:
 
 --- old/flist.c
 +++ new/flist.c
-@@ -53,6 +53,7 @@ extern int non_perishable_cnt;
+@@ -54,6 +54,7 @@ extern int non_perishable_cnt;
  extern int prune_empty_dirs;
  extern int copy_links;
  extern int copy_unsafe_links;
@@ -42,16 +42,16 @@ TODO:
  extern int protocol_version;
  extern int sanitize_paths;
  extern struct stats stats;
-@@ -70,6 +71,8 @@ int checksum_len;
- dev_t filesystem_dev; /* used to implement -x */
unsigned int file_struct_len;
+@@ -78,6 +79,8 @@ static dev_t tmp_rdev;
+ static struct idev tmp_idev;
static char tmp_sum[MD4_SUM_LENGTH];
  
 +struct file_list the_fattr_list;
 +
  static char empty_sum[MD4_SUM_LENGTH];
  static int flist_count_offset;
  
-@@ -252,6 +255,44 @@ static mode_t from_wire_mode(int mode)
+@@ -260,6 +263,44 @@ static mode_t from_wire_mode(int mode)
        return mode;
  }
  
@@ -74,7 +74,7 @@ TODO:
 +              return f1->length < f2->length ? -1 : 1;
 +
 +      if (always_checksum) {
-+              diff = u_memcmp(f1->u.sum, f2->u.sum, checksum_len);
++              diff = u_memcmp(F_SUM(f1), F_SUM(f2), checksum_len);
 +              if (diff)
 +                      return diff;
 +      } else if (f1->modtime != f2->modtime)
@@ -96,7 +96,7 @@ TODO:
  static void send_directory(int f, struct file_list *flist,
                           char *fbuf, int len);
  
-@@ -1388,6 +1429,25 @@ struct file_list *recv_file_list(int f)
+@@ -1395,6 +1436,25 @@ struct file_list *recv_file_list(int f)
  
        clean_flist(flist, relative_paths, 1);
  
@@ -105,7 +105,7 @@ TODO:
 +              the_fattr_list.count = j;
 +              the_fattr_list.files = new_array(struct file_struct *, j);
 +              if (!the_fattr_list.files)
-+                      goto oom;
++                      out_of_memory("recv_file_list");
 +              memcpy(the_fattr_list.files, flist->files,
 +                     j * sizeof (struct file_struct *));
 +              qsort(the_fattr_list.files, j,
@@ -124,7 +124,7 @@ TODO:
  
 --- old/generator.c
 +++ new/generator.c
-@@ -76,6 +76,7 @@ extern char *basis_dir[];
+@@ -77,6 +77,7 @@ extern char *basis_dir[];
  extern int compare_dest;
  extern int copy_dest;
  extern int link_dest;
@@ -132,7 +132,7 @@ TODO:
  extern int whole_file;
  extern int list_only;
  extern int new_root_dir;
-@@ -91,15 +92,18 @@ extern char *backup_dir;
+@@ -93,15 +94,18 @@ extern char *backup_dir;
  extern char *backup_suffix;
  extern int backup_suffix_len;
  extern struct file_list *the_file_list;
@@ -152,7 +152,7 @@ TODO:
  #define DEL_RECURSE           (1<<1) /* recurse */
  #define DEL_DIR_IS_EMPTY      (1<<2) /* internal delete_FUNCTIONS use only */
  
-@@ -121,11 +125,120 @@ static int is_backup_file(char *fn)
+@@ -123,11 +127,121 @@ static int is_backup_file(char *fn)
        return k > 0 && strcmp(fn+k, backup_suffix) == 0;
  }
  
@@ -178,15 +178,16 @@ TODO:
 +                      continue;
 +              }
 +              if (always_checksum) {
-+                      if (!f->u.sum) {
++                      if (!F_SUM(f)) {
 +                              if (fmid->modtime == f->modtime
 +                               && f_name_cmp(fmid, f) == 0)
 +                                      return -1; /* assume we can't help */
-+                              f->u.sum = pool_alloc(pool, MD4_SUM_LENGTH,
++                              /* XXX update this to new checksum var idiom! */
++                              F_SUM(f) = pool_alloc(pool, MD4_SUM_LENGTH,
 +                                                    "fattr_find");
-+                              file_checksum(fname, f->u.sum, f->length);
++                              file_checksum(fname, F_SUM(f), f->length);
 +                      }
-+                      diff = u_memcmp(fmid->u.sum, f->u.sum, checksum_len);
++                      diff = u_memcmp(F_SUM(fmid), F_SUM(f), checksum_len);
 +                      if (diff) {
 +                              if (diff < 0)
 +                                      low = mid + 1;
@@ -273,7 +274,7 @@ TODO:
   */
  static enum delret delete_item(char *fbuf, int mode, char *replace, int flags)
  {
-@@ -147,6 +260,8 @@ static enum delret delete_item(char *fbu
+@@ -149,6 +263,8 @@ static enum delret delete_item(char *fbu
                        goto check_ret;
                /* OK: try to delete the directory. */
        }
@@ -282,7 +283,7 @@ TODO:
  
        if (!replace && max_delete >= 0 && ++deletion_count > max_delete)
                return DR_AT_LIMIT;
-@@ -193,6 +308,8 @@ static enum delret delete_item(char *fbu
+@@ -195,6 +311,8 @@ static enum delret delete_item(char *fbu
   * its contents, otherwise just checks for content.  Returns DR_SUCCESS or
   * DR_NOT_EMPTY.  Note that fname must point to a MAXPATHLEN buffer!  (The
   * buffer is used for recursion, but returned unchanged.)
@@ -291,7 +292,7 @@ TODO:
   */
  static enum delret delete_dir_contents(char *fname, int flags)
  {
-@@ -249,6 +366,8 @@ static enum delret delete_dir_contents(c
+@@ -251,6 +369,8 @@ static enum delret delete_dir_contents(c
                if (S_ISDIR(fp->mode)
                 && delete_dir_contents(fname, flags | DEL_RECURSE) != DR_SUCCESS)
                        ret = DR_NOT_EMPTY;
@@ -300,7 +301,7 @@ TODO:
                if (delete_item(fname, fp->mode, NULL, flags) != DR_SUCCESS)
                        ret = DR_NOT_EMPTY;
        }
-@@ -333,15 +452,19 @@ static void delayed_deletions(char *delb
+@@ -335,15 +455,19 @@ static void delayed_deletions(char *delb
   * all the --delete-WHEN options.  Note that the fbuf pointer must point to a
   * MAXPATHLEN buffer with the name of the directory in it (the functions we
   * call will append names onto the end, but the old dir value will be restored
@@ -323,7 +324,7 @@ TODO:
        int dlen, i;
  
        if (!flist) {
-@@ -355,6 +478,8 @@ static void delete_in_dir(struct file_li
+@@ -357,6 +481,8 @@ static void delete_in_dir(struct file_li
        if (verbose > 2)
                rprintf(FINFO, "delete_in_dir(%s)\n", fbuf);
  
@@ -332,7 +333,7 @@ TODO:
        if (allowed_lull)
                maybe_send_keepalive();
  
-@@ -362,12 +487,14 @@ static void delete_in_dir(struct file_li
+@@ -364,12 +490,14 @@ static void delete_in_dir(struct file_li
                return; /* Impossible... */
  
        if (io_error && !(lp_ignore_errors(module_id) || ignore_errors)) {
@@ -352,7 +353,7 @@ TODO:
        }
  
        while (cur_depth >= file->dir.depth && cur_depth >= min_depth)
-@@ -378,6 +505,9 @@ static void delete_in_dir(struct file_li
+@@ -380,6 +508,9 @@ static void delete_in_dir(struct file_li
        dlen = strlen(fbuf);
        filt_array[cur_depth] = push_local_filters(fbuf, dlen);
  
@@ -362,7 +363,7 @@ TODO:
        if (one_file_system) {
                if (file->flags & FLAG_TOP_DIR)
                        filesystem_dev = stp->st_dev;
-@@ -387,6 +517,11 @@ static void delete_in_dir(struct file_li
+@@ -389,6 +520,11 @@ static void delete_in_dir(struct file_li
  
        dirlist = get_dirlist(fbuf, dlen, 0);
  
@@ -374,7 +375,7 @@ TODO:
        /* If an item in dirlist is not found in flist, delete it
         * from the filesystem. */
        for (i = dirlist->count; i--; ) {
-@@ -399,15 +534,22 @@ static void delete_in_dir(struct file_li
+@@ -401,15 +537,22 @@ static void delete_in_dir(struct file_li
                                        f_name(fp, NULL));
                        continue;
                }
@@ -400,7 +401,7 @@ TODO:
        flist_free(dirlist);
  }
  
-@@ -437,9 +579,9 @@ static void do_delete_pass(struct file_l
+@@ -439,9 +582,9 @@ static void do_delete_pass(struct file_l
                 || !S_ISDIR(st.st_mode))
                        continue;
  
@@ -412,7 +413,7 @@ TODO:
  
        if (do_progress && !am_server)
                rprintf(FINFO, "                    \r");
-@@ -968,6 +1110,7 @@ static int try_dests_non(struct file_str
+@@ -966,6 +1109,7 @@ static int try_dests_non(struct file_str
        return j;
  }
  
@@ -420,13 +421,13 @@ TODO:
  static int phase = 0;
  
  /* Acts on the_file_list->file's ndx'th item, whose name is fname.  If a dir,
-@@ -1154,8 +1297,12 @@ static void recv_generator(char *fname, 
+@@ -1152,8 +1296,12 @@ static void recv_generator(char *fname, 
                if (real_ret != 0 && one_file_system)
                        real_st.st_dev = filesystem_dev;
                if (delete_during && f_out != -1 && !phase && dry_run < 2
--                  && (file->flags & FLAG_DEL_HERE))
+-                  && (file->flags & FLAG_XFER_DIR))
 -                      delete_in_dir(the_file_list, fname, file, &real_st);
-+                  && (file->flags & FLAG_DEL_HERE)) {
++                  && (file->flags & FLAG_XFER_DIR)) {
 +                      if (detect_renamed && real_ret != 0)
 +                              unexplored_dirs++;
 +                      delete_in_dir(the_file_list, fname, file, &real_st,
@@ -435,7 +436,7 @@ TODO:
                return;
        }
  
-@@ -1407,8 +1554,14 @@ static void recv_generator(char *fname, 
+@@ -1406,8 +1554,14 @@ static void recv_generator(char *fname, 
                    && hard_link_check(file, ndx, fname, statret, &st,
                                       itemizing, code, HL_SKIP))
                        return;
@@ -451,7 +452,7 @@ TODO:
                rsyserr(FERROR, stat_errno, "recv_generator: failed to stat %s",
                        full_fname(fname));
                return;
-@@ -1594,13 +1747,19 @@ void generate_files(int f_out, struct fi
+@@ -1593,13 +1747,19 @@ void generate_files(int f_out, struct fi
                        (long)getpid(), flist->count);
        }
  
@@ -472,7 +473,7 @@ TODO:
                whole_file = 0;
        if (verbose >= 2) {
                rprintf(FINFO, "delta-transmission %s\n",
-@@ -1655,7 +1814,23 @@ void generate_files(int f_out, struct fi
+@@ -1654,7 +1814,23 @@ void generate_files(int f_out, struct fi
        }
        recv_generator(NULL, NULL, 0, 0, 0, code, -1);
        if (delete_during)
@@ -507,7 +508,7 @@ TODO:
  int numeric_ids = 0;
  int allow_8bit_chars = 0;
  int force_delete = 0;
-@@ -347,6 +348,7 @@ void usage(enum logcode F)
+@@ -343,6 +344,7 @@ void usage(enum logcode F)
    rprintf(F,"     --modify-window=NUM     compare mod-times with reduced accuracy\n");
    rprintf(F," -T, --temp-dir=DIR          create temporary files in directory DIR\n");
    rprintf(F," -y, --fuzzy                 find similar file for basis if no dest file\n");
@@ -515,7 +516,7 @@ TODO:
    rprintf(F,"     --compare-dest=DIR      also compare destination files relative to DIR\n");
    rprintf(F,"     --copy-dest=DIR         ... and include copies of unchanged files\n");
    rprintf(F,"     --link-dest=DIR         hardlink to files in DIR when unchanged\n");
-@@ -501,6 +503,7 @@ static struct poptOption long_options[] 
+@@ -497,6 +499,7 @@ static struct poptOption long_options[] 
    {"compare-dest",     0,  POPT_ARG_STRING, 0, OPT_COMPARE_DEST, 0, 0 },
    {"copy-dest",        0,  POPT_ARG_STRING, 0, OPT_COPY_DEST, 0, 0 },
    {"link-dest",        0,  POPT_ARG_STRING, 0, OPT_LINK_DEST, 0, 0 },
@@ -523,7 +524,7 @@ TODO:
    {"fuzzy",           'y', POPT_ARG_NONE,   &fuzzy_basis, 0, 0, 0 },
    {"compress",        'z', POPT_ARG_NONE,   0, 'z', 0, 0 },
    {"compress-level",   0,  POPT_ARG_INT,    &def_compress_level, 'z', 0, 0 },
-@@ -1360,7 +1363,7 @@ int parse_arguments(int *argc, const cha
+@@ -1361,7 +1364,7 @@ int parse_arguments(int *argc, const cha
                inplace = 1;
        }
  
@@ -532,7 +533,7 @@ TODO:
                partial_dir = tmp_partialdir;
  
        if (inplace) {
-@@ -1369,6 +1372,7 @@ int parse_arguments(int *argc, const cha
+@@ -1370,6 +1373,7 @@ int parse_arguments(int *argc, const cha
                        snprintf(err_buf, sizeof err_buf,
                                 "--%s cannot be used with --%s\n",
                                 append_mode ? "append" : "inplace",
@@ -540,7 +541,7 @@ TODO:
                                 delay_updates ? "delay-updates" : "partial-dir");
                        return 0;
                }
-@@ -1679,6 +1683,8 @@ void server_options(char **args,int *arg
+@@ -1680,6 +1684,8 @@ void server_options(char **args,int *arg
                        args[ac++] = "--super";
                if (size_only)
                        args[ac++] = "--size-only";
index 948b1ed..a819d2f 100644 (file)
@@ -24,17 +24,16 @@ To use this patch, run these commands for a successful build:
  extern int module_id;
  extern int ignore_errors;
  extern int numeric_ids;
-@@ -697,6 +698,16 @@ static struct file_struct *receive_file_
-                       sum = empty_sum;
+@@ -723,6 +724,15 @@ static struct file_struct *recv_file_ent
+                       bp = tmp_sum;
                }
-               read_buf(f, sum, checksum_len);
-+              if (pre_checksum) {
-+                      char sum2[MD4_SUM_LENGTH];
+               read_buf(f, bp, checksum_len);
++              if (pre_checksum && sum_len) {
 +                      STRUCT_STAT st;
 +                      char *fname = f_name(file, NULL);
 +                      if (stat(fname, &st) == 0 && st.st_size == file_length) {
-+                              file_checksum(fname, sum2, st.st_size);
-+                              if (memcmp(sum, sum2, checksum_len) != 0)
++                              file_checksum(fname, tmp_sum, st.st_size);
++                              if (memcmp(bp, tmp_sum, checksum_len) != 0)
 +                                      file->flags |= FLAG_SUM_DIFFERS;
 +                      }
 +              }
@@ -43,7 +42,7 @@ To use this patch, run these commands for a successful build:
        return file;
 --- old/generator.c
 +++ new/generator.c
-@@ -70,6 +70,7 @@ extern int ignore_timeout;
+@@ -71,6 +71,7 @@ extern int ignore_timeout;
  extern int protocol_version;
  extern int fuzzy_basis;
  extern int always_checksum;
@@ -51,7 +50,7 @@ To use this patch, run these commands for a successful build:
  extern int checksum_len;
  extern char *partial_dir;
  extern char *basis_dir[];
-@@ -376,7 +377,8 @@ void itemize(struct file_struct *file, i
+@@ -507,7 +508,8 @@ void itemize(struct file_struct *file, i
  
  
  /* Perform our quick-check heuristic for determining if a file is unchanged. */
@@ -61,16 +60,16 @@ To use this patch, run these commands for a successful build:
  {
        if (st->st_size != file->length)
                return 0;
-@@ -385,6 +387,8 @@ int unchanged_file(char *fn, struct file
+@@ -516,6 +518,8 @@ int unchanged_file(char *fn, struct file
           of the file time to determine whether to sync */
        if (always_checksum && S_ISREG(st->st_mode)) {
                char sum[MD4_SUM_LENGTH];
 +              if (pre_checksum && fnamecmp_type == FNAMECMP_FNAME)
 +                      return !(file->flags & FLAG_SUM_DIFFERS);
                file_checksum(fn, sum, st->st_size);
-               return memcmp(sum, file->u.sum, checksum_len) == 0;
+               return memcmp(sum, F_SUM(file), checksum_len) == 0;
        }
-@@ -622,7 +626,7 @@ static int try_dests_reg(struct file_str
+@@ -752,7 +756,7 @@ static int try_dests_reg(struct file_str
                        match_level = 1;
                        /* FALL THROUGH */
                case 1:
@@ -79,7 +78,7 @@ To use this patch, run these commands for a successful build:
                                continue;
                        best_match = j;
                        match_level = 2;
-@@ -1215,7 +1219,7 @@ static void recv_generator(char *fname, 
+@@ -1420,7 +1424,7 @@ static void recv_generator(char *fname, 
                ;
        else if (fnamecmp_type == FNAMECMP_FUZZY)
                ;
@@ -90,7 +89,7 @@ To use this patch, run these commands for a successful build:
                        handle_partial_dir(partialptr, PDIR_DELETE);
 --- old/hlink.c
 +++ new/hlink.c
-@@ -224,7 +224,7 @@ int hard_link_check(struct file_struct *
+@@ -235,7 +235,7 @@ int hard_link_check(struct file_struct *
                                                }
                                                break;
                                        }
@@ -119,7 +118,7 @@ To use this patch, run these commands for a successful build:
  int local_server = 0;
  int new_root_dir = 0;
  mode_t orig_umask = 0;
-@@ -784,6 +788,7 @@ static void do_server_recv(int f_in, int
+@@ -785,6 +789,7 @@ static void do_server_recv(int f_in, int
        struct file_list *flist;
        char *local_name = NULL;
        char *dir = NULL;
@@ -127,7 +126,7 @@ To use this patch, run these commands for a successful build:
        int save_verbose = verbose;
  
        if (filesfrom_fd >= 0) {
-@@ -827,6 +832,10 @@ static void do_server_recv(int f_in, int
+@@ -828,6 +833,10 @@ static void do_server_recv(int f_in, int
                filesfrom_fd = -1;
        }
  
@@ -138,7 +137,7 @@ To use this patch, run these commands for a successful build:
        flist = recv_file_list(f_in);
        verbose = save_verbose;
        if (!flist) {
-@@ -835,6 +844,9 @@ static void do_server_recv(int f_in, int
+@@ -836,6 +845,9 @@ static void do_server_recv(int f_in, int
        }
        the_file_list = flist;
  
@@ -148,7 +147,7 @@ To use this patch, run these commands for a successful build:
        if (argc > 0)
                local_name = get_local_name(flist,argv[0]);
  
-@@ -916,6 +928,7 @@ int client_run(int f_in, int f_out, pid_
+@@ -917,6 +929,7 @@ int client_run(int f_in, int f_out, pid_
  {
        struct file_list *flist = NULL;
        int exit_code = 0, exit_code2 = 0;
@@ -156,7 +155,7 @@ To use this patch, run these commands for a successful build:
        char *local_name = NULL;
  
        cleanup_child_pid = pid;
-@@ -990,11 +1003,18 @@ int client_run(int f_in, int f_out, pid_
+@@ -991,11 +1004,18 @@ int client_run(int f_in, int f_out, pid_
                filesfrom_fd = -1;
        }
  
@@ -177,11 +176,11 @@ To use this patch, run these commands for a successful build:
  
 --- old/rsync.h
 +++ new/rsync.h
-@@ -65,6 +65,7 @@
- #define FLAG_HLINK_TOL (1<<4) /* receiver/generator */
- #define FLAG_NO_FUZZY (1<<5)  /* generator */
- #define FLAG_MISSING (1<<6)   /* generator */
-+#define FLAG_SUM_DIFFERS (1<<7)       /* receiver/generator */
/* update this if you make incompatible changes */
- #define PROTOCOL_VERSION 29
+@@ -61,6 +61,7 @@
+ #define FLAG_SENT (1<<1)      /* sender/generator */
+ #define FLAG_XFER_DIR (1<<2)  /* sender/receiver/generator */
+ #define FLAG_MOUNT_DIR (1<<3) /* sender/generator */
++#define FLAG_SUM_DIFFERS (1<<3)       /* receiver/generator (non-dirs) */
+ #define FLAG_MISSING_DIR (1<<4)       /* generator (dirs only) */
#define FLAG_HLINK_INFO (1<<5)        /* receiver/generator */
+ #define FLAG_HLINK_FIRST (1<<6)       /* receiver/generator */
index fe98e42..34bec5a 100644 (file)
@@ -19,7 +19,7 @@ above:
 
 --- old/backup.c
 +++ new/backup.c
-@@ -129,7 +129,7 @@ static int make_bak_dir(char *fullpath)
+@@ -130,7 +130,7 @@ static int make_bak_dir(char *fullpath)
                if (p >= rel) {
                        /* Try to transfer the directory settings of the
                         * actual dir that the files are coming from. */
@@ -28,7 +28,7 @@ above:
                                rsyserr(FERROR, errno,
                                        "make_bak_dir stat %s failed",
                                        full_fname(rel));
-@@ -200,7 +200,7 @@ static int keep_backup(char *fname)
+@@ -201,7 +201,7 @@ static int keep_backup(const char *fname
        int ret_code;
  
        /* return if no file to keep */
@@ -53,7 +53,7 @@ above:
  
 --- old/flist.c
 +++ new/flist.c
-@@ -181,7 +181,7 @@ static int readlink_stat(const char *pat
+@@ -191,7 +191,7 @@ static int readlink_stat(const char *pat
        }
        return 0;
  #else
@@ -62,7 +62,7 @@ above:
  #endif
  }
  
-@@ -189,17 +189,17 @@ int link_stat(const char *path, STRUCT_S
+@@ -199,17 +199,17 @@ int link_stat(const char *path, STRUCT_S
  {
  #ifdef SUPPORT_LINKS
        if (copy_links)
@@ -84,7 +84,7 @@ above:
  #endif
  }
  
-@@ -234,26 +234,6 @@ static int is_excluded(char *fname, int 
+@@ -244,26 +244,6 @@ static int is_excluded(char *fname, int 
        return 0;
  }
  
@@ -111,7 +111,7 @@ above:
  static void send_directory(int f, struct file_list *flist,
                           char *fbuf, int len);
  
-@@ -793,7 +773,7 @@ struct file_struct *make_file(char *fnam
+@@ -803,7 +783,7 @@ struct file_struct *make_file(const char
                if (save_errno == ENOENT) {
  #ifdef SUPPORT_LINKS
                        /* Avoid "vanished" error if symlink points nowhere. */
@@ -120,7 +120,7 @@ above:
                            && S_ISLNK(st.st_mode)) {
                                io_error |= IOERR_GENERAL;
                                rprintf(FERROR, "symlink has no referent: %s\n",
-@@ -963,7 +943,7 @@ struct file_struct *make_file(char *fnam
+@@ -962,7 +942,7 @@ struct file_struct *make_file(const char
                int save_mode = file->mode;
                file->mode = S_IFDIR; /* Find a directory with our name. */
                if (flist_find(the_file_list, file) >= 0
@@ -183,7 +183,7 @@ above:
  int am_server = 0;
  int am_sender = 0;
  int am_generator = 0;
-@@ -329,6 +329,9 @@ void usage(enum logcode F)
+@@ -326,6 +326,9 @@ void usage(enum logcode F)
    rprintf(F," -t, --times                 preserve times\n");
    rprintf(F," -O, --omit-dir-times        omit directories when preserving times\n");
    rprintf(F,"     --super                 receiver attempts super-user activities\n");
@@ -193,7 +193,7 @@ above:
    rprintf(F," -S, --sparse                handle sparse files efficiently\n");
    rprintf(F," -n, --dry-run               show what would have been transferred\n");
    rprintf(F," -W, --whole-file            copy files whole (without rsync algorithm)\n");
-@@ -453,6 +456,7 @@ static struct poptOption long_options[] 
+@@ -451,6 +454,7 @@ static struct poptOption long_options[] 
    {"modify-window",    0,  POPT_ARG_INT,    &modify_window, OPT_MODIFY_WINDOW, 0, 0 },
    {"super",            0,  POPT_ARG_VAL,    &am_root, 2, 0, 0 },
    {"no-super",         0,  POPT_ARG_VAL,    &am_root, 0, 0, 0 },
@@ -201,7 +201,7 @@ above:
    {"owner",           'o', POPT_ARG_VAL,    &preserve_uid, 1, 0, 0 },
    {"no-owner",         0,  POPT_ARG_VAL,    &preserve_uid, 0, 0, 0 },
    {"no-o",             0,  POPT_ARG_VAL,    &preserve_uid, 0, 0, 0 },
-@@ -1178,6 +1182,14 @@ int parse_arguments(int *argc, const cha
+@@ -1177,6 +1181,14 @@ int parse_arguments(int *argc, const cha
        }
  #endif
  
@@ -218,18 +218,18 @@ above:
                        "--write-batch and --read-batch can not be used together\n");
 --- old/rsync.c
 +++ new/rsync.c
-@@ -196,7 +196,9 @@ int set_file_attrs(char *fname, struct f
-                                       (long)sxp->st.st_gid, (long)file->gid);
+@@ -249,7 +249,9 @@ int set_file_attrs(char *fname, struct f
+                                       (long)sxp->st.st_gid, (long)F_GID(file));
                        }
                }
 -              if (do_lchown(fname,
 +              if (am_root < 0) {
 +                      ;
 +              } else if (do_lchown(fname,
-                   change_uid ? file->uid : sxp->st.st_uid,
-                   change_gid ? file->gid : sxp->st.st_gid) != 0) {
+                   change_uid ? F_UID(file) : sxp->st.st_uid,
+                   change_gid ? F_GID(file) : sxp->st.st_gid) != 0) {
                        /* shouldn't have attempted to change uid or gid
-@@ -205,7 +207,7 @@ int set_file_attrs(char *fname, struct f
+@@ -258,7 +260,7 @@ int set_file_attrs(char *fname, struct f
                            change_uid ? "chown" : "chgrp",
                            full_fname(fname));
                        goto cleanup;
@@ -238,7 +238,7 @@ above:
                /* a lchown had been done - we have to re-stat if the
                 * destination had the setuid or setgid bits set due
                 * to the side effect of the chown call */
-@@ -222,6 +224,8 @@ int set_file_attrs(char *fname, struct f
+@@ -275,6 +277,8 @@ int set_file_attrs(char *fname, struct f
  #ifdef SUPPORT_XATTRS
        if (preserve_xattrs && set_xattr(fname, file, sxp) == 0)
                updated = 1;
@@ -247,7 +247,7 @@ above:
  #endif
  #ifdef SUPPORT_ACLS
        /* It's OK to call set_acl() now, even for a dir, as the generator
-@@ -236,7 +240,7 @@ int set_file_attrs(char *fname, struct f
+@@ -289,7 +293,7 @@ int set_file_attrs(char *fname, struct f
  
  #ifdef HAVE_CHMOD
        if ((sxp->st.st_mode & CHMOD_BITS) != (new_mode & CHMOD_BITS)) {
@@ -258,7 +258,7 @@ above:
                                "failed to set permissions on %s",
 --- old/rsync.h
 +++ new/rsync.h
-@@ -704,6 +704,12 @@ typedef struct {
+@@ -726,6 +726,12 @@ typedef struct {
  
  #include "proto.h"
  
@@ -271,7 +271,7 @@ above:
  /* We have replacement versions of these if they're missing. */
  #ifndef HAVE_ASPRINTF
  int asprintf(char **ptr, const char *format, ...);
-@@ -922,6 +928,26 @@ int inet_pton(int af, const char *src, v
+@@ -944,6 +950,26 @@ int inet_pton(int af, const char *src, v
  const char *get_panic_action(void);
  #endif
  
@@ -308,7 +308,7 @@ above:
   -S, --sparse                handle sparse files efficiently
   -n, --dry-run               show what would have been transferred
   -W, --whole-file            copy files whole (without rsync algorithm)
-@@ -846,7 +847,7 @@ permission value can be applied to the f
+@@ -847,7 +848,7 @@ permission value can be applied to the f
  dit(bf(-o, --owner)) This option causes rsync to set the owner of the
  destination file to be the same as the source file, but only if the
  receiving rsync is being run as the super-user (see also the bf(--super)
@@ -317,7 +317,7 @@ above:
  Without this option, the owner is set to the invoking user on the
  receiving side.
  
-@@ -869,7 +870,7 @@ default, but may fall back to using the 
+@@ -870,7 +871,7 @@ default, but may fall back to using the 
  dit(bf(--devices)) This option causes rsync to transfer character and
  block device files to the remote system to recreate these devices.
  This option has no effect if the receiving rsync is not run as the
@@ -326,7 +326,7 @@ above:
  
  dit(bf(--specials)) This option causes rsync to transfer special files
  such as named sockets and fifos.
-@@ -899,6 +900,33 @@ also for ensuring that you will get erro
+@@ -900,6 +901,33 @@ also for ensuring that you will get erro
  being running as the super-user.  To turn off super-user activities, the
  super-user can use bf(--no-super).
  
@@ -384,7 +384,7 @@ above:
  extern int read_only;
  extern int list_only;
  extern int preserve_perms;
-@@ -79,6 +80,15 @@ int do_mknod(char *pathname, mode_t mode
+@@ -79,6 +80,15 @@ int do_mknod(const char *pathname, mode_
  {
        if (dry_run) return 0;
        RETURN_ERROR_IF_RO_OR_LO;
@@ -437,7 +437,17 @@ above:
  int preserve_perms = 0;
 --- old/xattr.c
 +++ new/xattr.c
-@@ -43,11 +43,16 @@ extern unsigned int file_struct_len;
+@@ -30,6 +30,9 @@ extern int am_root;
+ extern int read_only;
+ extern int list_only;
+ extern int preserve_xattrs;
++extern int preserve_uid;
++extern int preserve_gid;
++extern int flist_extra_ndx;
+ extern unsigned int file_struct_len;
+ #define RSYNC_XAL_INITIAL 5
+@@ -44,11 +47,16 @@ extern unsigned int file_struct_len;
  #define SPRE_LEN ((int)sizeof SYSTEM_PREFIX - 1)
  
  #ifdef HAVE_LINUX_XATTRS
@@ -456,7 +466,7 @@ above:
  
  typedef struct {
        char *datum, *name;
-@@ -148,6 +153,10 @@ static int rsync_xal_get(const char *fna
+@@ -149,6 +157,10 @@ static int rsync_xal_get(const char *fna
                        continue;
  #endif
  
@@ -467,7 +477,7 @@ above:
                datum_len = sys_lgetxattr(fname, name, NULL, 0);
                if (datum_len < 0) {
                        if (errno == ENOTSUP)
-@@ -177,6 +186,13 @@ static int rsync_xal_get(const char *fna
+@@ -178,6 +190,13 @@ static int rsync_xal_get(const char *fna
                                return -1;
                        }
                }
@@ -481,7 +491,7 @@ above:
                rxas = EXPAND_ITEM_LIST(xalp, rsync_xa, RSYNC_XAL_INITIAL);
                rxas->name = ptr + datum_len;
                rxas->datum = ptr;
-@@ -298,13 +314,9 @@ void receive_xattr(struct file_struct *f
+@@ -298,13 +317,9 @@ void receive_xattr(struct file_struct *f
                        rsync_xa *rxa;
                        size_t name_len = read_int(f);
                        size_t datum_len = read_int(f);
@@ -496,7 +506,7 @@ above:
                        if (name_len + datum_len + extra_len < name_len)
                                out_of_memory("receive_xattr"); /* overflow */
                        ptr = new_array(char, name_len + datum_len + extra_len);
-@@ -315,9 +327,14 @@ void receive_xattr(struct file_struct *f
+@@ -315,9 +330,14 @@ void receive_xattr(struct file_struct *f
                        read_buf(f, ptr, datum_len);
  #ifdef HAVE_LINUX_XATTRS
                        /* Non-root can only save the user namespace. */
@@ -514,7 +524,7 @@ above:
                        }
  #else
                        /* This OS only has a user namespace, so we either
-@@ -335,6 +352,12 @@ void receive_xattr(struct file_struct *f
+@@ -335,6 +355,12 @@ void receive_xattr(struct file_struct *f
                                continue;
                        }
  #endif
@@ -527,7 +537,7 @@ above:
                        rxa = EXPAND_ITEM_LIST(&temp_xattr, rsync_xa, count);
                        rxa->name = name;
                        rxa->datum = ptr;
-@@ -414,4 +437,149 @@ int set_xattr(const char *fname, const s
+@@ -412,4 +438,149 @@ int set_xattr(const char *fname, const s
        return rsync_xal_set(fname, lst + ndx); /* TODO:  This needs to return 1 if no xattrs changed! */
  }
  
@@ -608,7 +618,7 @@ above:
 +      fmode = file->mode & (_S_IFMT | CHMOD_BITS);
 +
 +      if (IS_DEVICE(fmode) || IS_SPECIAL(fmode))
-+              rdev = file->u.rdev;
++              rdev = MAKEDEV(F_DMAJOR(file), F_DMINOR(file));
 +      else
 +              rdev = 0;
 +
@@ -621,7 +631,7 @@ above:
 +              fst.st_rdev = 0; /* just in case */
 +
 +      if (mode == fmode && fst.st_rdev == rdev
-+       && fst.st_uid == file->uid && fst.st_gid == file->gid) {
++       && fst.st_uid == F_UID(file) && fst.st_gid == F_GID(file)) {
 +              /* xst.st_mode will be 0 if there's no current stat xattr */
 +              if (xst.st_mode && sys_lremovexattr(fname, XSTAT_ATTR) < 0) {
 +                      rsyserr(FERROR, errno,
@@ -633,12 +643,12 @@ above:
 +      }
 +
 +      if (xst.st_mode != fmode || xst.st_rdev != rdev
-+       || xst.st_uid != file->uid || xst.st_gid != file->gid) {
++       || xst.st_uid != F_UID(file) || xst.st_gid != F_GID(file)) {
 +              char buf[256];
 +              int len = snprintf(buf, sizeof buf, "%o %u,%u %u:%u",
 +                      to_wire_mode(fmode),
 +                      (int)major(rdev), (int)minor(rdev),
-+                      (int)file->uid, (int)file->gid);
++                      (int)F_UID(file), (int)F_GID(file));
 +              if (sys_lsetxattr(fname, XSTAT_ATTR, buf, len) < 0) {
 +                      if (errno == EPERM && S_ISLNK(fst.st_mode))
 +                              return 0;
index 0035017..4a008d0 100644 (file)
@@ -31,7 +31,7 @@ TODO: fix --delete-delay to work with --flags option.
  extern int preserve_uid;
  extern int preserve_gid;
  extern int relative_paths;
-@@ -305,6 +306,9 @@ static void send_file_entry(struct file_
+@@ -313,6 +314,9 @@ static void send_file_entry(struct file_
        unsigned short flags;
        static time_t modtime;
        static mode_t mode;
@@ -41,7 +41,7 @@ TODO: fix --delete-delay to work with --flags option.
        static int64 dev;
        static dev_t rdev;
        static uint32 rdev_major;
-@@ -335,6 +339,12 @@ static void send_file_entry(struct file_
+@@ -343,6 +347,12 @@ static void send_file_entry(struct file_
                flags |= XMIT_SAME_MODE;
        else
                mode = file->mode;
@@ -54,7 +54,7 @@ TODO: fix --delete-delay to work with --flags option.
        if ((preserve_devices && IS_DEVICE(mode))
         || (preserve_specials && IS_SPECIAL(mode))) {
                if (protocol_version < 28) {
-@@ -417,6 +427,10 @@ static void send_file_entry(struct file_
+@@ -429,6 +439,10 @@ static void send_file_entry(struct file_
                write_int(f, modtime);
        if (!(flags & XMIT_SAME_MODE))
                write_int(f, to_wire_mode(mode));
@@ -65,7 +65,7 @@ TODO: fix --delete-delay to work with --flags option.
        if (preserve_uid && !(flags & XMIT_SAME_UID)) {
                if (!numeric_ids)
                        add_uid(uid);
-@@ -484,6 +498,9 @@ static struct file_struct *receive_file_
+@@ -497,6 +511,9 @@ static struct file_struct *recv_file_ent
  {
        static time_t modtime;
        static mode_t mode;
@@ -75,7 +75,7 @@ TODO: fix --delete-delay to work with --flags option.
        static int64 dev;
        static dev_t rdev;
        static uint32 rdev_major;
-@@ -557,9 +574,12 @@ static struct file_struct *receive_file_
+@@ -571,9 +588,12 @@ static struct file_struct *recv_file_ent
                modtime = (time_t)read_int(f);
        if (!(flags & XMIT_SAME_MODE))
                mode = from_wire_mode(read_int(f));
@@ -89,29 +89,31 @@ TODO: fix --delete-delay to work with --flags option.
  
        if (preserve_uid && !(flags & XMIT_SAME_UID))
                uid = (uid_t)read_int(f);
-@@ -610,6 +630,9 @@ static struct file_struct *receive_file_
+@@ -639,6 +659,10 @@ static struct file_struct *recv_file_ent
        file->modtime = modtime;
        file->length = file_length;
        file->mode = mode;
 +#ifdef SUPPORT_FLAGS
-+      file->fileflags = fileflags;
++      if (preserve_fileflags)
++              F_FFLAGS(file) = fileflags;
 +#endif
-       file->uid = uid;
-       file->gid = gid;
-@@ -870,6 +893,9 @@ struct file_struct *make_file(const char
+       if (preserve_uid)
+               F_UID(file) = uid;
+       if (preserve_gid)
+@@ -902,6 +926,10 @@ struct file_struct *make_file(const char
        file->modtime = st.st_mtime;
        file->length = st.st_size;
        file->mode = st.st_mode;
 +#ifdef SUPPORT_FLAGS
-+      file->fileflags = st.st_flags;
++      if (preserve_fileflags)
++              F_FFLAGS(file) = st.st_flags;
 +#endif
-       file->uid = st.st_uid;
-       file->gid = st.st_gid;
+       if (preserve_uid)
+               F_UID(file) = st.st_uid;
+       if (preserve_gid)
 --- old/generator.c
 +++ new/generator.c
-@@ -99,6 +99,12 @@ int non_perishable_cnt = 0;
+@@ -101,6 +101,12 @@ int non_perishable_cnt = 0;
  static int deletion_count = 0; /* used to implement --max-delete */
  static FILE *delete_delay_fp = NULL;
  
@@ -124,7 +126,7 @@ TODO: fix --delete-delay to work with --flags option.
  /* For calling delete_item() and delete_dir_contents(). */
  #define DEL_RECURSE           (1<<1) /* recurse */
  #define DEL_DIR_IS_EMPTY      (1<<2) /* internal delete_FUNCTIONS use only */
-@@ -114,7 +120,6 @@ enum delret {
+@@ -116,7 +122,6 @@ enum delret {
  /* Forward declaration for delete_item(). */
  static enum delret delete_dir_contents(char *fname, int flags);
  
@@ -132,7 +134,7 @@ TODO: fix --delete-delay to work with --flags option.
  static int is_backup_file(char *fn)
  {
        int k = strlen(fn) - backup_suffix_len;
-@@ -127,17 +132,20 @@ static int is_backup_file(char *fn)
+@@ -129,17 +134,20 @@ static int is_backup_file(char *fn)
   * Note that fbuf must point to a MAXPATHLEN buffer if the mode indicates it's
   * a directory! (The buffer is used for recursion, but returned unchanged.)
   */
@@ -156,7 +158,7 @@ TODO: fix --delete-delay to work with --flags option.
        if (S_ISDIR(mode) && !(flags & DEL_DIR_IS_EMPTY)) {
                ignore_perishable = 1;
                /* If DEL_RECURSE is not set, this just reports emptiness. */
-@@ -249,7 +257,7 @@ static enum delret delete_dir_contents(c
+@@ -251,7 +259,7 @@ static enum delret delete_dir_contents(c
                if (S_ISDIR(fp->mode)
                 && delete_dir_contents(fname, flags | DEL_RECURSE) != DR_SUCCESS)
                        ret = DR_NOT_EMPTY;
@@ -165,7 +167,7 @@ TODO: fix --delete-delay to work with --flags option.
                        ret = DR_NOT_EMPTY;
        }
  
-@@ -401,10 +409,10 @@ static void delete_in_dir(struct file_li
+@@ -403,10 +411,10 @@ static void delete_in_dir(struct file_li
                }
                if (flist_find(flist, fp) < 0) {
                        f_name(fp, delbuf);
@@ -178,7 +180,7 @@ TODO: fix --delete-delay to work with --flags option.
                }
        }
  
-@@ -1103,7 +1111,7 @@ static void recv_generator(char *fname, 
+@@ -1101,7 +1109,7 @@ static void recv_generator(char *fname, 
                 * we need to delete it.  If it doesn't exist, then
                 * (perhaps recursively) create it. */
                if (statret == 0 && !S_ISDIR(st.st_mode)) {
@@ -187,7 +189,7 @@ TODO: fix --delete-delay to work with --flags option.
                                return;
                        statret = -1;
                }
-@@ -1197,7 +1205,7 @@ static void recv_generator(char *fname, 
+@@ -1195,7 +1203,7 @@ static void recv_generator(char *fname, 
                        }
                        /* Not the right symlink (or not a symlink), so
                         * delete it. */
@@ -196,7 +198,7 @@ TODO: fix --delete-delay to work with --flags option.
                                return;
                } else if (basis_dir[0] != NULL) {
                        int j = try_dests_non(file, fname, ndx, fnamecmpbuf, &st,
-@@ -1268,7 +1276,7 @@ static void recv_generator(char *fname, 
+@@ -1267,7 +1275,7 @@ static void recv_generator(char *fname, 
                                        goto return_with_success;
                                return;
                        }
@@ -205,7 +207,7 @@ TODO: fix --delete-delay to work with --flags option.
                                return;
                } else if (basis_dir[0] != NULL) {
                        int j = try_dests_non(file, fname, ndx, fnamecmpbuf, &st,
-@@ -1354,7 +1362,7 @@ static void recv_generator(char *fname, 
+@@ -1353,7 +1361,7 @@ static void recv_generator(char *fname, 
        fnamecmp_type = FNAMECMP_FNAME;
  
        if (statret == 0 && !S_ISREG(st.st_mode)) {
@@ -287,7 +289,16 @@ TODO: fix --delete-delay to work with --flags option.
        if (write_batch && read_batch) {
                snprintf(err_buf, sizeof err_buf,
                        "--write-batch and --read-batch can not be used together\n");
-@@ -1580,6 +1598,9 @@ void server_options(char **args,int *arg
+@@ -1223,6 +1241,8 @@ int parse_arguments(int *argc, const cha
+               preserve_uid = flist_extra_ndx++;
+       if (preserve_gid)
+               preserve_gid = flist_extra_ndx++;
++      if (preserve_fileflags)
++              preserve_fileflags = flist_extra_ndx++;
+       *argv = poptGetArgs(pc);
+       *argc = count_args(*argv);
+@@ -1585,6 +1605,9 @@ void server_options(char **args,int *arg
        if (xfer_dirs && !recurse && delete_mode && am_sender)
                args[ac++] = "--no-r";
  
@@ -312,7 +323,7 @@ TODO: fix --delete-delay to work with --flags option.
  extern int preserve_executability;
  extern int preserve_times;
  extern int omit_dir_times;
-@@ -123,6 +126,41 @@ mode_t dest_mode(mode_t flist_mode, mode
+@@ -176,6 +179,41 @@ mode_t dest_mode(mode_t flist_mode, mode
        return new_mode;
  }
  
@@ -354,7 +365,7 @@ TODO: fix --delete-delay to work with --flags option.
  int set_file_attrs(char *fname, struct file_struct *file, STRUCT_STAT *st,
                   int flags)
  {
-@@ -221,6 +259,15 @@ int set_file_attrs(char *fname, struct f
+@@ -274,6 +312,15 @@ int set_file_attrs(char *fname, struct f
        }
  #endif
  
@@ -370,7 +381,7 @@ TODO: fix --delete-delay to work with --flags option.
        if (verbose > 1 && flags & ATTRS_REPORT) {
                if (updated)
                        rprintf(FCLIENT, "%s\n", fname);
-@@ -268,6 +315,9 @@ void finish_transfer(char *fname, char *
+@@ -321,6 +368,9 @@ void finish_transfer(char *fname, char *
        set_file_attrs(fnametmp, file, NULL,
                       ok_to_set_time ? 0 : ATTRS_SKIP_MTIME);
  
@@ -380,7 +391,7 @@ TODO: fix --delete-delay to work with --flags option.
        /* move tmp file over real file */
        if (verbose > 2)
                rprintf(FINFO, "renaming %s to %s\n", fnametmp, fname);
-@@ -282,6 +332,9 @@ void finish_transfer(char *fname, char *
+@@ -335,6 +385,9 @@ void finish_transfer(char *fname, char *
        }
        if (ret == 0) {
                /* The file was moved into place (not copied), so it's done. */
@@ -400,7 +411,7 @@ TODO: fix --delete-delay to work with --flags option.
  
  /* These flags are used in the live flist data. */
  
-@@ -345,6 +346,10 @@ enum msgcode {
+@@ -347,6 +348,10 @@ enum msgcode {
  #define schar char
  #endif
  
@@ -411,16 +422,14 @@ TODO: fix --delete-delay to work with --flags option.
  /* Find a variable that is either exactly 32-bits or longer.
   * If some code depends on 32-bit truncation, it will need to
   * take special action in a "#if SIZEOF_INT32 > 4" section. */
-@@ -528,6 +533,9 @@ struct file_struct {
-               struct hlink *links;
-       } link_u;
-       time_t modtime;
-+#ifdef SUPPORT_FLAGS
-+      uint32 fileflags;
-+#endif
-       uid_t uid;
-       gid_t gid;
-       mode_t mode;
+@@ -540,6 +545,7 @@ union flist_extras {
+ /* When enabled, all entries have these: */
+ #define F_UID(f) FLIST_EXTRA(f, preserve_uid).uid
+ #define F_GID(f) FLIST_EXTRA(f, preserve_gid).gid
++#define F_FFLAGS(f) FLIST_EXTRA(f, preserve_fileflags).num
+ /* These are per-entry optional and mutally exclusive: */
+ #define F_IDEV(f) FLIST_EXTRA(f, flist_extra_ndx).idev
 --- old/rsync.yo
 +++ new/rsync.yo
 @@ -321,6 +321,7 @@ to the detailed description below for a 
index e012c3c..38e2ef1 100644 (file)
@@ -17,22 +17,22 @@ To use this patch, run these commands for a successful build:
  extern int delete_mode;
  extern int delete_before;
  extern int delete_during;
-@@ -348,10 +349,11 @@ void itemize(struct file_struct *file, i
+@@ -479,10 +480,11 @@ void itemize(struct file_struct *file, i
                        iflags |= ITEM_REPORT_TIME;
                if ((file->mode & CHMOD_BITS) != (st->st_mode & CHMOD_BITS))
                        iflags |= ITEM_REPORT_PERMS;
--              if (preserve_uid && am_root && file->uid != st->st_uid)
-+              if (preserve_uid && am_root && file->uid != st->st_uid
+-              if (preserve_uid && am_root && F_UID(file) != st->st_uid)
++              if (preserve_uid && am_root && F_UID(file) != st->st_uid
 +               && !(omit_dir_changes && S_ISDIR(st->st_mode)))
                        iflags |= ITEM_REPORT_OWNER;
--              if (preserve_gid && file->gid != GID_NONE
--                  && st->st_gid != file->gid)
-+              if (preserve_gid && file->gid != GID_NONE && st->st_gid != file->gid
+-              if (preserve_gid && F_GID(file) != GID_NONE
+-                  && st->st_gid != F_GID(file))
++              if (preserve_gid && F_GID(file) != GID_NONE && st->st_gid != F_GID(file)
 +               && !(omit_dir_changes && S_ISDIR(st->st_mode)))
                        iflags |= ITEM_REPORT_GROUP;
        } else
                iflags |= ITEM_IS_NEW;
-@@ -892,7 +894,7 @@ static void recv_generator(char *fname, 
+@@ -1088,7 +1090,7 @@ static void recv_generator(char *fname, 
  
        /* If we're not preserving permissions, change the file-list's
         * mode based on the local permissions and some heuristics. */
@@ -51,7 +51,7 @@ To use this patch, run these commands for a successful build:
  int update_only = 0;
  int cvs_exclude = 0;
  int dry_run = 0;
-@@ -313,6 +314,7 @@ void usage(enum logcode F)
+@@ -309,6 +310,7 @@ void usage(enum logcode F)
    rprintf(F," -D                          same as --devices --specials\n");
    rprintf(F," -t, --times                 preserve times\n");
    rprintf(F," -O, --omit-dir-times        omit directories when preserving times\n");
@@ -59,7 +59,7 @@ To use this patch, run these commands for a successful build:
    rprintf(F,"     --super                 receiver attempts super-user activities\n");
    rprintf(F," -S, --sparse                handle sparse files efficiently\n");
    rprintf(F," -n, --dry-run               show what would have been transferred\n");
-@@ -429,6 +431,7 @@ static struct poptOption long_options[] 
+@@ -426,6 +428,7 @@ static struct poptOption long_options[] 
    {"no-times",         0,  POPT_ARG_VAL,    &preserve_times, 0, 0, 0 },
    {"no-t",             0,  POPT_ARG_VAL,    &preserve_times, 0, 0, 0 },
    {"omit-dir-times",  'O', POPT_ARG_VAL,    &omit_dir_times, 2, 0, 0 },
@@ -67,7 +67,7 @@ To use this patch, run these commands for a successful build:
    {"modify-window",    0,  POPT_ARG_INT,    &modify_window, OPT_MODIFY_WINDOW, 0, 0 },
    {"super",            0,  POPT_ARG_VAL,    &am_root, 2, 0, 0 },
    {"no-super",         0,  POPT_ARG_VAL,    &am_root, 0, 0, 0 },
-@@ -1287,6 +1290,9 @@ int parse_arguments(int *argc, const cha
+@@ -1286,6 +1289,9 @@ int parse_arguments(int *argc, const cha
                        "P *%s", backup_suffix);
                parse_rule(&filter_list, backup_dir_buf, 0, 0);
        }
@@ -77,7 +77,7 @@ To use this patch, run these commands for a successful build:
        if (make_backups && !backup_dir)
                omit_dir_times = 1;
  
-@@ -1515,6 +1521,8 @@ void server_options(char **args,int *arg
+@@ -1519,6 +1525,8 @@ void server_options(char **args,int *arg
                        argstr[x++] = 'm';
                if (omit_dir_times == 2)
                        argstr[x++] = 'O';
@@ -95,7 +95,7 @@ To use this patch, run these commands for a successful build:
 +extern int omit_dir_changes;
  extern int basis_dir_cnt;
  extern int make_backups;
- extern int cleanup_got_literal;
+ extern int flist_extra_ndx;
 @@ -551,7 +552,7 @@ int recv_files(int f_in, struct file_lis
  
                /* If we're not preserving permissions, change the file-list's
@@ -115,16 +115,16 @@ To use this patch, run these commands for a successful build:
  extern int am_root;
  extern int am_server;
  extern int am_sender;
-@@ -162,9 +163,11 @@ int set_file_attrs(char *fname, struct f
+@@ -215,9 +216,11 @@ int set_file_attrs(char *fname, struct f
                        updated = 1;
        }
  
--      change_uid = am_root && preserve_uid && st->st_uid != file->uid;
-+      change_uid = am_root && preserve_uid && st->st_uid != file->uid
+-      change_uid = am_root && preserve_uid && st->st_uid != F_UID(file);
++      change_uid = am_root && preserve_uid && st->st_uid != F_UID(file)
 +              && !(omit_dir_changes && S_ISDIR(st->st_mode));
-       change_gid = preserve_gid && file->gid != GID_NONE
--              && st->st_gid != file->gid;
-+              && st->st_gid != file->gid
+       change_gid = preserve_gid && F_GID(file) != GID_NONE
+-              && st->st_gid != F_GID(file);
++              && st->st_gid != F_GID(file)
 +              && !(omit_dir_changes && S_ISDIR(st->st_mode));
  #if !defined HAVE_LCHOWN && !defined CHOWN_MODIFIES_SYMLINK
        if (S_ISLNK(st->st_mode))
index 6c5c259..57ceac5 100644 (file)
@@ -19,7 +19,7 @@ To use this patch, run these commands for a successful build:
  extern struct file_list *the_file_list;
  
  const char phase_unknown[] = "unknown";
-@@ -147,16 +148,24 @@ static void check_timeout(void)
+@@ -166,16 +167,24 @@ static void check_timeout(void)
  {
        time_t t;
  
@@ -49,15 +49,15 @@ To use this patch, run these commands for a successful build:
                        rprintf(FERROR, "io timeout after %d seconds -- exiting\n",
 --- old/options.c
 +++ new/options.c
-@@ -116,6 +116,7 @@ int checksum_seed = 0;
- int inplace = 0;
- int delay_updates = 0;
- long block_size = 0; /* "long" because popt can't set an int32. */
+@@ -106,6 +106,7 @@ size_t bwlimit_writemax = 0;
+ int ignore_existing = 0;
+ int ignore_non_existing = 0;
+ int need_messages_from_generator = 0;
 +time_t stop_at_utime = 0;
- /** Network address family. **/
-@@ -377,6 +378,8 @@ void usage(enum logcode F)
+ int max_delete = -1;
+ OFF_T max_size = 0;
+ OFF_T min_size = 0;
+@@ -374,6 +375,8 @@ void usage(enum logcode F)
    rprintf(F,"     --password-file=FILE    read password from FILE\n");
    rprintf(F,"     --list-only             list the files instead of copying them\n");
    rprintf(F,"     --bwlimit=KBPS          limit I/O bandwidth; KBytes per second\n");
@@ -66,7 +66,7 @@ To use this patch, run these commands for a successful build:
    rprintf(F,"     --write-batch=FILE      write a batched update to FILE\n");
    rprintf(F,"     --only-write-batch=FILE like --write-batch but w/o updating destination\n");
    rprintf(F,"     --read-batch=FILE       read a batched update from FILE\n");
-@@ -398,7 +401,7 @@ enum {OPT_VERSION = 1000, OPT_DAEMON, OP
+@@ -395,7 +398,7 @@ enum {OPT_VERSION = 1000, OPT_DAEMON, OP
        OPT_FILTER, OPT_COMPARE_DEST, OPT_COPY_DEST, OPT_LINK_DEST, OPT_HELP,
        OPT_INCLUDE, OPT_INCLUDE_FROM, OPT_MODIFY_WINDOW, OPT_MIN_SIZE, OPT_CHMOD,
        OPT_READ_BATCH, OPT_WRITE_BATCH, OPT_ONLY_WRITE_BATCH, OPT_MAX_SIZE,
@@ -75,7 +75,7 @@ To use this patch, run these commands for a successful build:
        OPT_SERVER, OPT_REFUSED_BASE = 9000};
  
  static struct poptOption long_options[] = {
-@@ -516,6 +519,8 @@ static struct poptOption long_options[] 
+@@ -514,6 +517,8 @@ static struct poptOption long_options[] 
    {"log-format",       0,  POPT_ARG_STRING, &stdout_format, 0, 0, 0 }, /* DEPRECATED */
    {"itemize-changes", 'i', POPT_ARG_NONE,   0, 'i', 0, 0 },
    {"bwlimit",          0,  POPT_ARG_INT,    &bwlimit, 0, 0, 0 },
@@ -84,7 +84,7 @@ To use this patch, run these commands for a successful build:
    {"backup",          'b', POPT_ARG_NONE,   &make_backups, 0, 0, 0 },
    {"backup-dir",       0,  POPT_ARG_STRING, &backup_dir, 0, 0, 0 },
    {"suffix",           0,  POPT_ARG_STRING, &backup_suffix, 0, 0, 0 },
-@@ -1089,6 +1094,36 @@ int parse_arguments(int *argc, const cha
+@@ -1087,6 +1092,36 @@ int parse_arguments(int *argc, const cha
                        usage(FINFO);
                        exit_cleanup(0);
  
@@ -121,7 +121,7 @@ To use this patch, run these commands for a successful build:
                default:
                        /* A large opt value means that set_refuse_options()
                         * turned this option off. */
-@@ -1642,6 +1677,15 @@ void server_options(char **args,int *arg
+@@ -1646,6 +1681,15 @@ void server_options(char **args,int *arg
                args[ac++] = arg;
        }
  
@@ -139,7 +139,7 @@ To use this patch, run these commands for a successful build:
                args[ac++] = backup_dir;
 --- old/rsync.yo
 +++ new/rsync.yo
-@@ -394,6 +394,8 @@ to the detailed description below for a 
+@@ -395,6 +395,8 @@ to the detailed description below for a 
       --password-file=FILE    read password from FILE
       --list-only             list the files instead of copying them
       --bwlimit=KBPS          limit I/O bandwidth; KBytes per second
@@ -148,7 +148,7 @@ To use this patch, run these commands for a successful build:
       --write-batch=FILE      write a batched update to FILE
       --only-write-batch=FILE like --write-batch but w/o updating dest
       --read-batch=FILE       read a batched update from FILE
-@@ -1739,6 +1741,19 @@ transfer was too fast, it will wait befo
+@@ -1746,6 +1748,19 @@ transfer was too fast, it will wait befo
  result is an average transfer rate equaling the specified limit. A value
  of zero specifies no limit.
  
index f66f8e0..2bfc713 100644 (file)
@@ -44,60 +44,17 @@ TODO:
  OBJS3=progress.o pipe.o
  DAEMON_OBJ = params.o loadparm.o clientserver.o access.o connection.o authenticate.o
  popt_OBJS=popt/findme.o  popt/popt.o  popt/poptconfig.o \
---- old/acls.c
-+++ new/acls.c
-@@ -30,6 +30,7 @@ extern int read_only;
- extern int list_only;
- extern int orig_umask;
- extern int preserve_acls;
-+extern int preserve_xattrs;
- extern unsigned int file_struct_len;
- /* === ACL structures === */
-@@ -741,6 +742,10 @@ void receive_acl(struct file_struct *fil
-       type = SMB_ACL_TYPE_ACCESS;
-       racl_list = &access_acl_list;
-       ndx_ptr = (char*)file + file_struct_len;
-+#ifdef SUPPORT_XATTRS
-+      if (preserve_xattrs)
-+              ndx_ptr += 4;
-+#endif
-       do {
-               char tag = read_byte(f);
-               int ndx;
-@@ -800,6 +805,10 @@ void cache_acl(struct file_struct *file,
-       racl = sxp->acc_acl;
-       racl_list = &access_acl_list;
-       ndx_ptr = (char*)file + file_struct_len;
-+#ifdef SUPPORT_XATTRS
-+      if (preserve_xattrs)
-+              ndx_ptr += 4;
-+#endif
-       do {
-               if (!racl)
-                       ndx = -1;
-@@ -920,6 +929,10 @@ int set_acl(const char *fname, const str
-       type = SMB_ACL_TYPE_ACCESS;
-       ndx_ptr = (char*)file + file_struct_len;
-+#ifdef SUPPORT_XATTRS
-+      if (preserve_xattrs)
-+              ndx_ptr += 4;
-+#endif
-       do {
-               acl_duo *duo_item;
-               BOOL eq;
 --- old/backup.c
 +++ new/backup.c
-@@ -30,6 +30,7 @@ extern char *backup_dir;
+@@ -24,6 +24,7 @@
+ extern int verbose;
  extern int am_root;
  extern int preserve_acls;
 +extern int preserve_xattrs;
  extern int preserve_devices;
  extern int preserve_specials;
  extern int preserve_links;
-@@ -136,6 +137,9 @@ static int make_bak_dir(char *fullpath)
+@@ -137,6 +138,9 @@ static int make_bak_dir(char *fullpath)
  #ifdef SUPPORT_ACLS
                                sx.acc_acl = sx.def_acl = NULL;
  #endif
@@ -107,7 +64,7 @@ TODO:
                                if (!(file = make_file(rel, NULL, NULL, 0, NO_FILTERS)))
                                        continue;
  #ifdef SUPPORT_ACLS
-@@ -144,6 +148,12 @@ static int make_bak_dir(char *fullpath)
+@@ -145,6 +149,12 @@ static int make_bak_dir(char *fullpath)
                                        cache_acl(file, &sx);
                                }
  #endif
@@ -120,7 +77,7 @@ TODO:
                                set_file_attrs(fullpath, file, NULL, 0);
                                free(file);
                        }
-@@ -195,6 +205,9 @@ static int keep_backup(const char *fname
+@@ -196,6 +206,9 @@ static int keep_backup(const char *fname
  #ifdef SUPPORT_ACLS
        sx.acc_acl = sx.def_acl = NULL;
  #endif
@@ -130,7 +87,7 @@ TODO:
  
        if (!(file = make_file(fname, NULL, NULL, 0, NO_FILTERS)))
                return 1; /* the file could have disappeared */
-@@ -208,6 +221,12 @@ static int keep_backup(const char *fname
+@@ -211,6 +224,12 @@ static int keep_backup(const char *fname
                cache_acl(file, &sx);
        }
  #endif
@@ -196,43 +153,7 @@ TODO:
  extern int preserve_links;
  extern int preserve_hard_links;
  extern int preserve_devices;
-@@ -499,7 +500,7 @@ static struct file_struct *receive_file_
-       char thisname[MAXPATHLEN];
-       unsigned int l1 = 0, l2 = 0;
-       int alloc_len, basename_len, dirname_len, linkname_len, sum_len;
--#ifdef SUPPORT_ACLS
-+#if defined SUPPORT_ACLS || defined SUPPORT_XATTRS
-       int xtra_len;
- #endif
-       OFF_T file_length;
-@@ -611,10 +612,16 @@ static struct file_struct *receive_file_
-               xtra_len = (S_ISDIR(mode) ? 2 : 1) * 4;
-       else
-               xtra_len = 0;
-+#elif defined SUPPORT_XATTRS
-+      xtra_len = 0;
-+#endif
-+#ifdef SUPPORT_XATTRS
-+      if (preserve_xattrs)
-+              xtra_len += 4;
- #endif
-       alloc_len = file_struct_len + dirname_len + basename_len
--#ifdef SUPPORT_ACLS
-+#if defined SUPPORT_ACLS || defined SUPPORT_XATTRS
-                 + xtra_len
- #endif
-                 + linkname_len + sum_len;
-@@ -623,7 +630,7 @@ static struct file_struct *receive_file_
-       file = (struct file_struct *)bp;
-       memset(bp, 0, file_struct_len);
-       bp += file_struct_len;
--#ifdef SUPPORT_ACLS
-+#if defined SUPPORT_ACLS || defined SUPPORT_XATTRS
-       bp += xtra_len;
- #endif
-@@ -724,6 +731,10 @@ static struct file_struct *receive_file_
+@@ -738,6 +739,10 @@ static struct file_struct *recv_file_ent
        if (preserve_acls)
                receive_acl(file, f);
  #endif
@@ -243,7 +164,7 @@ TODO:
  
        return file;
  }
-@@ -982,7 +993,7 @@ static struct file_struct *send_file_nam
+@@ -991,7 +996,7 @@ static struct file_struct *send_file_nam
                                          unsigned short flags)
  {
        struct file_struct *file;
@@ -252,7 +173,7 @@ TODO:
        statx sx;
  #endif
  
-@@ -1002,6 +1013,13 @@ static struct file_struct *send_file_nam
+@@ -1011,6 +1016,13 @@ static struct file_struct *send_file_nam
                        return NULL;
        }
  #endif
@@ -266,26 +187,17 @@ TODO:
  
        maybe_emit_filelist_progress(flist->count + flist_count_offset);
  
-@@ -1014,11 +1032,19 @@ static struct file_struct *send_file_nam
-               if (preserve_acls && f >= 0)
-                       send_acl(&sx, f);
- #endif
-+#ifdef SUPPORT_XATTRS
-+              if (preserve_xattrs && f >= 0)
-+                      send_xattr(&sx, f);
-+#endif
-       } else {
- #ifdef SUPPORT_ACLS
-               if (preserve_acls && f >= 0)
-                       free_acl(&sx);
+@@ -1021,6 +1033,10 @@ static struct file_struct *send_file_nam
+       if (preserve_acls && f >= 0)
+               send_acl(&sx, f);
  #endif
 +#ifdef SUPPORT_XATTRS
-+              if (preserve_xattrs && f >= 0)
-+                      free_xattr(&sx);
++      if (preserve_xattrs && f >= 0)
++              send_xattr(&sx, f);
 +#endif
-       }
        return file;
  }
 --- old/lib/sysxattr.c
 +++ new/lib/sysxattr.c
 @@ -0,0 +1,135 @@
@@ -540,7 +452,16 @@ TODO:
  
                default:
                        /* A large opt value means that set_refuse_options()
-@@ -1563,6 +1584,10 @@ void server_options(char **args,int *arg
+@@ -1255,6 +1276,8 @@ int parse_arguments(int *argc, const cha
+               preserve_gid = flist_extra_ndx++;
+       if (preserve_acls)
+               preserve_acls = flist_extra_ndx++;
++      if (preserve_xattrs)
++              preserve_xattrs = flist_extra_ndx++;
+       *argv = poptGetArgs(pc);
+       *argc = count_args(*argv);
+@@ -1570,6 +1593,10 @@ void server_options(char **args,int *arg
        if (preserve_acls)
                argstr[x++] = 'A';
  #endif
@@ -561,7 +482,7 @@ TODO:
  extern int preserve_perms;
  extern int preserve_executability;
  extern int preserve_times;
-@@ -218,6 +219,10 @@ int set_file_attrs(char *fname, struct f
+@@ -271,6 +272,10 @@ int set_file_attrs(char *fname, struct f
        if (daemon_chmod_modes && !S_ISLNK(new_mode))
                new_mode = tweak_mode(new_mode, daemon_chmod_modes);
  
@@ -574,7 +495,7 @@ TODO:
         * will enable owner-writability using chmod, if necessary.
 --- old/rsync.h
 +++ new/rsync.h
-@@ -501,6 +501,10 @@ struct idev {
+@@ -503,6 +503,10 @@ struct idev {
  #define ACLS_NEED_MASK 1
  #endif
  
@@ -585,7 +506,15 @@ TODO:
  #define GID_NONE ((gid_t)-1)
  
  #define HL_CHECK_MASTER       0
-@@ -699,6 +703,9 @@ typedef struct {
+@@ -549,6 +553,7 @@ union flist_extras {
+ #define F_UID(f) FLIST_EXTRA(f, preserve_uid).uid
+ #define F_GID(f) FLIST_EXTRA(f, preserve_gid).gid
+ #define F_ACL(f) FLIST_EXTRA(f, preserve_acls).num
++#define F_XATTR(f) FLIST_EXTRA(f, preserve_xattrs).num
+ /* These are per-entry optional and mutally exclusive: */
+ #define F_IDEV(f) FLIST_EXTRA(f, flist_extra_ndx).idev
+@@ -712,6 +717,9 @@ typedef struct {
      struct rsync_acl *acc_acl; /* access ACL */
      struct rsync_acl *def_acl; /* default ACL */
  #endif
@@ -628,7 +557,7 @@ TODO:
  transfer.  The resulting value is treated as though it was the permissions
 --- old/xattr.c
 +++ new/xattr.c
-@@ -0,0 +1,417 @@
+@@ -0,0 +1,415 @@
 +/*
 + * Extended Attribute support for rsync.
 + * Written by Jay Fenlason, vaguely based on the ACLs patch.
@@ -660,6 +589,7 @@ TODO:
 +extern int am_root;
 +extern int read_only;
 +extern int list_only;
++extern int preserve_xattrs;
 +extern unsigned int file_struct_len;
 +
 +#define RSYNC_XAL_INITIAL 5
@@ -919,7 +849,6 @@ TODO:
 +void receive_xattr(struct file_struct *file, int f)
 +{
 +      static item_list temp_xattr = EMPTY_ITEM_LIST;
-+      char *ndx_ptr = (char*)file + file_struct_len;
 +      int ndx, tag = read_byte(f);
 +
 +      if (tag == 'X') {
@@ -987,14 +916,13 @@ TODO:
 +              exit_cleanup(RERR_STREAMIO);
 +      }
 +
-+      SIVAL(ndx_ptr, 0, ndx);
++      F_XATTR(file) = ndx;
 +}
 +
 +/* Turn the xattr data in statx into cached xattr data, setting the index
 + * values in the file struct. */
 +void cache_xattr(struct file_struct *file, statx *sxp)
 +{
-+      char *ndx_ptr = (char*)file + file_struct_len;
 +      int ndx;
 +
 +      if (!sxp->xattr)
@@ -1005,7 +933,7 @@ TODO:
 +              rsync_xal_store(sxp->xattr); /* adds item to rsync_xal_l */
 +      free_xattr(sxp);
 +
-+      SIVAL(ndx_ptr, 0, ndx);
++      F_XATTR(file) = ndx;
 +}
 +
 +static int rsync_xal_set(const char *fname, item_list *xalp)
@@ -1030,7 +958,6 @@ TODO:
 +int set_xattr(const char *fname, const struct file_struct *file, UNUSED(statx *sxp))
 +{
 +      int ndx;
-+      char *ndx_ptr = (char*)file + file_struct_len;
 +      item_list *lst = rsync_xal_l.items;
 +
 +      if (dry_run)
@@ -1041,7 +968,7 @@ TODO:
 +              return -1;
 +      }
 +
-+      ndx = IVAL(ndx_ptr, 0);
++      ndx = F_XATTR(file);
 +      return rsync_xal_set(fname, lst + ndx); /* TODO:  This needs to return 1 if no xattrs changed! */
 +}
 +