Fixed some patch fuzz.
[rsync/rsync-patches.git] / acls.diff
index 937f793..c86aa66 100644 (file)
--- a/acls.diff
+++ b/acls.diff
@@ -1,5 +1,6 @@
-After applying this patch, run these commands for a successful build:
+To use this patch, run these commands for a successful build:
 
 
+    patch -p1 <patches/acls.diff
     ./prepare-source
     ./configure --enable-acl-support
     make
     ./prepare-source
     ./configure --enable-acl-support
     make
@@ -9,7 +10,7 @@ latest ACL-enabling patch to send files to an older ACL-enabled rsync.
 
 --- old/Makefile.in
 +++ new/Makefile.in
 
 --- old/Makefile.in
 +++ new/Makefile.in
-@@ -25,15 +25,15 @@ VERSION=@VERSION@
+@@ -26,15 +26,15 @@ VERSION=@VERSION@
  .SUFFIXES:
  .SUFFIXES: .c .o
  
  .SUFFIXES:
  .SUFFIXES: .c .o
  
@@ -20,9 +21,9 @@ latest ACL-enabling patch to send files to an older ACL-enabled rsync.
 +      lib/permstring.o lib/pool_alloc.o lib/sysacls.o @LIBOBJS@
  ZLIBOBJ=zlib/deflate.o zlib/inffast.o zlib/inflate.o zlib/inftrees.o \
        zlib/trees.o zlib/zutil.o zlib/adler32.o zlib/compress.o zlib/crc32.o
 +      lib/permstring.o lib/pool_alloc.o lib/sysacls.o @LIBOBJS@
  ZLIBOBJ=zlib/deflate.o zlib/inffast.o zlib/inflate.o zlib/inftrees.o \
        zlib/trees.o zlib/zutil.o zlib/adler32.o zlib/compress.o zlib/crc32.o
- OBJS1=rsync.o generator.o receiver.o cleanup.o sender.o exclude.o util.o \
-       main.o checksum.o match.o syscall.o log.o backup.o
- OBJS2=options.o flist.o io.o compat.o hlink.o token.o uidlist.o socket.o \
+ OBJS1=flist.o rsync.o generator.o receiver.o cleanup.o sender.o exclude.o \
+       util.o main.o checksum.o match.o syscall.o log.o backup.o
+ OBJS2=options.o io.o compat.o hlink.o token.o uidlist.o socket.o \
 -      fileio.o batch.o clientname.o chmod.o
 +      fileio.o batch.o clientname.o chmod.o acls.o
  OBJS3=progress.o pipe.o
 -      fileio.o batch.o clientname.o chmod.o
 +      fileio.o batch.o clientname.o chmod.o acls.o
  OBJS3=progress.o pipe.o
@@ -58,11 +59,10 @@ latest ACL-enabling patch to send files to an older ACL-enabled rsync.
 +
 +#ifdef SUPPORT_ACLS
 +
 +
 +#ifdef SUPPORT_ACLS
 +
-+extern int am_root;
 +extern int dry_run;
 +extern int dry_run;
++extern int read_only;
++extern int list_only;
 +extern int orig_umask;
 +extern int orig_umask;
-+extern int preserve_acls;
-+extern unsigned int file_struct_len;
 +
 +/* === ACL structures === */
 +
 +
 +/* === ACL structures === */
 +
@@ -295,7 +295,6 @@ latest ACL-enabling patch to send files to an older ACL-enabled rsync.
 +      const char *errfun;
 +      int rc;
 +
 +      const char *errfun;
 +      int rc;
 +
-+      *racl = empty_rsync_acl;
 +      errfun = "sys_acl_get_entry";
 +      for (rc = sys_acl_get_entry(sacl, SMB_ACL_FIRST_ENTRY, &entry);
 +           rc == 1;
 +      errfun = "sys_acl_get_entry";
 +      for (rc = sys_acl_get_entry(sacl, SMB_ACL_FIRST_ENTRY, &entry);
 +           rc == 1;
@@ -534,6 +533,7 @@ latest ACL-enabling patch to send files to an older ACL-enabled rsync.
 +
 +              if (!racl)
 +                      out_of_memory("get_acl");
 +
 +              if (!racl)
 +                      out_of_memory("get_acl");
++              *racl = empty_rsync_acl;
 +              if (type == SMB_ACL_TYPE_ACCESS)
 +                      sxp->acc_acl = racl;
 +              else
 +              if (type == SMB_ACL_TYPE_ACCESS)
 +                      sxp->acc_acl = racl;
 +              else
@@ -547,9 +547,8 @@ latest ACL-enabling patch to send files to an older ACL-enabled rsync.
 +                              free_acl(sxp);
 +                              return -1;
 +                      }
 +                              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. */
 +                      /* ACLs are not supported, so pretend we have a basic ACL. */
-+                      *racl = empty_rsync_acl;
 +                      if (type == SMB_ACL_TYPE_ACCESS)
 +                              rsync_acl_fake_perms(racl, sxp->st.st_mode);
 +              } else {
 +                      if (type == SMB_ACL_TYPE_ACCESS)
 +                              rsync_acl_fake_perms(racl, sxp->st.st_mode);
 +              } else {
@@ -644,10 +643,8 @@ latest ACL-enabling patch to send files to an older ACL-enabled rsync.
 +                              sxp->def_acl = racl;
 +              }
 +
 +                              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');
 +                      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');
@@ -676,8 +673,6 @@ latest ACL-enabling patch to send files to an older ACL-enabled rsync.
 +      id_access *ida;
 +      size_t count;
 +
 +      id_access *ida;
 +      size_t count;
 +
-+      *racl = empty_rsync_acl;
-+
 +      if (!(count = read_int(f)))
 +              return;
 +
 +      if (!(count = read_int(f)))
 +              return;
 +
@@ -768,14 +763,12 @@ latest ACL-enabling patch to send files to an older ACL-enabled rsync.
 +{
 +      SMB_ACL_TYPE_T type;
 +      item_list *racl_list;
 +{
 +      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;
 +
 +      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;
 +      do {
 +              char tag = read_byte(f);
 +              int ndx;
@@ -801,6 +794,7 @@ latest ACL-enabling patch to send files to an older ACL-enabled rsync.
 +                      acl_duo *duo_item;
 +                      ndx = racl_list->count;
 +                      duo_item = EXPAND_ITEM_LIST(racl_list, acl_duo, 1000);
 +                      acl_duo *duo_item;
 +                      ndx = racl_list->count;
 +                      duo_item = EXPAND_ITEM_LIST(racl_list, acl_duo, 1000);
++                      duo_item->racl = empty_rsync_acl;
 +                      receive_rsync_acl(&duo_item->racl, f, type);
 +                      duo_item->sacl = NULL;
 +              } else {
 +                      receive_rsync_acl(&duo_item->racl, f, type);
 +                      duo_item->sacl = NULL;
 +              } else {
@@ -811,9 +805,11 @@ latest ACL-enabling patch to send files to an older ACL-enabled rsync.
 +                              exit_cleanup(RERR_STREAMIO);
 +                      }
 +              }
 +                              exit_cleanup(RERR_STREAMIO);
 +                      }
 +              }
-+              SIVAL(ndx_ptr, 0, ndx);
++              if (type == SMB_ACL_TYPE_ACCESS)
++                      F_ACL(file) = ndx;
++              else
++                      F_DEF_ACL(file) = ndx;
 +              racl_list = &default_acl_list;
 +              racl_list = &default_acl_list;
-+              ndx_ptr += 4;
 +      } while (BUMP_TYPE(type) && S_ISDIR(file->mode));
 +}
 +
 +      } while (BUMP_TYPE(type) && S_ISDIR(file->mode));
 +}
 +
@@ -824,7 +820,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;
 +      SMB_ACL_TYPE_T type;
 +      rsync_acl *racl;
 +      item_list *racl_list;
-+      char *ndx_ptr;
 +      int ndx;
 +
 +      if (S_ISLNK(file->mode))
 +      int ndx;
 +
 +      if (S_ISLNK(file->mode))
@@ -833,7 +828,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;
 +      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;
 +      do {
 +              if (!racl)
 +                      ndx = -1;
@@ -845,10 +839,12 @@ latest ACL-enabling patch to send files to an older ACL-enabled rsync.
 +                      new_duo->sacl = NULL;
 +                      *racl = empty_rsync_acl;
 +              }
 +                      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_DEF_ACL(file) = ndx;
 +              racl = sxp->def_acl;
 +              racl_list = &default_acl_list;
 +              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);
 +      } while (BUMP_TYPE(type) && S_ISDIR(sxp->st.st_mode));
 +
 +      free_acl(sxp);
@@ -916,13 +912,13 @@ latest ACL-enabling patch to send files to an older ACL-enabled rsync.
 +                      rsyserr(FERROR, errno, "change_sacl_perms: %s()",
 +                              errfun);
 +              }
 +                      rsyserr(FERROR, errno, "change_sacl_perms: %s()",
 +                              errfun);
 +              }
-+              return ~0u;
++              return (mode_t)~0;
 +      }
 +
 +#ifdef SMB_ACL_LOSES_SPECIAL_MODE_BITS
 +      /* Ensure that chmod() will be called to restore any lost setid bits. */
 +      if (old_mode & (S_ISUID | S_ISGID | S_ISVTX)
 +      }
 +
 +#ifdef SMB_ACL_LOSES_SPECIAL_MODE_BITS
 +      /* Ensure that chmod() will be called to restore any lost setid bits. */
 +      if (old_mode & (S_ISUID | S_ISGID | S_ISVTX)
-+       && (old_mode & CHMOD_BITS) == (mode & CHMOD_BITS))
++       && BITS_EQUAL(old_mode, mode, CHMOD_BITS))
 +              old_mode &= ~(S_ISUID | S_ISGID | S_ISVTX);
 +#endif
 +
 +              old_mode &= ~(S_ISUID | S_ISGID | S_ISVTX);
 +#endif
 +
@@ -942,21 +938,23 @@ latest ACL-enabling patch to send files to an older ACL-enabled rsync.
 +{
 +      int unchanged = 1;
 +      SMB_ACL_TYPE_T type;
 +{
 +      int unchanged = 1;
 +      SMB_ACL_TYPE_T type;
-+      char *ndx_ptr;
++
++      if (!dry_run && (read_only || list_only)) {
++              errno = EROFS;
++              return -1;
++      }
 +
 +      if (S_ISLNK(file->mode))
 +              return 1;
 +
 +      type = SMB_ACL_TYPE_ACCESS;
 +
 +      if (S_ISLNK(file->mode))
 +              return 1;
 +
 +      type = SMB_ACL_TYPE_ACCESS;
-+      ndx_ptr = (char*)file + file_struct_len;
 +      do {
 +              acl_duo *duo_item;
 +      do {
 +              acl_duo *duo_item;
++              int32 ndx;
 +              BOOL eq;
 +              BOOL eq;
-+              int32 ndx = IVAL(ndx_ptr, 0);
-+
-+              ndx_ptr += 4;
 +
 +              if (type == SMB_ACL_TYPE_ACCESS) {
 +
 +              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;
 +                      if (ndx < 0 || (size_t)ndx >= access_acl_list.count)
 +                              continue;
 +                      duo_item = access_acl_list.items;
@@ -964,6 +962,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 {
 +                      eq = sxp->acc_acl
 +                          && rsync_acl_equal_enough(sxp->acc_acl, &duo_item->racl, file->mode);
 +              } else {
++                      ndx = F_DEF_ACL(file);
 +                      if (ndx < 0 || (size_t)ndx >= default_acl_list.count)
 +                              continue;
 +                      duo_item = default_acl_list.items;
 +                      if (ndx < 0 || (size_t)ndx >= default_acl_list.count)
 +                              continue;
 +                      duo_item = default_acl_list.items;
@@ -992,7 +991,7 @@ latest ACL-enabling patch to send files to an older ACL-enabled rsync.
 +                              if (type == SMB_ACL_TYPE_ACCESS) {
 +                                      cur_mode = change_sacl_perms(duo_item->sacl, &duo_item->racl,
 +                                                                   cur_mode, file->mode);
 +                              if (type == SMB_ACL_TYPE_ACCESS) {
 +                                      cur_mode = change_sacl_perms(duo_item->sacl, &duo_item->racl,
 +                                                                   cur_mode, file->mode);
-+                                      if (cur_mode == ~0u)
++                                      if (cur_mode == (mode_t)~0)
 +                                              continue;
 +                              }
 +                              if (sys_acl_set_file(fname, type, duo_item->sacl) < 0) {
 +                                              continue;
 +                              }
 +                              if (sys_acl_set_file(fname, type, duo_item->sacl) < 0) {
@@ -1088,7 +1087,8 @@ latest ACL-enabling patch to send files to an older ACL-enabled rsync.
 +              /* Couldn't get an ACL.  Darn. */
 +              switch (errno) {
 +              case ENOTSUP:
 +              /* 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) {
 +                      break;
 +              case ENOENT:
 +                      if (dry_run) {
@@ -1105,6 +1105,7 @@ latest ACL-enabling patch to send files to an older ACL-enabled rsync.
 +      }
 +
 +      /* Convert it. */
 +      }
 +
 +      /* Convert it. */
++      racl = empty_rsync_acl;
 +      ok = unpack_smb_acl(&racl, sacl);
 +      sys_acl_free_acl(sacl);
 +      if (!ok) {
 +      ok = unpack_smb_acl(&racl, sacl);
 +      sys_acl_free_acl(sacl);
 +      if (!ok) {
@@ -1126,15 +1127,15 @@ latest ACL-enabling patch to send files to an older ACL-enabled rsync.
 +#endif /* SUPPORT_ACLS */
 --- old/backup.c
 +++ new/backup.c
 +#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;
  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
+@@ -93,7 +94,8 @@ path
  ****************************************************************************/
  static int make_bak_dir(char *fullpath)
  {
  ****************************************************************************/
  static int make_bak_dir(char *fullpath)
  {
@@ -1144,7 +1145,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;
        char *rel = fullpath + backup_dir_len;
        char *end = rel + strlen(rel);
        char *p = end;
-@@ -126,13 +128,24 @@ static int make_bak_dir(char *fullpath)
+@@ -125,15 +127,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. */
                if (p >= rel) {
                        /* Try to transfer the directory settings of the
                         * actual dir that the files are coming from. */
@@ -1155,6 +1156,7 @@ latest ACL-enabling patch to send files to an older ACL-enabled rsync.
                                        full_fname(rel));
                        } else {
 -                              do_lchown(fullpath, st.st_uid, st.st_gid);
                                        full_fname(rel));
                        } else {
 -                              do_lchown(fullpath, st.st_uid, st.st_gid);
+-#ifdef HAVE_CHMOD
 -                              do_chmod(fullpath, st.st_mode);
 +#ifdef SUPPORT_ACLS
 +                              sx.acc_acl = sx.def_acl = NULL;
 -                              do_chmod(fullpath, st.st_mode);
 +#ifdef SUPPORT_ACLS
 +                              sx.acc_acl = sx.def_acl = NULL;
@@ -1166,15 +1168,15 @@ latest ACL-enabling patch to send files to an older ACL-enabled rsync.
 +                                      get_acl(rel, &sx);
 +                                      cache_acl(file, &sx);
 +                              }
 +                                      get_acl(rel, &sx);
 +                                      cache_acl(file, &sx);
 +                              }
-+#endif
+ #endif
 +                              set_file_attrs(fullpath, file, NULL, 0);
 +                              free(file);
                        }
                }
                *p = '/';
 +                              set_file_attrs(fullpath, file, NULL, 0);
 +                              free(file);
                        }
                }
                *p = '/';
-@@ -170,15 +183,18 @@ static int robust_move(char *src, char *
+@@ -171,15 +182,18 @@ static int robust_move(const char *src, 
   * We will move the file to be deleted into a parallel directory tree. */
   * We will move the file to be deleted into a parallel directory tree. */
- static int keep_backup(char *fname)
+ static int keep_backup(const char *fname)
  {
 -      STRUCT_STAT st;
 +      statx sx;
  {
 -      STRUCT_STAT st;
 +      statx sx;
@@ -1193,9 +1195,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 */
  
        if (!(file = make_file(fname, NULL, NULL, 0, NO_FILTERS)))
                return 1; /* the file could have disappeared */
-@@ -186,6 +202,13 @@ static int keep_backup(char *fname)
-       if (!(buf = get_backup_name(fname)))
+@@ -189,6 +203,13 @@ static int keep_backup(const char *fname
                return 0;
                return 0;
+       }
  
 +#ifdef SUPPORT_ACLS
 +      if (preserve_acls) {
  
 +#ifdef SUPPORT_ACLS
 +      if (preserve_acls) {
@@ -1207,7 +1209,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))) {
        /* 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))) {
-@@ -254,7 +277,7 @@ static int keep_backup(char *fname)
+@@ -260,7 +281,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);
                if (robust_move(fname, buf) != 0) {
                        rsyserr(FERROR, errno, "keep_backup failed: %s -> \"%s\"",
                                full_fname(fname), buf);
@@ -1216,9 +1218,20 @@ latest ACL-enabling patch to send files to an older ACL-enabled rsync.
                        /* If someone has hard-linked the file into the backup
                         * dir, rename() might return success but do nothing! */
                        robust_unlink(fname); /* Just in case... */
                        /* If someone has hard-linked the file into the backup
                         * dir, rename() might return success but do nothing! */
                        robust_unlink(fname); /* Just in case... */
+--- old/compat.c
++++ new/compat.c
+@@ -50,6 +50,8 @@ void setup_protocol(int f_out,int f_in)
+               preserve_uid = ++file_extra_cnt;
+       if (preserve_gid)
+               preserve_gid = ++file_extra_cnt;
++      if (preserve_acls && !am_sender)
++              preserve_acls = ++file_extra_cnt;
+       if (remote_protocol == 0) {
+               if (!read_batch)
 --- old/configure.in
 +++ new/configure.in
 --- old/configure.in
 +++ new/configure.in
-@@ -482,6 +482,11 @@ if test x"$ac_cv_func_strcasecmp" = x"no
+@@ -542,6 +542,11 @@ if test x"$ac_cv_func_strcasecmp" = x"no
      AC_CHECK_LIB(resolv, strcasecmp)
  fi
  
      AC_CHECK_LIB(resolv, strcasecmp)
  fi
  
@@ -1230,11 +1243,11 @@ latest ACL-enabling patch to send files to an older ACL-enabled rsync.
  dnl At the moment we don't test for a broken memcmp(), because all we
  dnl need to do is test for equality, not comparison, and it seems that
  dnl every platform has a memcmp that can do at least that.
  dnl At the moment we don't test for a broken memcmp(), because all we
  dnl need to do is test for equality, not comparison, and it seems that
  dnl every platform has a memcmp that can do at least that.
-@@ -746,6 +751,78 @@ AC_SUBST(OBJ_RESTORE)
+@@ -806,6 +811,78 @@ AC_SUBST(OBJ_RESTORE)
  AC_SUBST(CC_SHOBJ_FLAG)
  AC_SUBST(BUILD_POPT)
  
  AC_SUBST(CC_SHOBJ_FLAG)
  AC_SUBST(BUILD_POPT)
  
-+AC_CHECK_HEADERS(sys/acl.h)
++AC_CHECK_HEADERS(sys/acl.h acl/libacl.h)
 +AC_CHECK_FUNCS(_acl __acl _facl __facl)
 +#################################################
 +# check for ACL support
 +AC_CHECK_FUNCS(_acl __acl _facl __facl)
 +#################################################
 +# check for ACL support
@@ -1311,7 +1324,7 @@ latest ACL-enabling patch to send files to an older ACL-enabled rsync.
  
 --- old/flist.c
 +++ new/flist.c
  
 --- old/flist.c
 +++ new/flist.c
-@@ -40,6 +40,7 @@ extern int filesfrom_fd;
+@@ -41,6 +41,7 @@ extern int filesfrom_fd;
  extern int one_file_system;
  extern int copy_dirlinks;
  extern int keep_dirlinks;
  extern int one_file_system;
  extern int copy_dirlinks;
  extern int keep_dirlinks;
@@ -1319,55 +1332,30 @@ 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;
  extern int preserve_links;
  extern int preserve_hard_links;
  extern int preserve_devices;
-@@ -133,6 +134,8 @@ static void list_file_entry(struct file_
+@@ -147,6 +148,8 @@ static void list_file_entry(struct file_
        permstring(permbuf, f->mode);
        permstring(permbuf, f->mode);
+       len = F_LENGTH(f);
  
 +      /* TODO: indicate '+' if the entry has an ACL. */
 +
  #ifdef SUPPORT_LINKS
        if (preserve_links && S_ISLNK(f->mode)) {
                rprintf(FINFO, "%s %11.0f %s %s -> %s\n",
  
 +      /* TODO: indicate '+' if the entry has an ACL. */
 +
  #ifdef SUPPORT_LINKS
        if (preserve_links && S_ISLNK(f->mode)) {
                rprintf(FINFO, "%s %11.0f %s %s -> %s\n",
-@@ -491,6 +494,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;
-@@ -594,13 +600,27 @@ static struct file_struct *receive_file_
-       sum_len = always_checksum && S_ISREG(mode) ? MD4_SUM_LENGTH : 0;
+@@ -662,6 +665,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)
  
 +#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) * EXTRA_LEN;
 +#endif
 +
 +#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");
+       if (always_checksum && S_ISREG(mode))
+               extra_len += SUM_EXTRA_CNT * EXTRA_LEN;
  
  
-       file = (struct file_struct *)bp;
-       memset(bp, 0, file_struct_len);
-       bp += file_struct_len;
-+#ifdef SUPPORT_ACLS
-+      bp += xtra_len;
-+#endif
-       file->modtime = modtime;
-       file->length = file_length;
-@@ -693,6 +713,11 @@ static struct file_struct *receive_file_
-               read_buf(f, sum, checksum_len);
+@@ -799,6 +808,11 @@ static struct file_struct *recv_file_ent
+                       read_buf(f, bp, checksum_len);
        }
  
 +#ifdef SUPPORT_ACLS
        }
  
 +#ifdef SUPPORT_ACLS
@@ -1378,8 +1366,8 @@ latest ACL-enabling patch to send files to an older ACL-enabled rsync.
        return file;
  }
  
        return file;
  }
  
-@@ -942,6 +967,9 @@ static struct file_struct *send_file_nam
-                                         unsigned short flags)
+@@ -1068,6 +1082,9 @@ static struct file_struct *send_file_nam
+                                         int flags)
  {
        struct file_struct *file;
 +#ifdef SUPPORT_ACLS
  {
        struct file_struct *file;
 +#ifdef SUPPORT_ACLS
@@ -1388,12 +1376,12 @@ 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);
  
        file = make_file(fname, flist, stp, flags,
                         f == -2 ? SERVER_FILTERS : ALL_FILTERS);
-@@ -951,6 +979,15 @@ static struct file_struct *send_file_nam
+@@ -1077,12 +1094,26 @@ static struct file_struct *send_file_nam
        if (chmod_modes && !S_ISLNK(file->mode))
                file->mode = tweak_mode(file->mode, chmod_modes);
  
 +#ifdef SUPPORT_ACLS
        if (chmod_modes && !S_ISLNK(file->mode))
                file->mode = tweak_mode(file->mode, chmod_modes);
  
 +#ifdef SUPPORT_ACLS
-+      if (preserve_acls) {
++      if (preserve_acls && f >= 0) {
 +              sx.st.st_mode = file->mode;
 +              sx.acc_acl = sx.def_acl = NULL;
 +              if (get_acl(fname, &sx) < 0)
 +              sx.st.st_mode = file->mode;
 +              sx.acc_acl = sx.def_acl = NULL;
 +              if (get_acl(fname, &sx) < 0)
@@ -1404,22 +1392,18 @@ 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);
        maybe_emit_filelist_progress(flist->count + flist_count_offset);
  
        flist_expand(flist);
-@@ -958,6 +995,15 @@ static struct file_struct *send_file_nam
-       if (file->basename[0]) {
-               flist->files[flist->count++] = file;
-               send_file_entry(file, f);
+       flist->files[flist->count++] = file;
+-      if (f >= 0)
++      if (f >= 0) {
+               send_file_entry(file, f, flist->count - 1);
 +#ifdef SUPPORT_ACLS
 +              if (preserve_acls)
 +                      send_acl(&sx, f);
 +#endif
 +#ifdef SUPPORT_ACLS
 +              if (preserve_acls)
 +                      send_acl(&sx, f);
 +#endif
-+      } else {
-+#ifdef SUPPORT_ACLS
-+              if (preserve_acls)
-+                      free_acl(&sx);
-+#endif
-       }
++      }
        return file;
  }
        return file;
  }
 --- old/generator.c
 +++ new/generator.c
 @@ -35,6 +35,7 @@ extern int do_progress;
 --- old/generator.c
 +++ new/generator.c
 @@ -35,6 +35,7 @@ extern int do_progress;
@@ -1430,32 +1414,31 @@ 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;
  extern int preserve_links;
  extern int preserve_devices;
  extern int preserve_specials;
-@@ -84,6 +85,7 @@ extern long block_size; /* "long" becaus
- extern int max_delete;
- extern int force_delete;
+@@ -87,6 +88,7 @@ extern int force_delete;
  extern int one_file_system;
  extern int one_file_system;
-+extern mode_t orig_umask;
  extern struct stats stats;
  extern dev_t filesystem_dev;
  extern struct stats stats;
  extern dev_t filesystem_dev;
++extern mode_t orig_umask;
  extern char *backup_dir;
  extern char *backup_dir;
-@@ -316,22 +318,27 @@ static void do_delete_pass(struct file_l
+ extern char *backup_suffix;
+ extern int backup_suffix_len;
+@@ -518,21 +520,26 @@ static void do_delete_pass(struct file_l
                rprintf(FINFO, "                    \r");
  }
  
 -int unchanged_attrs(struct file_struct *file, STRUCT_STAT *st)
 +int unchanged_attrs(struct file_struct *file, statx *sxp)
  {
                rprintf(FINFO, "                    \r");
  }
  
 -int unchanged_attrs(struct file_struct *file, STRUCT_STAT *st)
 +int unchanged_attrs(struct file_struct *file, statx *sxp)
  {
-       if (preserve_perms
--       && (st->st_mode & CHMOD_BITS) != (file->mode & CHMOD_BITS))
-+       && (sxp->st.st_mode & CHMOD_BITS) != (file->mode & CHMOD_BITS))
+-      if (preserve_perms && !BITS_EQUAL(st->st_mode, file->mode, CHMOD_BITS))
++      if (preserve_perms && !BITS_EQUAL(sxp->st.st_mode, file->mode, CHMOD_BITS))
                return 0;
  
                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;
  
                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
                return 0;
  
 +#ifdef SUPPORT_ACLS
@@ -1468,30 +1451,31 @@ latest ACL-enabling patch to send files to an older ACL-enabled rsync.
  
 -void itemize(struct file_struct *file, int ndx, int statret, STRUCT_STAT *st,
 +void itemize(struct file_struct *file, int ndx, int statret, statx *sxp,
  
 -void itemize(struct file_struct *file, int ndx, int statret, STRUCT_STAT *st,
 +void itemize(struct file_struct *file, int ndx, int statret, statx *sxp,
-            int32 iflags, uchar fnamecmp_type, char *xname)
+            int32 iflags, uchar fnamecmp_type, const char *xname)
  {
        if (statret >= 0) { /* A from-dest-dir statret can == 1! */
  {
        if (statret >= 0) { /* A from-dest-dir statret can == 1! */
-@@ -339,19 +346,23 @@ void itemize(struct file_struct *file, i
+@@ -540,20 +547,24 @@ void itemize(struct file_struct *file, i
                    : S_ISDIR(file->mode) ? !omit_dir_times
                    : !S_ISLNK(file->mode);
  
                    : S_ISDIR(file->mode) ? !omit_dir_times
                    : !S_ISLNK(file->mode);
  
--              if (S_ISREG(file->mode) && file->length != st->st_size)
-+              if (S_ISREG(file->mode) && file->length != sxp->st.st_size)
+-              if (S_ISREG(file->mode) && F_LENGTH(file) != st->st_size)
++              if (S_ISREG(file->mode) && F_LENGTH(file) != sxp->st.st_size)
                        iflags |= ITEM_REPORT_SIZE;
                if ((iflags & (ITEM_TRANSFER|ITEM_LOCAL_CHANGE) && !keep_time
                        iflags |= ITEM_REPORT_SIZE;
                if ((iflags & (ITEM_TRANSFER|ITEM_LOCAL_CHANGE) && !keep_time
-                    && (!(iflags & ITEM_XNAME_FOLLOWS) || *xname))
--                  || (keep_time && cmp_time(file->modtime, st->st_mtime) != 0))
-+                  || (keep_time && cmp_time(file->modtime, sxp->st.st_mtime) != 0))
+                 && !(iflags & ITEM_MATCHED)
+                 && (!(iflags & ITEM_XNAME_FOLLOWS) || *xname))
+-               || (keep_time && cmp_time(file->modtime, st->st_mtime) != 0))
++               || (keep_time && cmp_time(file->modtime, sxp->st.st_mtime) != 0))
                        iflags |= ITEM_REPORT_TIME;
                        iflags |= ITEM_REPORT_TIME;
--              if ((file->mode & CHMOD_BITS) != (st->st_mode & CHMOD_BITS))
-+              if ((file->mode & CHMOD_BITS) != (sxp->st.st_mode & CHMOD_BITS))
+-              if (!BITS_EQUAL(st->st_mode, file->mode, CHMOD_BITS))
++              if (!BITS_EQUAL(sxp->st.st_mode, file->mode, CHMOD_BITS))
                        iflags |= ITEM_REPORT_PERMS;
                        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;
                        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)
                        iflags |= ITEM_REPORT_GROUP;
 +#ifdef SUPPORT_ACLS
 +              if (preserve_acls && set_acl(NULL, file, sxp) == 0)
@@ -1500,16 +1484,16 @@ latest ACL-enabling patch to send files to an older ACL-enabled rsync.
        } else
                iflags |= ITEM_IS_NEW;
  
        } else
                iflags |= ITEM_IS_NEW;
  
-@@ -604,7 +615,7 @@ void check_for_finished_hlinks(int itemi
+@@ -808,7 +819,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,
 -                       char *cmpbuf, STRUCT_STAT *stp, int itemizing,
 +                       char *cmpbuf, statx *sxp, int itemizing,
   * 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,
 -                       char *cmpbuf, STRUCT_STAT *stp, int itemizing,
 +                       char *cmpbuf, statx *sxp, int itemizing,
-                        int maybe_ATTRS_REPORT, enum logcode code)
+                        enum logcode code)
  {
  {
-       int save_ignore_times = ignore_times;
-@@ -618,7 +629,7 @@ static int try_dests_reg(struct file_str
+       int best_match = -1;
+@@ -817,7 +828,7 @@ static int try_dests_reg(struct file_str
  
        do {
                pathjoin(cmpbuf, MAXPATHLEN, basis_dir[j], fname);
  
        do {
                pathjoin(cmpbuf, MAXPATHLEN, basis_dir[j], fname);
@@ -1518,7 +1502,7 @@ latest ACL-enabling patch to send files to an older ACL-enabled rsync.
                        continue;
                switch (match_level) {
                case 0:
                        continue;
                switch (match_level) {
                case 0:
-@@ -626,16 +637,20 @@ static int try_dests_reg(struct file_str
+@@ -825,16 +836,20 @@ static int try_dests_reg(struct file_str
                        match_level = 1;
                        /* FALL THROUGH */
                case 1:
                        match_level = 1;
                        /* FALL THROUGH */
                case 1:
@@ -1542,25 +1526,31 @@ latest ACL-enabling patch to send files to an older ACL-enabled rsync.
                                continue;
                        best_match = j;
                        match_level = 3;
                                continue;
                        best_match = j;
                        match_level = 3;
-@@ -652,14 +667,14 @@ static int try_dests_reg(struct file_str
+@@ -849,7 +864,7 @@ static int try_dests_reg(struct file_str
        if (j != best_match) {
                j = best_match;
                pathjoin(cmpbuf, MAXPATHLEN, basis_dir[j], fname);
 -              if (link_stat(cmpbuf, stp, 0) < 0)
 +              if (link_stat(cmpbuf, &sxp->st, 0) < 0)
        if (j != best_match) {
                j = best_match;
                pathjoin(cmpbuf, MAXPATHLEN, basis_dir[j], fname);
 -              if (link_stat(cmpbuf, stp, 0) < 0)
 +              if (link_stat(cmpbuf, &sxp->st, 0) < 0)
-                       match_level = 0;
+                       return -1;
        }
  
        }
  
-       if (match_level == 3 && !copy_dest) {
- #ifdef SUPPORT_HARD_LINKS
-               if (link_dest) {
--                      if (hard_link_one(file, ndx, fname, 0, stp,
-+                      if (hard_link_one(file, ndx, fname, 0, sxp,
-                                         cmpbuf, 1,
-                                         itemizing && verbose > 1,
-                                         code) < 0)
-@@ -668,8 +683,13 @@ static int try_dests_reg(struct file_str
-                               hard_link_cluster(file, ndx, itemizing, code);
+@@ -859,16 +874,25 @@ static int try_dests_reg(struct file_str
+                       if (!hard_link_one(file, fname, cmpbuf, 1))
+                               goto try_a_copy;
+                       if (preserve_hard_links && F_IS_HLINKED(file))
+-                              finish_hard_link(file, fname, stp, itemizing, code, j);
++                              finish_hard_link(file, fname, &sxp->st, itemizing, code, j);
+                       if (itemizing && (verbose > 1 || stdout_format_has_i > 1)) {
+-                              itemize(file, ndx, 1, stp,
++#ifdef SUPPORT_ACLS
++                              if (preserve_acls && !ACL_READY(*sxp))
++                                      get_acl(fname, sxp);
++#endif
++                              itemize(file, ndx, 1, sxp,
+                                       ITEM_LOCAL_CHANGE | ITEM_XNAME_FOLLOWS,
+                                       0, "");
+                       }
                } else
  #endif
 -              if (itemizing)
                } else
  #endif
 -              if (itemizing)
@@ -1572,10 +1562,10 @@ latest ACL-enabling patch to send files to an older ACL-enabled rsync.
 +#endif
 +                      itemize(file, ndx, 0, sxp, 0, 0, NULL);
 +              }
 +#endif
 +                      itemize(file, ndx, 0, sxp, 0, 0, NULL);
 +              }
-               if (verbose > 1 && maybe_ATTRS_REPORT) {
+               if (verbose > 1 && maybe_ATTRS_REPORT)
                        rprintf(FCLIENT, "%s is uptodate\n", fname);
                        rprintf(FCLIENT, "%s is uptodate\n", fname);
-               }
-@@ -685,8 +705,13 @@ static int try_dests_reg(struct file_str
+               return -2;
+@@ -885,8 +909,13 @@ static int try_dests_reg(struct file_str
                        }
                        return -1;
                }
                        }
                        return -1;
                }
@@ -1591,59 +1581,103 @@ 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)
                set_file_attrs(fname, file, NULL, 0);
                if (maybe_ATTRS_REPORT
                 && ((!itemizing && verbose && match_level == 2)
-@@ -710,13 +735,18 @@ static int try_dests_non(struct file_str
+@@ -897,7 +926,7 @@ static int try_dests_reg(struct file_str
+               }
+ #ifdef SUPPORT_HARD_LINKS
+               if (preserve_hard_links && F_IS_HLINKED(file))
+-                      finish_hard_link(file, fname, stp, itemizing, code, -1);
++                      finish_hard_link(file, fname, &sxp->st, itemizing, code, -1);
+ #endif
+               return -2;
+       }
+@@ -909,7 +938,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,
+-                       char *cmpbuf, STRUCT_STAT *stp, int itemizing,
++                       char *cmpbuf, statx *sxp, int itemizing,
                         enum logcode code)
  {
                         enum logcode code)
  {
-       char fnamebuf[MAXPATHLEN];
--      STRUCT_STAT st;
-+      statx sx;
-       int i = 0;
+       char lnk[MAXPATHLEN];
+@@ -942,24 +971,24 @@ static int try_dests_non(struct file_str
  
        do {
  
        do {
-               pathjoin(fnamebuf, MAXPATHLEN, basis_dir[i], fname);
--              if (link_stat(fnamebuf, &st, 0) < 0 || S_ISDIR(st.st_mode)
--               || !unchanged_attrs(file, &st))
-+              if (link_stat(fnamebuf, &sx.st, 0) < 0 || S_ISDIR(sx.st.st_mode))
-+                      continue;
-+#ifdef SUPPORT_ACLS
-+              if (preserve_acls)
-+                      get_acl(fnamebuf, &sx);
-+#endif
-+              if (!unchanged_attrs(file, &sx))
+               pathjoin(cmpbuf, MAXPATHLEN, basis_dir[j], fname);
+-              if (link_stat(cmpbuf, stp, 0) < 0)
++              if (link_stat(cmpbuf, &sxp->st, 0) < 0)
                        continue;
                        continue;
-               if (S_ISLNK(file->mode)) {
- #ifdef SUPPORT_LINKS
-@@ -729,10 +759,10 @@ static int try_dests_non(struct file_str
- #endif
+               switch (type) {
+               case TYPE_DIR:
+-                      if (!S_ISDIR(stp->st_mode))
++                      if (!S_ISDIR(sxp->st.st_mode))
                                continue;
                                continue;
-               } else if (IS_SPECIAL(file->mode)) {
--                      if (!IS_SPECIAL(st.st_mode) || st.st_rdev != file->u.rdev)
-+                      if (!IS_SPECIAL(sx.st.st_mode) || sx.st.st_rdev != file->u.rdev)
+                       break;
+               case TYPE_SPECIAL:
+-                      if (!IS_SPECIAL(stp->st_mode))
++                      if (!IS_SPECIAL(sxp->st.st_mode))
                                continue;
                                continue;
-               } else if (IS_DEVICE(file->mode)) {
--                      if (!IS_DEVICE(st.st_mode) || st.st_rdev != file->u.rdev)
-+                      if (!IS_DEVICE(sx.st.st_mode) || sx.st.st_rdev != file->u.rdev)
+                       break;
+               case TYPE_DEVICE:
+-                      if (!IS_DEVICE(stp->st_mode))
++                      if (!IS_DEVICE(sxp->st.st_mode))
                                continue;
                                continue;
-               } else {
-                       rprintf(FERROR,
-@@ -763,7 +793,15 @@ static int try_dests_non(struct file_str
-                       int changes = compare_dest ? 0 : ITEM_LOCAL_CHANGE
-                                   + (link_dest ? ITEM_XNAME_FOLLOWS : 0);
-                       char *lp = link_dest ? "" : NULL;
--                      itemize(file, ndx, 0, &st, changes, 0, lp);
+                       break;
+ #ifdef SUPPORT_LINKS
+               case TYPE_SYMLINK:
+-                      if (!S_ISLNK(stp->st_mode))
++                      if (!S_ISLNK(sxp->st.st_mode))
+                               continue;
+                       break;
+ #endif
+@@ -974,7 +1003,7 @@ static int try_dests_non(struct file_str
+               case TYPE_SPECIAL:
+               case TYPE_DEVICE:
+                       devp = F_RDEV_P(file);
+-                      if (stp->st_rdev != MAKEDEV(DEV_MAJOR(devp), DEV_MINOR(devp)))
++                      if (sxp->st.st_rdev != MAKEDEV(DEV_MAJOR(devp), DEV_MINOR(devp)))
+                               continue;
+                       break;
+ #ifdef SUPPORT_LINKS
+@@ -991,7 +1020,11 @@ static int try_dests_non(struct file_str
+                       match_level = 2;
+                       best_match = j;
+               }
+-              if (unchanged_attrs(file, stp)) {
++#ifdef SUPPORT_ACLS
++              if (preserve_acls)
++                      get_acl(cmpbuf, sxp);
++#endif
++              if (unchanged_attrs(file, sxp)) {
+                       match_level = 3;
+                       best_match = j;
+                       break;
+@@ -1004,7 +1037,7 @@ static int try_dests_non(struct file_str
+       if (j != best_match) {
+               j = best_match;
+               pathjoin(cmpbuf, MAXPATHLEN, basis_dir[j], fname);
+-              if (link_stat(cmpbuf, stp, 0) < 0)
++              if (link_stat(cmpbuf, &sxp->st, 0) < 0)
+                       return -1;
+       }
+@@ -1035,7 +1068,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;
+-                      itemize(file, ndx, 0, stp, chg + ITEM_MATCHED, 0, lp);
 +#ifdef SUPPORT_ACLS
 +                      if (preserve_acls)
 +#ifdef SUPPORT_ACLS
 +                      if (preserve_acls)
-+                              get_acl(fname, &sx);
++                              get_acl(fname, sxp);
 +#endif
 +#endif
-+                      itemize(file, ndx, 0, &sx, changes, 0, lp);
++                      itemize(file, ndx, 0, sxp, chg + ITEM_MATCHED, 0, lp);
 +#ifdef SUPPORT_ACLS
 +                      if (preserve_acls)
 +#ifdef SUPPORT_ACLS
 +                      if (preserve_acls)
-+                              free_acl(&sx);
++                              free_acl(sxp);
 +#endif
                }
                if (verbose > 1 && maybe_ATTRS_REPORT) {
 +#endif
                }
                if (verbose > 1 && maybe_ATTRS_REPORT) {
-                       rprintf(FCLIENT, "%s is uptodate\n", fname);
-@@ -775,6 +813,7 @@ static int try_dests_non(struct file_str
+                       rprintf(FCLIENT, "%s%s is uptodate\n",
+@@ -1048,6 +1089,7 @@ static int try_dests_non(struct file_str
  }
  
  static int phase = 0;
  }
  
  static int phase = 0;
@@ -1651,7 +1685,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
  
  /* 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
-@@ -796,7 +835,8 @@ static void recv_generator(char *fname, 
+@@ -1068,7 +1110,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;
        static int need_fuzzy_dirlist = 0;
        struct file_struct *fuzzy_file = NULL;
        int fd = -1, f_copy = -1;
@@ -1661,7 +1695,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;
        struct file_struct *back_file = NULL;
        int statret, real_ret, stat_errno;
        char *fnamecmp, *partialptr, *backupptr = NULL;
-@@ -852,6 +892,9 @@ static void recv_generator(char *fname, 
+@@ -1124,6 +1167,9 @@ static void recv_generator(char *fname, 
                } else if (!dry_run)
                        return;
        }
                } else if (!dry_run)
                        return;
        }
@@ -1671,16 +1705,16 @@ latest ACL-enabling patch to send files to an older ACL-enabled rsync.
        if (dry_run > 1) {
                statret = -1;
                stat_errno = ENOENT;
        if (dry_run > 1) {
                statret = -1;
                stat_errno = ENOENT;
-@@ -859,7 +902,7 @@ static void recv_generator(char *fname, 
-               char *dn = file->dirname ? file->dirname : ".";
+@@ -1131,7 +1177,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
                if (parent_dirname != dn && strcmp(parent_dirname, dn) != 0) {
                        if (relative_paths && !implied_dirs
--                       && safe_stat(dn, &st) < 0
-+                       && safe_stat(dn, &sx.st) < 0
+-                       && do_stat(dn, &st) < 0
++                       && do_stat(dn, &sx.st) < 0
                         && create_directory_path(fname) < 0) {
                                rsyserr(FERROR, errno,
                                        "recv_generator: mkdir %s failed",
                         && create_directory_path(fname) < 0) {
                                rsyserr(FERROR, errno,
                                        "recv_generator: mkdir %s failed",
-@@ -871,6 +914,10 @@ static void recv_generator(char *fname, 
+@@ -1143,6 +1189,10 @@ static void recv_generator(char *fname, 
                        }
                        if (fuzzy_basis)
                                need_fuzzy_dirlist = 1;
                        }
                        if (fuzzy_basis)
                                need_fuzzy_dirlist = 1;
@@ -1691,7 +1725,7 @@ latest ACL-enabling patch to send files to an older ACL-enabled rsync.
                }
                parent_dirname = dn;
  
                }
                parent_dirname = dn;
  
-@@ -879,7 +926,7 @@ static void recv_generator(char *fname, 
+@@ -1152,7 +1202,7 @@ static void recv_generator(char *fname, 
                        need_fuzzy_dirlist = 0;
                }
  
                        need_fuzzy_dirlist = 0;
                }
  
@@ -1700,7 +1734,7 @@ latest ACL-enabling patch to send files to an older ACL-enabled rsync.
                                    keep_dirlinks && S_ISDIR(file->mode));
                stat_errno = errno;
        }
                                    keep_dirlinks && S_ISDIR(file->mode));
                stat_errno = errno;
        }
-@@ -897,8 +944,9 @@ static void recv_generator(char *fname, 
+@@ -1170,8 +1220,9 @@ static void recv_generator(char *fname, 
         * mode based on the local permissions and some heuristics. */
        if (!preserve_perms) {
                int exists = statret == 0
         * mode based on the local permissions and some heuristics. */
        if (!preserve_perms) {
                int exists = statret == 0
@@ -1712,20 +1746,37 @@ latest ACL-enabling patch to send files to an older ACL-enabled rsync.
        }
  
        if (S_ISDIR(file->mode)) {
        }
  
        if (S_ISDIR(file->mode)) {
-@@ -907,8 +955,8 @@ static void recv_generator(char *fname, 
+@@ -1180,8 +1231,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. */
 -              if (statret == 0 && !S_ISDIR(st.st_mode)) {
                 * 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. */
 -              if (statret == 0 && !S_ISDIR(st.st_mode)) {
--                      if (delete_item(fname, st.st_mode, del_opts) < 0)
+-                      if (delete_item(fname, st.st_mode, "directory", del_opts) != 0)
 +              if (statret == 0 && !S_ISDIR(sx.st.st_mode)) {
 +              if (statret == 0 && !S_ISDIR(sx.st.st_mode)) {
-+                      if (delete_item(fname, sx.st.st_mode, del_opts) < 0)
++                      if (delete_item(fname, sx.st.st_mode, "directory", del_opts) != 0)
                                return;
                        statret = -1;
                }
                                return;
                        statret = -1;
                }
-@@ -917,7 +965,11 @@ static void recv_generator(char *fname, 
+@@ -1190,14 +1241,14 @@ static void recv_generator(char *fname, 
                        dry_run++;
                }
                        dry_run++;
                }
+               real_ret = statret;
+-              real_st = st;
++              real_sx = sx;
+               if (new_root_dir) {
+                       if (*fname == '.' && fname[1] == '\0')
+                               statret = -1;
+                       new_root_dir = 0;
+               }
+               if (statret != 0 && basis_dir[0] != NULL) {
+-                      int j = try_dests_non(file, fname, ndx, fnamecmpbuf, &st,
++                      int j = try_dests_non(file, fname, ndx, fnamecmpbuf, &sx,
+                                             itemizing, code);
+                       if (j == -2) {
+                               itemizing = 0;
+@@ -1206,7 +1257,11 @@ static void recv_generator(char *fname, 
+                               statret = 1;
+               }
                if (itemizing && f_out != -1) {
 -                      itemize(file, ndx, statret, &st,
 +#ifdef SUPPORT_ACLS
                if (itemizing && f_out != -1) {
 -                      itemize(file, ndx, statret, &st,
 +#ifdef SUPPORT_ACLS
@@ -1735,76 +1786,71 @@ latest ACL-enabling patch to send files to an older ACL-enabled rsync.
 +                      itemize(file, ndx, statret, &sx,
                                statret ? ITEM_LOCAL_CHANGE : 0, 0, NULL);
                }
 +                      itemize(file, ndx, statret, &sx,
                                statret ? ITEM_LOCAL_CHANGE : 0, 0, NULL);
                }
-               if (statret != 0 && do_mkdir(fname,file->mode) < 0 && errno != EEXIST) {
-@@ -937,19 +989,19 @@ static void recv_generator(char *fname, 
+               if (real_ret != 0 && do_mkdir(fname,file->mode) < 0 && errno != EEXIST) {
+@@ -1226,21 +1281,21 @@ static void recv_generator(char *fname, 
                                return;
                        }
                }
                                return;
                        }
                }
--              if (set_file_attrs(fname, file, statret ? NULL : &st, 0)
-+              if (set_file_attrs(fname, file, statret ? NULL : &sx, 0)
-                   && verbose && code && f_out != -1)
+-              if (set_file_attrs(fname, file, real_ret ? NULL : &real_st, 0)
++              if (set_file_attrs(fname, file, real_ret ? NULL : &real_sx, 0)
+                   && verbose && code != FNONE && f_out != -1)
                        rprintf(code, "%s/\n", fname);
                        rprintf(code, "%s/\n", fname);
+               if (real_ret != 0 && one_file_system)
+-                      real_st.st_dev = filesystem_dev;
++                      real_sx.st.st_dev = filesystem_dev;
                if (delete_during && f_out != -1 && !phase && dry_run < 2
                if (delete_during && f_out != -1 && !phase && dry_run < 2
-                   && (file->flags & FLAG_DEL_HERE))
--                      delete_in_dir(the_file_list, fname, file, &st);
+                   && (file->flags & FLAG_XFER_DIR))
+-                      delete_in_dir(the_file_list, fname, file, &real_st);
 -              return;
 -              return;
-+                      delete_in_dir(the_file_list, fname, file, &sx.st);
++                      delete_in_dir(the_file_list, fname, file, &real_sx.st);
 +              goto cleanup;
        }
  
 +              goto cleanup;
        }
  
-       if (preserve_hard_links && file->link_u.links
--          && hard_link_check(file, ndx, fname, statret, &st,
-+          && hard_link_check(file, ndx, fname, statret, &sx,
-                              itemizing, code, HL_CHECK_MASTER))
+ #ifdef SUPPORT_HARD_LINKS
+       if (preserve_hard_links && F_HLINK_NOT_FIRST(file)
+-       && hard_link_check(file, ndx, fname, statret, &st, itemizing, code))
 -              return;
 -              return;
++       && hard_link_check(file, ndx, fname, statret, &sx, itemizing, code))
 +              goto cleanup;
 +              goto cleanup;
+ #endif
  
        if (preserve_links && S_ISLNK(file->mode)) {
  
        if (preserve_links && S_ISLNK(file->mode)) {
- #ifdef SUPPORT_LINKS
-@@ -967,7 +1019,7 @@ static void recv_generator(char *fname, 
+@@ -1260,17 +1315,17 @@ static void recv_generator(char *fname, 
                        char lnk[MAXPATHLEN];
                        int len;
  
                        char lnk[MAXPATHLEN];
                        int len;
  
--                      if (!S_ISDIR(st.st_mode)
-+                      if (!S_ISDIR(sx.st.st_mode)
-                           && (len = readlink(fname, lnk, MAXPATHLEN-1)) > 0) {
-                               lnk[len] = 0;
-                               /* A link already pointing to the
-@@ -975,10 +1027,10 @@ static void recv_generator(char *fname, 
-                                * required. */
-                               if (strcmp(lnk, file->u.link) == 0) {
-                                       if (itemizing) {
--                                              itemize(file, ndx, 0, &st, 0,
-+                                              itemize(file, ndx, 0, &sx, 0,
-                                                       0, NULL);
-                                       }
--                                      set_file_attrs(fname, file, &st,
-+                                      set_file_attrs(fname, file, &sx,
-                                                      maybe_ATTRS_REPORT);
-                                       if (preserve_hard_links
-                                           && file->link_u.links) {
-@@ -991,9 +1043,9 @@ static void recv_generator(char *fname, 
+-                      if (!S_ISLNK(st.st_mode))
++                      if (!S_ISLNK(sx.st.st_mode))
+                               statret = -1;
+                       else if ((len = readlink(fname, lnk, MAXPATHLEN-1)) > 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);
+ #ifdef SUPPORT_HARD_LINKS
+                               if (preserve_hard_links && F_IS_HLINKED(file))
+-                                      finish_hard_link(file, fname, &st, itemizing, code, -1);
++                                      finish_hard_link(file, fname, &sx.st, itemizing, code, -1);
+ #endif
+                               if (remove_source_files == 1)
+                                       goto return_with_success;
+@@ -1278,10 +1333,10 @@ static void recv_generator(char *fname, 
                        }
                        /* Not the right symlink (or not a symlink), so
                         * delete it. */
                        }
                        /* Not the right symlink (or not a symlink), so
                         * delete it. */
--                      if (delete_item(fname, st.st_mode, del_opts) < 0)
-+                      if (delete_item(fname, sx.st.st_mode, del_opts) < 0)
+-                      if (delete_item(fname, st.st_mode, "symlink", del_opts) != 0)
++                      if (delete_item(fname, sx.st.st_mode, "symlink", del_opts) != 0)
                                return;
                                return;
--                      if (!S_ISLNK(st.st_mode))
-+                      if (!S_ISLNK(sx.st.st_mode))
-                               statret = -1;
                } else if (basis_dir[0] != NULL) {
                } else if (basis_dir[0] != NULL) {
-                       if (try_dests_non(file, fname, ndx, itemizing,
-@@ -1009,7 +1061,7 @@ static void recv_generator(char *fname, 
-                       }
-               }
-               if (preserve_hard_links && file->link_u.links
--                  && 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) {
-@@ -1018,7 +1070,7 @@ static void recv_generator(char *fname, 
+-                      int j = try_dests_non(file, fname, ndx, fnamecmpbuf, &st,
++                      int j = try_dests_non(file, fname, ndx, fnamecmpbuf, &sx,
+                                             itemizing, code);
+                       if (j == -2) {
+ #ifndef CAN_HARDLINK_SYMLINK
+@@ -1306,7 +1361,7 @@ static void recv_generator(char *fname, 
                } else {
                        set_file_attrs(fname, file, NULL, 0);
                        if (itemizing) {
                } else {
                        set_file_attrs(fname, file, NULL, 0);
                        if (itemizing) {
@@ -1812,64 +1858,80 @@ latest ACL-enabling patch to send files to an older ACL-enabled rsync.
 +                              itemize(file, ndx, statret, &sx,
                                        ITEM_LOCAL_CHANGE, 0, NULL);
                        }
 +                              itemize(file, ndx, statret, &sx,
                                        ITEM_LOCAL_CHANGE, 0, NULL);
                        }
-                       if (code && verbose) {
-@@ -1052,18 +1104,22 @@ static void recv_generator(char *fname, 
-                               itemizing = code = 0;
+                       if (code != FNONE && verbose)
+@@ -1332,33 +1387,38 @@ static void recv_generator(char *fname, 
+               if (statret == 0) {
+                       char *t;
+                       if (IS_DEVICE(file->mode)) {
+-                              if (!IS_DEVICE(st.st_mode))
++                              if (!IS_DEVICE(sx.st.st_mode))
+                                       statret = -1;
+                               t = "device file";
+                       } else {
+-                              if (!IS_SPECIAL(st.st_mode))
++                              if (!IS_SPECIAL(sx.st.st_mode))
+                                       statret = -1;
+                               t = "special file";
                        }
                        }
-               }
+                       if (statret == 0
+-                       && BITS_EQUAL(st.st_mode, file->mode, _S_IFMT)
+-                       && st.st_rdev == rdev) {
++                       && BITS_EQUAL(sx.st.st_mode, file->mode, _S_IFMT)
++                       && sx.st.st_rdev == rdev) {
+                               /* The device or special file is identical. */
+-                              if (itemizing)
+-                                      itemize(file, ndx, 0, &st, 0, 0, NULL);
+-                              set_file_attrs(fname, file, &st, maybe_ATTRS_REPORT);
++                              if (itemizing) {
 +#ifdef SUPPORT_ACLS
 +#ifdef SUPPORT_ACLS
-+              if (preserve_acls && statret == 0)
-+                      get_acl(fname, &sx);
++                                      if (preserve_acls)
++                                              get_acl(fname, &sx);
 +#endif
 +#endif
-               if (statret != 0
--               || (st.st_mode & ~CHMOD_BITS) != (file->mode & ~CHMOD_BITS)
--               || st.st_rdev != file->u.rdev) {
-+               || (sx.st.st_mode & ~CHMOD_BITS) != (file->mode & ~CHMOD_BITS)
-+               || sx.st.st_rdev != file->u.rdev) {
-                       if (statret == 0
--                       && delete_item(fname, st.st_mode, del_opts) < 0)
--                              return;
-+                       && delete_item(fname, sx.st.st_mode, del_opts) < 0)
-+                              goto cleanup;
-                       if (preserve_hard_links && file->link_u.links
--                          && hard_link_check(file, ndx, fname, -1, &st,
-+                          && hard_link_check(file, ndx, fname, -1, &sx,
-                                              itemizing, code, HL_SKIP))
++                                      itemize(file, ndx, 0, &sx, 0, 0, NULL);
++                              }
++                              set_file_attrs(fname, file, &sx, maybe_ATTRS_REPORT);
+ #ifdef SUPPORT_HARD_LINKS
+                               if (preserve_hard_links && F_IS_HLINKED(file))
+-                                      finish_hard_link(file, fname, &st, itemizing, code, -1);
++                                      finish_hard_link(file, fname, &sx.st, itemizing, code, -1);
+ #endif
+                               if (remove_source_files == 1)
+                                       goto return_with_success;
 -                              return;
 -                              return;
--                      if ((IS_DEVICE(file->mode) && !IS_DEVICE(st.st_mode))
--                       || (IS_SPECIAL(file->mode) && !IS_SPECIAL(st.st_mode)))
 +                              goto cleanup;
 +                              goto cleanup;
-+                      if ((IS_DEVICE(file->mode) && !IS_DEVICE(sx.st.st_mode))
-+                       || (IS_SPECIAL(file->mode) && !IS_SPECIAL(sx.st.st_mode)))
-                               statret = -1;
-                       if (verbose > 2) {
-                               rprintf(FINFO,"mknod(%s,0%o,0x%x)\n",
-@@ -1076,7 +1132,7 @@ static void recv_generator(char *fname, 
-                       } else {
-                               set_file_attrs(fname, file, NULL, 0);
-                               if (itemizing) {
--                                      itemize(file, ndx, statret, &st,
-+                                      itemize(file, ndx, statret, &sx,
-                                               ITEM_LOCAL_CHANGE, 0, NULL);
-                               }
-                               if (code && verbose)
-@@ -1088,12 +1144,12 @@ static void recv_generator(char *fname, 
                        }
                        }
+-                      if (delete_item(fname, st.st_mode, t, del_opts) != 0)
++                      if (delete_item(fname, sx.st.st_mode, t, del_opts) != 0)
+                               return;
+               } else if (basis_dir[0] != NULL) {
+-                      int j = try_dests_non(file, fname, ndx, fnamecmpbuf, &st,
++                      int j = try_dests_non(file, fname, ndx, fnamecmpbuf, &sx,
+                                             itemizing, code);
+                       if (j == -2) {
+ #ifndef CAN_HARDLINK_SPECIAL
+@@ -1388,7 +1448,11 @@ static void recv_generator(char *fname, 
                } else {
                } else {
-                       if (itemizing)
--                              itemize(file, ndx, statret, &st, 0, 0, NULL);
--                      set_file_attrs(fname, file, &st, maybe_ATTRS_REPORT);
-+                              itemize(file, ndx, statret, &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);
+                       set_file_attrs(fname, file, NULL, 0);
+                       if (itemizing) {
+-                              itemize(file, ndx, statret, &st,
++#ifdef SUPPORT_ACLS
++                              if (preserve_acls && statret == 0)
++                                      get_acl(fname, &sx);
++#endif
++                              itemize(file, ndx, statret, &sx,
+                                       ITEM_LOCAL_CHANGE, 0, NULL);
+                       }
+                       if (code != FNONE && verbose)
+@@ -1400,7 +1464,7 @@ static void recv_generator(char *fname, 
+                       if (remove_source_files == 1)
+                               goto return_with_success;
                }
 -              return;
 +              goto cleanup;
        }
  
        if (!S_ISREG(file->mode)) {
                }
 -              return;
 +              goto cleanup;
        }
  
        if (!S_ISREG(file->mode)) {
-@@ -1127,7 +1183,7 @@ static void recv_generator(char *fname, 
+@@ -1434,7 +1498,7 @@ static void recv_generator(char *fname, 
        }
  
        if (update_only && statret == 0
        }
  
        if (update_only && statret == 0
@@ -1878,14 +1940,14 @@ latest ACL-enabling patch to send files to an older ACL-enabled rsync.
                if (verbose > 1)
                        rprintf(FINFO, "%s is newer\n", fname);
                return;
                if (verbose > 1)
                        rprintf(FINFO, "%s is newer\n", fname);
                return;
-@@ -1136,18 +1192,18 @@ static void recv_generator(char *fname, 
+@@ -1443,20 +1507,20 @@ static void recv_generator(char *fname, 
        fnamecmp = fname;
        fnamecmp_type = FNAMECMP_FNAME;
  
 -      if (statret == 0 && !S_ISREG(st.st_mode)) {
        fnamecmp = fname;
        fnamecmp_type = FNAMECMP_FNAME;
  
 -      if (statret == 0 && !S_ISREG(st.st_mode)) {
--              if (delete_item(fname, st.st_mode, del_opts) != 0)
+-              if (delete_item(fname, st.st_mode, "regular file", del_opts) != 0)
 +      if (statret == 0 && !S_ISREG(sx.st.st_mode)) {
 +      if (statret == 0 && !S_ISREG(sx.st.st_mode)) {
-+              if (delete_item(fname, sx.st.st_mode, del_opts) != 0)
++              if (delete_item(fname, sx.st.st_mode, "regular file", del_opts) != 0)
                        return;
                statret = -1;
                stat_errno = ENOENT;
                        return;
                statret = -1;
                stat_errno = ENOENT;
@@ -1894,14 +1956,16 @@ latest ACL-enabling patch to send files to an older ACL-enabled rsync.
        if (statret != 0 && basis_dir[0] != NULL) {
 -              int j = try_dests_reg(file, fname, ndx, fnamecmpbuf, &st,
 +              int j = try_dests_reg(file, fname, ndx, fnamecmpbuf, &sx,
        if (statret != 0 && basis_dir[0] != NULL) {
 -              int j = try_dests_reg(file, fname, ndx, fnamecmpbuf, &st,
 +              int j = try_dests_reg(file, fname, ndx, fnamecmpbuf, &sx,
-                                     itemizing, maybe_ATTRS_REPORT, code);
-               if (j == -2)
+                                     itemizing, code);
+               if (j == -2) {
+                       if (remove_source_files == 1)
+                               goto return_with_success;
 -                      return;
 +                      goto cleanup;
 -                      return;
 +                      goto cleanup;
-               if (j != -1) {
+               }
+               if (j >= 0) {
                        fnamecmp = fnamecmpbuf;
                        fnamecmp = fnamecmpbuf;
-                       fnamecmp_type = j;
-@@ -1156,7 +1212,7 @@ static void recv_generator(char *fname, 
+@@ -1466,7 +1530,7 @@ static void recv_generator(char *fname, 
        }
  
        real_ret = statret;
        }
  
        real_ret = statret;
@@ -1910,30 +1974,21 @@ 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
  
        if (partial_dir && (partialptr = partial_dir_fname(fname)) != NULL
            && link_stat(partialptr, &partial_st, 0) == 0
-@@ -1175,7 +1231,7 @@ static void recv_generator(char *fname, 
+@@ -1485,7 +1549,7 @@ static void recv_generator(char *fname, 
                                rprintf(FINFO, "fuzzy basis selected for %s: %s\n",
                                        fname, fnamecmpbuf);
                        }
                                rprintf(FINFO, "fuzzy basis selected for %s: %s\n",
                                        fname, fnamecmpbuf);
                        }
--                      st.st_size = fuzzy_file->length;
-+                      sx.st.st_size = fuzzy_file->length;
+-                      st.st_size = F_LENGTH(fuzzy_file);
++                      sx.st.st_size = F_LENGTH(fuzzy_file);
                        statret = 0;
                        fnamecmp = fnamecmpbuf;
                        fnamecmp_type = FNAMECMP_FUZZY;
                        statret = 0;
                        fnamecmp = fnamecmpbuf;
                        fnamecmp_type = FNAMECMP_FUZZY;
-@@ -1184,7 +1240,7 @@ static void recv_generator(char *fname, 
-       if (statret != 0) {
-               if (preserve_hard_links && file->link_u.links
--                  && 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)
-@@ -1194,31 +1250,44 @@ static void recv_generator(char *fname, 
+@@ -1504,36 +1568,41 @@ static void recv_generator(char *fname, 
                return;
        }
  
                return;
        }
  
--      if (append_mode && st.st_size > file->length)
-+      if (append_mode && sx.st.st_size > file->length)
+-      if (append_mode && st.st_size > F_LENGTH(file))
++      if (append_mode && sx.st.st_size > F_LENGTH(file))
                return;
  
        if (fnamecmp_type <= FNAMECMP_BASIS_DIR_HIGH)
                return;
  
        if (fnamecmp_type <= FNAMECMP_BASIS_DIR_HIGH)
@@ -1946,28 +2001,28 @@ latest ACL-enabling patch to send files to an older ACL-enabled rsync.
                        do_unlink(partialptr);
                        handle_partial_dir(partialptr, PDIR_DELETE);
                }
                        do_unlink(partialptr);
                        handle_partial_dir(partialptr, PDIR_DELETE);
                }
-               if (itemizing) {
--                      itemize(file, ndx, real_ret, &real_st,
-+#ifdef SUPPORT_ACLS
-+                      if (preserve_acls && real_ret == 0)
-+                              get_acl(fname, &real_sx);
-+#endif
-+                      itemize(file, ndx, real_ret, &real_sx,
-                               0, 0, NULL);
+-              if (itemizing)
+-                      itemize(file, ndx, statret, &st, 0, 0, NULL);
+-              set_file_attrs(fname, file, &st, maybe_ATTRS_REPORT);
++              if (itemizing) {
 +#ifdef SUPPORT_ACLS
 +#ifdef SUPPORT_ACLS
-+                      if (preserve_acls) {
-+                              if (fnamecmp_type == FNAMECMP_FNAME) {
-+                                      sx.acc_acl = real_sx.acc_acl;
-+                                      sx.def_acl = real_sx.def_acl;
-+                              } else
-+                                      free_acl(&real_sx);
-+                      }
++                      if (preserve_acls && statret == 0)
++                              get_acl(fnamecmp, &sx);
 +#endif
 +#endif
-               }
--              set_file_attrs(fname, file, &st, maybe_ATTRS_REPORT);
++                      itemize(file, ndx, statret, &sx, 0, 0, NULL);
++              }
 +              set_file_attrs(fname, file, &sx, 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);
+ #ifdef SUPPORT_HARD_LINKS
+               if (preserve_hard_links && F_IS_HLINKED(file))
+-                      finish_hard_link(file, fname, &st, itemizing, code, -1);
++                      finish_hard_link(file, fname, &sx.st, itemizing, code, -1);
+ #endif
+               if (remove_source_files != 1)
+-                      return;
++                      goto cleanup;
+         return_with_success:
+               if (!dry_run)
+                       send_msg_int(MSG_SUCCESS, ndx);
 -              return;
 +              goto cleanup;
        }
 -              return;
 +              goto cleanup;
        }
@@ -1979,15 +2034,13 @@ latest ACL-enabling patch to send files to an older ACL-enabled rsync.
                fnamecmp = partialptr;
                fnamecmp_type = FNAMECMP_PARTIAL_DIR;
                statret = 0;
                fnamecmp = partialptr;
                fnamecmp_type = FNAMECMP_PARTIAL_DIR;
                statret = 0;
-@@ -1242,17 +1311,21 @@ static void recv_generator(char *fname, 
-         pretend_missing:
+@@ -1558,16 +1627,20 @@ static void recv_generator(char *fname, 
                /* pretend the file didn't exist */
                /* pretend the file didn't exist */
-               if (preserve_hard_links && file->link_u.links
--                  && hard_link_check(file, ndx, fname, statret, &st,
-+                  && hard_link_check(file, ndx, fname, statret, &sx,
-                                      itemizing, code, HL_SKIP))
+ #ifdef SUPPORT_HARD_LINKS
+               if (preserve_hard_links && F_HLINK_NOT_LAST(file))
 -                      return;
 +                      goto cleanup;
 -                      return;
 +                      goto cleanup;
+ #endif
                statret = real_ret = -1;
 +#ifdef SUPPORT_ACLS
 +              if (preserve_acls && ACL_READY(sx))
                statret = real_ret = -1;
 +#ifdef SUPPORT_ACLS
 +              if (preserve_acls && ACL_READY(sx))
@@ -2004,18 +2057,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);
                }
                if (!(back_file = make_file(fname, NULL, NULL, 0, NO_FILTERS))) {
                        close(fd);
-@@ -1263,7 +1336,7 @@ static void recv_generator(char *fname, 
+@@ -1578,7 +1651,7 @@ static void recv_generator(char *fname, 
                                full_fname(backupptr));
                                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) {
                        close(fd);
 -                      return;
 +                      goto cleanup;
                }
                if ((f_copy = do_open(backupptr,
                    O_WRONLY | O_CREAT | O_TRUNC | O_EXCL, 0600)) < 0) {
-@@ -1271,14 +1344,14 @@ static void recv_generator(char *fname, 
+@@ -1586,14 +1659,14 @@ static void recv_generator(char *fname, 
                                full_fname(backupptr));
                                full_fname(backupptr));
-                       free(back_file);
+                       unmake_file(back_file);
                        close(fd);
 -                      return;
 +                      goto cleanup;
                        close(fd);
 -                      return;
 +                      goto cleanup;
@@ -2030,14 +2083,14 @@ latest ACL-enabling patch to send files to an older ACL-enabled rsync.
        }
  
        if (verbose > 2)
        }
  
        if (verbose > 2)
-@@ -1296,24 +1369,32 @@ static void recv_generator(char *fname, 
+@@ -1615,26 +1688,34 @@ static void recv_generator(char *fname, 
                        iflags |= ITEM_BASIS_TYPE_FOLLOWS;
                if (fnamecmp_type == FNAMECMP_FUZZY)
                        iflags |= ITEM_XNAME_FOLLOWS;
 -              itemize(file, -1, real_ret, &real_st, iflags, fnamecmp_type,
 +#ifdef SUPPORT_ACLS
 +              if (preserve_acls && real_ret == 0)
                        iflags |= ITEM_BASIS_TYPE_FOLLOWS;
                if (fnamecmp_type == FNAMECMP_FUZZY)
                        iflags |= ITEM_XNAME_FOLLOWS;
 -              itemize(file, -1, real_ret, &real_st, iflags, fnamecmp_type,
 +#ifdef SUPPORT_ACLS
 +              if (preserve_acls && real_ret == 0)
-+                      get_acl(fname, &real_sx);
++                      get_acl(fnamecmp, &real_sx);
 +#endif
 +              itemize(file, -1, real_ret, &real_sx, iflags, fnamecmp_type,
                        fuzzy_file ? fuzzy_file->basename : NULL);
 +#endif
 +              itemize(file, -1, real_ret, &real_sx, iflags, fnamecmp_type,
                        fuzzy_file ? fuzzy_file->basename : NULL);
@@ -2048,8 +2101,11 @@ latest ACL-enabling patch to send files to an older ACL-enabled rsync.
        }
  
        if (!do_xfers) {
        }
  
        if (!do_xfers) {
-               if (preserve_hard_links && file->link_u.links)
-                       hard_link_cluster(file, ndx, itemizing, code);
+ #ifdef SUPPORT_HARD_LINKS
+               if (preserve_hard_links && F_IS_HLINKED(file))
+-                      finish_hard_link(file, fname, &st, itemizing, code, -1);
++                      finish_hard_link(file, fname, &sx.st, itemizing, code, -1);
+ #endif
 -              return;
 +              goto cleanup;
        }
 -              return;
 +              goto cleanup;
        }
@@ -2068,7 +2124,7 @@ latest ACL-enabling patch to send files to an older ACL-enabled rsync.
  
        if (f_copy >= 0) {
                close(f_copy);
  
        if (f_copy >= 0) {
                close(f_copy);
-@@ -1326,6 +1407,13 @@ static void recv_generator(char *fname, 
+@@ -1647,6 +1728,13 @@ static void recv_generator(char *fname, 
        }
  
        close(fd);
        }
  
        close(fd);
@@ -2082,7 +2138,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)
  }
  
  void generate_files(int f_out, struct file_list *flist, char *local_name)
-@@ -1385,6 +1473,8 @@ void generate_files(int f_out, struct fi
+@@ -1713,6 +1801,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;
  
         * notice that and let us know via the redo pipe (or its closing). */
        ignore_timeout = 1;
  
@@ -2093,30 +2149,30 @@ latest ACL-enabling patch to send files to an older ACL-enabled rsync.
  
 --- old/hlink.c
 +++ new/hlink.c
  
 --- old/hlink.c
 +++ new/hlink.c
-@@ -25,6 +25,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 link_dest;
 +extern int preserve_acls;
  extern int make_backups;
- extern int stdout_format_has_i;
- extern char *basis_dir[];
-@@ -143,15 +144,19 @@ void init_hard_links(void)
+ extern int protocol_version;
+ extern int remove_source_files;
+@@ -268,15 +269,19 @@ void match_hard_links(void)
+ }
  
  
- #ifdef SUPPORT_HARD_LINKS
  static int maybe_hard_link(struct file_struct *file, int ndx,
  static int maybe_hard_link(struct file_struct *file, int ndx,
--                         char *fname, int statret, STRUCT_STAT *st,
-+                         char *fname, int statret, statx *sxp,
-                          char *toname, STRUCT_STAT *to_st,
-                          int itemizing, enum logcode code)
+-                         const char *fname, int statret, STRUCT_STAT *stp,
++                         const char *fname, int statret, statx *sxp,
+                          const char *oldname, STRUCT_STAT *old_stp,
+                          const char *realname, int itemizing, enum logcode code)
  {
        if (statret == 0) {
  {
        if (statret == 0) {
--              if (st->st_dev == to_st->st_dev
--               && st->st_ino == to_st->st_ino) {
-+              if (sxp->st.st_dev == to_st->st_dev
-+               && sxp->st.st_ino == to_st->st_ino) {
+-              if (stp->st_dev == old_stp->st_dev
+-               && stp->st_ino == old_stp->st_ino) {
++              if (sxp->st.st_dev == old_stp->st_dev
++               && sxp->st.st_ino == old_stp->st_ino) {
                        if (itemizing) {
                        if (itemizing) {
--                              itemize(file, ndx, statret, st,
+-                              itemize(file, ndx, statret, stp,
 +#ifdef SUPPORT_ACLS
 +                              if (preserve_acls && !ACL_READY(*sxp))
 +                                      get_acl(fname, sxp);
 +#ifdef SUPPORT_ACLS
 +                              if (preserve_acls && !ACL_READY(*sxp))
 +                                      get_acl(fname, sxp);
@@ -2125,108 +2181,136 @@ latest ACL-enabling patch to send files to an older ACL-enabled rsync.
                                        ITEM_LOCAL_CHANGE | ITEM_XNAME_FOLLOWS,
                                        0, "");
                        }
                                        ITEM_LOCAL_CHANGE | ITEM_XNAME_FOLLOWS,
                                        0, "");
                        }
-@@ -166,13 +171,13 @@ static int maybe_hard_link(struct file_s
-                       return -1;
-               }
-       }
--      return hard_link_one(file, ndx, fname, statret, st, toname,
-+      return hard_link_one(file, ndx, fname, statret, sxp, toname,
-                            0, itemizing, code);
- }
- #endif
+@@ -297,7 +302,11 @@ static int maybe_hard_link(struct file_s
  
  
- int hard_link_check(struct file_struct *file, int ndx, char *fname,
--                  int statret, STRUCT_STAT *st, int itemizing,
+       if (hard_link_one(file, fname, oldname, 0)) {
+               if (itemizing) {
+-                      itemize(file, ndx, statret, stp,
++#ifdef SUPPORT_ACLS
++                      if (preserve_acls && statret == 0 && !ACL_READY(*sxp))
++                              get_acl(fname, sxp);
++#endif
++                      itemize(file, ndx, statret, sxp,
+                               ITEM_LOCAL_CHANGE | ITEM_XNAME_FOLLOWS, 0,
+                               realname);
+               }
+@@ -311,7 +320,7 @@ static int maybe_hard_link(struct file_s
+ /* Only called if FLAG_HLINKED is set and FLAG_HLINK_FIRST is not.  Returns:
+  * 0 = process the file, 1 = skip the file, -1 = error occurred. */
+ int hard_link_check(struct file_struct *file, int ndx, const char *fname,
+-                  int statret, STRUCT_STAT *stp, int itemizing,
 +                  int statret, statx *sxp, int itemizing,
 +                  int statret, statx *sxp, int itemizing,
-                   enum logcode code, int skip)
+                   enum logcode code)
  {
  {
- #ifdef SUPPORT_HARD_LINKS
-@@ -207,7 +212,7 @@ int hard_link_check(struct file_struct *
-                                                || st2.st_ino != st3.st_ino)
-                                                       continue;
-                                               statret = 1;
--                                              st = &st3;
-+                                              sxp->st = st3;
-                                               if (verbose < 2 || !stdout_format_has_i)
-                                                       itemizing = code = 0;
-                                               break;
-@@ -215,12 +220,16 @@ int hard_link_check(struct file_struct *
-                                       if (!unchanged_file(cmpbuf, file, &st3))
-                                               continue;
-                                       statret = 1;
--                                      st = &st3;
--                                      if (unchanged_attrs(file, &st3))
-+                                      sxp->st = st3;
+       STRUCT_STAT prev_st;
+@@ -362,18 +371,20 @@ int hard_link_check(struct file_struct *
+       if (statret < 0 && basis_dir[0] != NULL) {
+               /* If we match an alt-dest item, we don't output this as a change. */
+               char cmpbuf[MAXPATHLEN];
+-              STRUCT_STAT alt_st;
++              statx alt_sx;
+               int j = 0;
 +#ifdef SUPPORT_ACLS
 +#ifdef SUPPORT_ACLS
-+                                      if (preserve_acls)
-+                                              get_acl(cmpbuf, sxp);
++              alt_sx.acc_acl = alt_sx.def_acl = NULL;
 +#endif
 +#endif
-+                                      if (unchanged_attrs(file, sxp))
-                                               break;
-                               } while (basis_dir[++j] != NULL);
+               do {
+                       pathjoin(cmpbuf, MAXPATHLEN, basis_dir[j], fname);
+-                      if (link_stat(cmpbuf, &alt_st, 0) < 0)
++                      if (link_stat(cmpbuf, &alt_sx.st, 0) < 0)
+                               continue;
+                       if (link_dest) {
+-                              if (prev_st.st_dev != alt_st.st_dev
+-                               || prev_st.st_ino != alt_st.st_ino)
++                              if (prev_st.st_dev != alt_sx.st.st_dev
++                               || prev_st.st_ino != alt_sx.st.st_ino)
+                                       continue;
+                               statret = 1;
+-                              *stp = alt_st;
+                               if (verbose < 2 || !stdout_format_has_i) {
+                                       itemizing = 0;
+                                       code = FNONE;
+@@ -382,16 +393,36 @@ int hard_link_check(struct file_struct *
+                               }
+                               break;
                        }
                        }
--                      maybe_hard_link(file, ndx, fname, statret, st,
-+                      maybe_hard_link(file, ndx, fname, statret, sxp,
-                                       toname, &st2, itemizing, code);
-                       file->F_HLINDEX = FINISHED_LINK;
-               } else
-@@ -233,7 +242,7 @@ int hard_link_check(struct file_struct *
- #ifdef SUPPORT_HARD_LINKS
- int hard_link_one(struct file_struct *file, int ndx, char *fname,
--                int statret, STRUCT_STAT *st, char *toname, int terse,
-+                int statret, statx *sxp, char *toname, int terse,
-                 int itemizing, enum logcode code)
- {
-       if (do_link(toname, fname)) {
-@@ -249,7 +258,11 @@ int hard_link_one(struct file_struct *fi
-       }
-       if (itemizing) {
--              itemize(file, ndx, statret, st,
+-                      if (!unchanged_file(cmpbuf, file, &alt_st))
++                      if (!unchanged_file(cmpbuf, file, &alt_sx.st))
+                               continue;
+                       statret = 1;
+-                      *stp = alt_st;
+-                      if (unchanged_attrs(file, &alt_st))
++#ifdef SUPPORT_ACLS
++                      if (preserve_acls)
++                              get_acl(cmpbuf, &alt_sx);
++#endif
++                      if (unchanged_attrs(file, &alt_sx))
+                               break;
+               } while (basis_dir[++j] != NULL);
++              if (statret == 1) {
++                      sxp->st = alt_sx.st;
++#ifdef SUPPORT_ACLS
++                      if (preserve_acls) {
++                              if (!ACL_READY(*sxp))
++                                      get_acl(cmpbuf, sxp);
++                              else {
++                                      sxp->acc_acl = alt_sx.acc_acl;
++                                      sxp->def_acl = alt_sx.def_acl;
++                              }
++                      }
++#endif
++              }
 +#ifdef SUPPORT_ACLS
 +#ifdef SUPPORT_ACLS
-+              if (preserve_acls && statret == 0 && !ACL_READY(*sxp))
-+                      get_acl(fname, sxp);
++              else if (preserve_acls)
++                      free_acl(&alt_sx);
 +#endif
 +#endif
-+              itemize(file, ndx, statret, sxp,
-                       ITEM_LOCAL_CHANGE | ITEM_XNAME_FOLLOWS, 0,
-                       terse ? "" : toname);
        }
        }
-@@ -266,11 +279,12 @@ void hard_link_cluster(struct file_struc
- #ifdef SUPPORT_HARD_LINKS
-       char hlink1[MAXPATHLEN];
-       char *hlink2;
--      STRUCT_STAT st1, st2;
-+      statx sx;
+-      if (maybe_hard_link(file, ndx, fname, statret, stp, prev_name, &prev_st,
++      if (maybe_hard_link(file, ndx, fname, statret, sxp, prev_name, &prev_st,
+                           realname, itemizing, code) < 0)
+               return -1;
+@@ -426,7 +457,8 @@ void finish_hard_link(struct file_struct
+                     STRUCT_STAT *stp, int itemizing, enum logcode code,
+                     int alt_dest)
+ {
+-      STRUCT_STAT st, prev_st;
++      statx prev_sx;
 +      STRUCT_STAT st;
 +      STRUCT_STAT st;
-       int statret, ndx = master;
+       char alt_name[MAXPATHLEN], *prev_name;
+       const char *our_name;
+       int prev_statret, ndx, prev_ndx = F_HL_PREV(file);
+@@ -450,14 +482,24 @@ void finish_hard_link(struct file_struct
+       } else
+               our_name = fname;
  
  
-       file->F_HLINDEX = FINISHED_LINK;
--      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)) {
-@@ -284,9 +298,13 @@ void hard_link_cluster(struct file_struc
-               if (file->F_HLINDEX != SKIPPED_LINK)
-                       continue;
-               hlink2 = f_name(file, NULL);
--              statret = link_stat(hlink2, &st2, 0);
--              maybe_hard_link(file, ndx, hlink2, statret, &st2,
--                              hlink1, &st1, itemizing, code);
-+              statret = link_stat(hlink2, &sx.st, 0);
-+              maybe_hard_link(file, ndx, hlink2, statret, &sx,
-+                              hlink1, &st, itemizing, code);
++#ifdef SUPPORT_ACLS
++      prev_sx.acc_acl = prev_sx.def_acl = NULL;
++#endif
++
+       while ((ndx = prev_ndx) >= 0) {
++              int val;
+               file = FPTR(ndx);
+               file->flags = (file->flags & ~FLAG_HLINK_FIRST) | FLAG_HLINK_DONE;
+               prev_ndx = F_HL_PREV(file);
+               prev_name = f_name(file, NULL);
+-              prev_statret = link_stat(prev_name, &prev_st, 0);
+-              if (maybe_hard_link(file, ndx, prev_name, prev_statret, &prev_st,
+-                                  our_name, stp, fname, itemizing, code) < 0)
++              prev_statret = link_stat(prev_name, &prev_sx.st, 0);
++              val = maybe_hard_link(file, ndx, prev_name, prev_statret, &prev_sx,
++                                    our_name, stp, fname, itemizing, code);
 +#ifdef SUPPORT_ACLS
 +              if (preserve_acls)
 +#ifdef SUPPORT_ACLS
 +              if (preserve_acls)
-+                      free_acl(&sx);
++                      free_acl(&prev_sx);
 +#endif
 +#endif
-               file->F_HLINDEX = FINISHED_LINK;
-       } while (!(file->flags & FLAG_HLINK_EOL));
- #endif
++              if (val < 0)
+                       continue;
+               if (remove_source_files == 1 && do_xfers)
+                       send_msg_int(MSG_SUCCESS, ndx);
 --- old/lib/sysacls.c
 +++ new/lib/sysacls.c
 --- old/lib/sysacls.c
 +++ new/lib/sysacls.c
-@@ -0,0 +1,3240 @@
+@@ -0,0 +1,3251 @@
 +/* 
 +   Unix SMB/CIFS implementation.
 +   Samba system utilities for ACL support.
 +/* 
 +   Unix SMB/CIFS implementation.
 +   Samba system utilities for ACL support.
@@ -2250,7 +2334,14 @@ latest ACL-enabling patch to send files to an older ACL-enabled rsync.
 +#include "rsync.h"
 +#include "sysacls.h" /****** ADDED ******/
 +
 +#include "rsync.h"
 +#include "sysacls.h" /****** ADDED ******/
 +
++#ifdef SUPPORT_ACLS
++
 +/****** EXTRAS -- THESE ITEMS ARE NOT FROM THE SAMBA SOURCE ******/
 +/****** EXTRAS -- THESE ITEMS ARE NOT FROM THE SAMBA SOURCE ******/
++#ifdef DEBUG
++#undef DEBUG
++#endif
++#define DEBUG(x,y)
++
 +void SAFE_FREE(void *mem)
 +{
 +      if (mem)
 +void SAFE_FREE(void *mem)
 +{
 +      if (mem)
@@ -4526,8 +4617,10 @@ latest ACL-enabling patch to send files to an older ACL-enabled rsync.
 +      uid_t user_id;
 +
 +      /* AIX has no DEFAULT */
 +      uid_t user_id;
 +
 +      /* AIX has no DEFAULT */
-+      if  ( type == SMB_ACL_TYPE_DEFAULT )
++      if  ( type == SMB_ACL_TYPE_DEFAULT ) {
++              errno = ENOTSUP;
 +              return NULL;
 +              return NULL;
++      }
 +
 +      /* Get the acl using statacl */
 + 
 +
 +      /* Get the acl using statacl */
 + 
@@ -5467,12 +5560,19 @@ latest ACL-enabling patch to send files to an older ACL-enabled rsync.
 +#endif
 +      return 0;
 +}
 +#endif
 +      return 0;
 +}
++
++#endif /* SUPPORT_ACLS */
 --- old/lib/sysacls.h
 +++ new/lib/sysacls.h
 --- old/lib/sysacls.h
 +++ new/lib/sysacls.h
-@@ -0,0 +1,33 @@
-+#if defined SUPPORT_ACLS && defined HAVE_SYS_ACL_H
+@@ -0,0 +1,40 @@
++#ifdef SUPPORT_ACLS
++
++#ifdef HAVE_SYS_ACL_H
 +#include <sys/acl.h>
 +#endif
 +#include <sys/acl.h>
 +#endif
++#ifdef HAVE_ACL_LIBACL_H
++#include <acl/libacl.h>
++#endif
 +#include "smb_acls.h"
 +
 +#define SMB_MALLOC(cnt) new_array(char, cnt)
 +#include "smb_acls.h"
 +
 +#define SMB_MALLOC(cnt) new_array(char, cnt)
@@ -5503,32 +5603,23 @@ latest ACL-enabling patch to send files to an older ACL-enabled rsync.
 +int sys_acl_free_text(char *text);
 +int sys_acl_free_acl(SMB_ACL_T the_acl);
 +int sys_acl_free_qualifier(void *qual, SMB_ACL_TAG_T tagtype);
 +int sys_acl_free_text(char *text);
 +int sys_acl_free_acl(SMB_ACL_T the_acl);
 +int sys_acl_free_qualifier(void *qual, SMB_ACL_TAG_T tagtype);
++
++#endif /* SUPPORT_ACLS */
 --- old/log.c
 +++ new/log.c
 --- old/log.c
 +++ new/log.c
-@@ -582,8 +582,10 @@ static void log_formatted(enum logcode c
-                       n[5] = !(iflags & ITEM_REPORT_PERMS) ? '.' : 'p';
-                       n[6] = !(iflags & ITEM_REPORT_OWNER) ? '.' : 'o';
-                       n[7] = !(iflags & ITEM_REPORT_GROUP) ? '.' : 'g';
--                      n[8] = '.';
--                      n[9] = '\0';
-+                      n[8] = !(iflags & ITEM_REPORT_ATIME) ? '.' : 'u';
-+                      n[9] = !(iflags & ITEM_REPORT_ACL) ? '.' : 'a';
-+                      n[10] = !(iflags & ITEM_REPORT_XATTR) ? '.' : 'x';
-+                      n[11] = '\0';
+@@ -625,8 +625,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';
+-                      c[8] = '.';
+-                      c[9] = '\0';
++                      c[8] = !(iflags & ITEM_REPORT_ATIME) ? '.' : 'u';
++                      c[9] = !(iflags & ITEM_REPORT_ACL) ? '.' : 'a';
++                      c[10] = !(iflags & ITEM_REPORT_XATTR) ? '.' : 'x';
++                      c[11] = '\0';
  
                        if (iflags & (ITEM_IS_NEW|ITEM_MISSING_DATA)) {
                                char ch = iflags & ITEM_IS_NEW ? '+' : '?';
  
                        if (iflags & (ITEM_IS_NEW|ITEM_MISSING_DATA)) {
                                char ch = iflags & ITEM_IS_NEW ? '+' : '?';
---- old/mkproto.awk
-+++ new/mkproto.awk
-@@ -58,7 +58,7 @@ BEGIN {
-   next;
- }
--!/^OFF_T|^size_t|^off_t|^pid_t|^unsigned|^mode_t|^DIR|^user|^int|^char|^uint|^uchar|^short|^struct|^BOOL|^void|^time|^const|^RETSIGTYPE/ {
-+!/^OFF_T|^size_t|^off_t|^pid_t|^id_t|^unsigned|^mode_t|^DIR|^user|^int|^char|^uint|^uchar|^short|^struct|^BOOL|^void|^time|^const|^RETSIGTYPE/ {
-   next;
- }
 --- old/options.c
 +++ new/options.c
 @@ -47,6 +47,7 @@ int copy_dirlinks = 0;
 --- old/options.c
 +++ new/options.c
 @@ -47,6 +47,7 @@ int copy_dirlinks = 0;
@@ -5558,37 +5649,36 @@ latest ACL-enabling patch to send files to an older ACL-enabled rsync.
  #ifdef SUPPORT_LINKS
        links = "";
  #endif
  #ifdef SUPPORT_LINKS
        links = "";
  #endif
-@@ -227,9 +233,9 @@ static void print_rsync_version(enum log
-       rprintf(f, "Copyright (C) 1996-2006 by Andrew Tridgell, Wayne Davison, and others.\n");
-       rprintf(f, "<http://rsync.samba.org/>\n");
-       rprintf(f, "Capabilities: %d-bit files, %ssocketpairs, "
--              "%shard links, %ssymlinks, batchfiles,\n",
-+              "%shard links, %sACLs, %ssymlinks, batchfiles,\n",
-               (int) (sizeof (OFF_T) * 8),
--              got_socketpair, hardlinks, links);
-+              got_socketpair, hardlinks, acls, links);
+@@ -232,8 +238,8 @@ static void print_rsync_version(enum log
+               (int)(sizeof (int64) * 8));
+       rprintf(f, "    %ssocketpairs, %shardlinks, %ssymlinks, %sIPv6, batchfiles, %sinplace,\n",
+               got_socketpair, hardlinks, links, ipv6, have_inplace);
+-      rprintf(f, "    %sappend\n",
+-              have_inplace);
++      rprintf(f, "    %sappend, %sACLs\n",
++              have_inplace, acls);
  
  
-       /* Note that this field may not have type ino_t.  It depends
-        * on the complicated interaction between largefile feature
-@@ -282,7 +288,7 @@ void usage(enum logcode F)
-   rprintf(F," -v, --verbose               increase verbosity\n");
+ #ifdef MAINTAINER_MODE
+       rprintf(f, "Panic Action: \"%s\"\n", get_panic_action());
+@@ -279,7 +285,7 @@ void usage(enum logcode F)
    rprintf(F," -q, --quiet                 suppress non-error messages\n");
    rprintf(F," -q, --quiet                 suppress non-error messages\n");
+   rprintf(F,"     --no-motd               suppress daemon-mode MOTD (see manpage caveat)\n");
    rprintf(F," -c, --checksum              skip based on checksum, not mod-time & size\n");
 -  rprintf(F," -a, --archive               archive mode; same as -rlptgoD (no -H)\n");
 +  rprintf(F," -a, --archive               archive mode; same as -rlptgoD (no -H, -A)\n");
    rprintf(F,"     --no-OPTION             turn off an implied OPTION (e.g. --no-D)\n");
    rprintf(F," -r, --recursive             recurse into directories\n");
    rprintf(F," -R, --relative              use relative path names\n");
    rprintf(F," -c, --checksum              skip based on checksum, not mod-time & size\n");
 -  rprintf(F," -a, --archive               archive mode; same as -rlptgoD (no -H)\n");
 +  rprintf(F," -a, --archive               archive mode; same as -rlptgoD (no -H, -A)\n");
    rprintf(F,"     --no-OPTION             turn off an implied OPTION (e.g. --no-D)\n");
    rprintf(F," -r, --recursive             recurse into directories\n");
    rprintf(F," -R, --relative              use relative path names\n");
-@@ -303,6 +309,9 @@ void usage(enum logcode F)
-   rprintf(F," -H, --hard-links            preserve hard links\n");
+@@ -301,6 +307,9 @@ void usage(enum logcode F)
    rprintf(F," -p, --perms                 preserve permissions\n");
    rprintf(F," -E, --executability         preserve the file's executability\n");
    rprintf(F," -p, --perms                 preserve permissions\n");
    rprintf(F," -E, --executability         preserve the file's executability\n");
+   rprintf(F,"     --chmod=CHMOD           affect file and/or directory permissions\n");
 +#ifdef SUPPORT_ACLS
 +  rprintf(F," -A, --acls                  preserve ACLs (implies --perms)\n");
 +#endif
 +#ifdef SUPPORT_ACLS
 +  rprintf(F," -A, --acls                  preserve ACLs (implies --perms)\n");
 +#endif
-   rprintf(F,"     --chmod=CHMOD           change destination permissions\n");
    rprintf(F," -o, --owner                 preserve owner (super-user only)\n");
    rprintf(F," -g, --group                 preserve group\n");
    rprintf(F," -o, --owner                 preserve owner (super-user only)\n");
    rprintf(F," -g, --group                 preserve group\n");
+   rprintf(F,"     --devices               preserve device files (super-user only)\n");
 @@ -421,6 +430,9 @@ static struct poptOption long_options[] 
    {"no-perms",         0,  POPT_ARG_VAL,    &preserve_perms, 0, 0, 0 },
    {"no-p",             0,  POPT_ARG_VAL,    &preserve_perms, 0, 0, 0 },
 @@ -421,6 +430,9 @@ static struct poptOption long_options[] 
    {"no-perms",         0,  POPT_ARG_VAL,    &preserve_perms, 0, 0, 0 },
    {"no-p",             0,  POPT_ARG_VAL,    &preserve_perms, 0, 0, 0 },
@@ -5599,13 +5689,13 @@ latest ACL-enabling patch to send files to an older ACL-enabled rsync.
    {"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 },
    {"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 },
-@@ -1083,6 +1095,24 @@ int parse_arguments(int *argc, const cha
+@@ -1086,6 +1098,24 @@ int parse_arguments(int *argc, const cha
                        usage(FINFO);
                        exit_cleanup(0);
  
 +              case 'A':
 +#ifdef SUPPORT_ACLS
                        usage(FINFO);
                        exit_cleanup(0);
  
 +              case 'A':
 +#ifdef SUPPORT_ACLS
-+                      preserve_acls++;
++                      preserve_acls = 1;
 +                      preserve_perms = 1;
 +                      break;
 +#else
 +                      preserve_perms = 1;
 +                      break;
 +#else
@@ -5651,18 +5741,18 @@ latest ACL-enabling patch to send files to an older ACL-enabled rsync.
        int max_phase = protocol_version >= 29 ? 2 : 1;
 +      int dflt_perms = (ACCESSPERMS & ~orig_umask);
 +#ifdef SUPPORT_ACLS
        int max_phase = protocol_version >= 29 ? 2 : 1;
 +      int dflt_perms = (ACCESSPERMS & ~orig_umask);
 +#ifdef SUPPORT_ACLS
-+      char *parent_dirname = "";
++      const char *parent_dirname = "";
 +#endif
 +#endif
-       int i, recv_ok;
+       int ndx, recv_ok;
  
        if (verbose > 2)
  
        if (verbose > 2)
-@@ -543,7 +548,16 @@ int recv_files(int f_in, struct file_lis
+@@ -545,7 +550,16 @@ int recv_files(int f_in, struct file_lis
                 * mode based on the local permissions and some heuristics. */
                if (!preserve_perms) {
                        int exists = fd1 != -1;
 -                      file->mode = dest_mode(file->mode, st.st_mode, exists);
 +#ifdef SUPPORT_ACLS
                 * mode based on the local permissions and some heuristics. */
                if (!preserve_perms) {
                        int exists = fd1 != -1;
 -                      file->mode = dest_mode(file->mode, st.st_mode, exists);
 +#ifdef SUPPORT_ACLS
-+                      char *dn = file->dirname ? file->dirname : ".";
++                      const char *dn = file->dirname ? file->dirname : ".";
 +                      if (parent_dirname != dn
 +                       && strcmp(parent_dirname, dn) != 0) {
 +                              dflt_perms = default_perms_for_dir(dn);
 +                      if (parent_dirname != dn
 +                       && strcmp(parent_dirname, dn) != 0) {
 +                              dflt_perms = default_perms_for_dir(dn);
@@ -5673,7 +5763,7 @@ latest ACL-enabling patch to send files to an older ACL-enabled rsync.
 +                                             dflt_perms, exists);
                }
  
 +                                             dflt_perms, exists);
                }
  
-               /* We now check to see if we are writing file "inplace" */
+               /* We now check to see if we are writing the file "inplace" */
 --- old/rsync.c
 +++ new/rsync.c
 @@ -32,6 +32,7 @@
 --- old/rsync.c
 +++ new/rsync.c
 @@ -32,6 +32,7 @@
@@ -5684,25 +5774,35 @@ 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;
  extern int preserve_perms;
  extern int preserve_executability;
  extern int preserve_times;
-@@ -100,7 +101,8 @@ void free_sums(struct sum_struct *s)
+@@ -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;
+@@ -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. */
  
  /* 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. */
--mode_t dest_mode(mode_t flist_mode, mode_t cur_mode, int exists)
-+mode_t dest_mode(mode_t flist_mode, mode_t cur_mode, int dflt_perms,
+-mode_t dest_mode(mode_t flist_mode, mode_t stat_mode, int exists)
++mode_t dest_mode(mode_t flist_mode, mode_t stat_mode, int dflt_perms,
 +               int exists)
  {
 +               int exists)
  {
+       int new_mode;
        /* If the file already exists, we'll return the local permissions,
        /* If the file already exists, we'll return the local permissions,
-        * possibly tweaked by the --executability option. */
-@@ -115,55 +117,63 @@ mode_t dest_mode(mode_t flist_mode, mode
-                               cur_mode |= (cur_mode & 0444) >> 2;
+@@ -170,56 +171,65 @@ mode_t dest_mode(mode_t flist_mode, mode
+                               new_mode |= (new_mode & 0444) >> 2;
                }
                }
-       } else
--              cur_mode = flist_mode & ACCESSPERMS & ~orig_umask;
-+              cur_mode = flist_mode & ACCESSPERMS & dflt_perms;
-       if (daemon_chmod_modes && !S_ISLNK(flist_mode))
-               cur_mode = tweak_mode(cur_mode, daemon_chmod_modes);
-       return (flist_mode & ~CHMOD_BITS) | (cur_mode & CHMOD_BITS);
+       } else {
+-              /* Apply the umask and turn off special permissions. */
+-              new_mode = flist_mode & (~CHMOD_BITS | (ACCESSPERMS & ~orig_umask));
++              /* Apply destination default permissions and turn
++               * off special permissions. */
++              new_mode = flist_mode & (~CHMOD_BITS | dflt_perms);
+       }
+       return new_mode;
  }
  
 -int set_file_attrs(char *fname, struct file_struct *file, STRUCT_STAT *st,
  }
  
 -int set_file_attrs(char *fname, struct file_struct *file, STRUCT_STAT *st,
@@ -5713,6 +5813,7 @@ latest ACL-enabling patch to send files to an older ACL-enabled rsync.
 -      STRUCT_STAT st2;
 +      statx sx2;
        int change_uid, change_gid;
 -      STRUCT_STAT st2;
 +      statx sx2;
        int change_uid, change_gid;
+       mode_t new_mode = file->mode;
  
 -      if (!st) {
 +      if (!sxp) {
  
 -      if (!st) {
 +      if (!sxp) {
@@ -5728,12 +5829,12 @@ latest ACL-enabling patch to send files to an older ACL-enabled rsync.
 +#ifdef SUPPORT_ACLS
 +              sx2.acc_acl = sx2.def_acl = NULL;
 +#endif
 +#ifdef SUPPORT_ACLS
 +              sx2.acc_acl = sx2.def_acl = NULL;
 +#endif
-               if (!preserve_perms && S_ISDIR(file->mode)
+               if (!preserve_perms && S_ISDIR(new_mode)
 -               && st->st_mode & S_ISGID) {
 +               && sx2.st.st_mode & S_ISGID) {
                        /* We just created this directory and its setgid
                         * bit is on, so make sure it stays on. */
 -               && st->st_mode & S_ISGID) {
 +               && sx2.st.st_mode & S_ISGID) {
                        /* We just created this directory and its setgid
                         * bit is on, so make sure it stays on. */
-                       file->mode |= S_ISGID;
+                       new_mode |= S_ISGID;
                }
 +              sxp = &sx2;
        }
                }
 +              sxp = &sx2;
        }
@@ -5761,37 +5862,37 @@ latest ACL-enabling patch to send files to an older ACL-enabled rsync.
                        updated = 1;
        }
  
                        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
  #if !defined HAVE_LCHOWN && !defined CHOWN_MODIFIES_SYMLINK
 -      if (S_ISLNK(st->st_mode))
 +      if (S_ISLNK(sxp->st.st_mode))
                ;
        else
  #endif
-@@ -173,43 +183,55 @@ 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,
                                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,
                        }
                        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,
                        }
                }
                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",
                        /* shouldn't have attempted to change uid or gid
                         * unless have the privilege */
                        rsyserr(FERROR, errno, "%s %s failed",
@@ -5813,6 +5914,9 @@ latest ACL-enabling patch to send files to an older ACL-enabled rsync.
                updated = 1;
        }
  
                updated = 1;
        }
  
+       if (daemon_chmod_modes && !S_ISLNK(new_mode))
+               new_mode = tweak_mode(new_mode, daemon_chmod_modes);
++
 +#ifdef SUPPORT_ACLS
 +      /* It's OK to call set_acl() now, even for a dir, as the generator
 +       * will enable owner-writability using chmod, if necessary.
 +#ifdef SUPPORT_ACLS
 +      /* It's OK to call set_acl() now, even for a dir, as the generator
 +       * will enable owner-writability using chmod, if necessary.
@@ -5825,11 +5929,9 @@ latest ACL-enabling patch to send files to an older ACL-enabled rsync.
 +#endif
 +
  #ifdef HAVE_CHMOD
 +#endif
 +
  #ifdef HAVE_CHMOD
--      if ((st->st_mode & CHMOD_BITS) != (file->mode & CHMOD_BITS)) {
--              int ret = do_chmod(fname, file->mode);
-+      if ((sxp->st.st_mode & CHMOD_BITS) != (file->mode & CHMOD_BITS)) {
-+              mode_t mode = file->mode;
-+              int ret = do_chmod(fname, mode);
+-      if (!BITS_EQUAL(st->st_mode, new_mode, CHMOD_BITS)) {
++      if (!BITS_EQUAL(sxp->st.st_mode, new_mode, CHMOD_BITS)) {
+               int ret = do_chmod(fname, new_mode);
                if (ret < 0) {
                        rsyserr(FERROR, errno,
                                "failed to set permissions on %s",
                if (ret < 0) {
                        rsyserr(FERROR, errno,
                                "failed to set permissions on %s",
@@ -5839,7 +5941,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;
                }
                if (ret == 0) /* ret == 1 if symlink could not be set */
                        updated = 1;
-@@ -222,6 +244,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);
        }
                else
                        rprintf(FCLIENT, "%s is uptodate\n", fname);
        }
@@ -5853,12 +5955,11 @@ latest ACL-enabling patch to send files to an older ACL-enabled rsync.
  
 --- old/rsync.h
 +++ new/rsync.h
  
 --- old/rsync.h
 +++ new/rsync.h
-@@ -486,6 +486,15 @@ struct idev {
+@@ -532,6 +532,14 @@ struct idev_node {
  #define IN_LOOPBACKNET 127
  #endif
  
  #define IN_LOOPBACKNET 127
  #endif
  
-+#if HAVE_POSIX_ACLS|HAVE_UNIXWARE_ACLS|HAVE_SOLARIS_ACLS|\
-+    HAVE_HPUX_ACLS|HAVE_IRIX_ACLS|HAVE_AIX_ACLS|HAVE_TRU64_ACLS
++#ifndef HAVE_NO_ACLS
 +#define SUPPORT_ACLS 1
 +#endif
 +
 +#define SUPPORT_ACLS 1
 +#endif
 +
@@ -5868,8 +5969,29 @@ latest ACL-enabling patch to send files to an older ACL-enabled rsync.
 +
  #define GID_NONE ((gid_t)-1)
  
 +
  #define GID_NONE ((gid_t)-1)
  
- #define HL_CHECK_MASTER       0
-@@ -646,6 +655,17 @@ struct stats {
+ union file_extras {
+@@ -551,6 +559,7 @@ struct file_struct {
+ extern int file_extra_cnt;
+ extern int preserve_uid;
+ extern int preserve_gid;
++extern int preserve_acls;
+ #define FILE_STRUCT_LEN (offsetof(struct file_struct, basename))
+ #define EXTRA_LEN (sizeof (union file_extras))
+@@ -583,10 +592,12 @@ extern int preserve_gid;
+ /* When the associated option is on, all entries will have these present: */
+ #define F_UID(f) REQ_EXTRA(f, preserve_uid)->unum
+ #define F_GID(f) REQ_EXTRA(f, preserve_gid)->unum
++#define F_ACL(f) REQ_EXTRA(f, preserve_acls)->unum
+ /* These items are per-entry optional and mutally exclusive: */
+ #define F_HL_GNUM(f) OPT_EXTRA(f, LEN64_BUMP(f))->num
+ #define F_HL_PREV(f) OPT_EXTRA(f, LEN64_BUMP(f))->num
++#define F_DEF_ACL(f) OPT_EXTRA(f, LEN64_BUMP(f))->unum
+ /* This optional item might follow an F_HL_*() item.
+  * (Note: a device doesn't need to check LEN64_BUMP(f).) */
+@@ -722,6 +733,17 @@ struct stats {
  
  struct chmod_mode_struct;
  
  
  struct chmod_mode_struct;
  
@@ -5887,9 +6009,9 @@ latest ACL-enabling patch to send files to an older ACL-enabled rsync.
  #include "byteorder.h"
  #include "lib/mdfour.h"
  #include "lib/wildmatch.h"
  #include "byteorder.h"
  #include "lib/mdfour.h"
  #include "lib/wildmatch.h"
-@@ -661,6 +681,16 @@ struct chmod_mode_struct;
- #define UNUSED(x) x __attribute__((__unused__))
+@@ -740,6 +762,16 @@ struct chmod_mode_struct;
+ #define NORETURN __attribute__((__noreturn__))
+ #endif
  
 +typedef struct {
 +    STRUCT_STAT st;
  
 +typedef struct {
 +    STRUCT_STAT st;
@@ -5906,24 +6028,24 @@ latest ACL-enabling patch to send files to an older ACL-enabled rsync.
  /* We have replacement versions of these if they're missing. */
 --- old/rsync.yo
 +++ new/rsync.yo
  /* We have replacement versions of these if they're missing. */
 --- old/rsync.yo
 +++ new/rsync.yo
-@@ -300,7 +300,7 @@ to the detailed description below for a 
-  -v, --verbose               increase verbosity
+@@ -301,7 +301,7 @@ to the detailed description below for a 
   -q, --quiet                 suppress non-error messages
   -q, --quiet                 suppress non-error messages
+      --no-motd               suppress daemon-mode MOTD (see caveat)
   -c, --checksum              skip based on checksum, not mod-time & size
 - -a, --archive               archive mode; same as -rlptgoD (no -H)
 + -a, --archive               archive mode; same as -rlptgoD (no -H, -A)
       --no-OPTION             turn off an implied OPTION (e.g. --no-D)
   -r, --recursive             recurse into directories
   -R, --relative              use relative path names
   -c, --checksum              skip based on checksum, not mod-time & size
 - -a, --archive               archive mode; same as -rlptgoD (no -H)
 + -a, --archive               archive mode; same as -rlptgoD (no -H, -A)
       --no-OPTION             turn off an implied OPTION (e.g. --no-D)
   -r, --recursive             recurse into directories
   -R, --relative              use relative path names
-@@ -321,6 +321,7 @@ to the detailed description below for a 
-  -H, --hard-links            preserve hard links
+@@ -323,6 +323,7 @@ to the detailed description below for a 
   -p, --perms                 preserve permissions
   -E, --executability         preserve executability
   -p, --perms                 preserve permissions
   -E, --executability         preserve executability
+      --chmod=CHMOD           affect file and/or directory permissions
 + -A, --acls                  preserve ACLs (implies -p) [non-standard]
 + -A, --acls                  preserve ACLs (implies -p) [non-standard]
-      --chmod=CHMOD           change destination permissions
   -o, --owner                 preserve owner (super-user only)
   -g, --group                 preserve group
   -o, --owner                 preserve owner (super-user only)
   -g, --group                 preserve group
-@@ -746,7 +747,9 @@ quote(itemize(
+      --devices               preserve device files (super-user only)
+@@ -754,7 +755,9 @@ quote(itemization(
    permissions, though the bf(--executability) option might change just
    the execute permission for the file.
    it() New files get their "normal" permission bits set to the source
    permissions, though the bf(--executability) option might change just
    the execute permission for the file.
    it() New files get their "normal" permission bits set to the source
@@ -5934,7 +6056,7 @@ latest ACL-enabling patch to send files to an older ACL-enabled rsync.
    their special permission bits disabled except in the case where a new
    directory inherits a setgid bit from its parent directory.
  ))
    their special permission bits disabled except in the case where a new
    directory inherits a setgid bit from its parent directory.
  ))
-@@ -777,9 +780,11 @@ The preservation of the destination's se
+@@ -785,9 +788,11 @@ The preservation of the destination's se
  directories when bf(--perms) is off was added in rsync 2.6.7.  Older rsync
  versions erroneously preserved the three special permission bits for
  newly-created files when bf(--perms) was off, while overriding the
  directories when bf(--perms) is off was added in rsync 2.6.7.  Older rsync
  versions erroneously preserved the three special permission bits for
  newly-created files when bf(--perms) was off, while overriding the
@@ -5949,7 +6071,7 @@ latest ACL-enabling patch to send files to an older ACL-enabled rsync.
  
  dit(bf(-E, --executability)) This option causes rsync to preserve the
  executability (or non-executability) of regular files when bf(--perms) is
  
  dit(bf(-E, --executability)) This option causes rsync to preserve the
  executability (or non-executability) of regular files when bf(--perms) is
-@@ -797,6 +802,15 @@ quote(itemize(
+@@ -805,6 +810,14 @@ quote(itemization(
  
  If bf(--perms) is enabled, this option is ignored.
  
  
  If bf(--perms) is enabled, this option is ignored.
  
@@ -5957,15 +6079,14 @@ latest ACL-enabling patch to send files to an older ACL-enabled rsync.
 +ACLs to be the same as the source ACLs.  This nonstandard option only
 +works if the remote rsync also supports it.  bf(--acls) implies bf(--perms).
 +
 +ACLs to be the same as the source ACLs.  This nonstandard option only
 +works if the remote rsync also supports it.  bf(--acls) implies bf(--perms).
 +
-+Note also that an optimization of the ACL-sending protocol used by this
-+version makes it incompatible with sending files to an older ACL-enabled
-+rsync unless you double the bf(--acls) option (e.g. bf(-AA)).  This
-+doubling is not needed when pulling files from an older rsync.
++The ACL-sending protocol used by this version was first introduced in
++the patch that was shipped with 2.6.8.  Sending ACLs to an older version
++of the ACL patch is not supported.
 +
  dit(bf(--chmod)) This option tells rsync to apply one or more
  comma-separated "chmod" strings to the permission of the files in the
  transfer.  The resulting value is treated as though it was the permissions
 +
  dit(bf(--chmod)) This option tells rsync to apply one or more
  comma-separated "chmod" strings to the permission of the files in the
  transfer.  The resulting value is treated as though it was the permissions
-@@ -1378,8 +1392,8 @@ if the receiving rsync is at least versi
+@@ -1402,8 +1415,8 @@ if the receiving rsync is at least versi
  with older versions of rsync, but that also turns on the output of other
  verbose messages).
  
  with older versions of rsync, but that also turns on the output of other
  verbose messages).
  
@@ -5976,7 +6097,7 @@ latest ACL-enabling patch to send files to an older ACL-enabled rsync.
  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.
  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.
-@@ -1428,7 +1442,11 @@ quote(itemize(
+@@ -1452,7 +1465,11 @@ 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).
    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).
@@ -6273,16 +6394,6 @@ latest ACL-enabling patch to send files to an older ACL-enabled rsync.
 +
 +#endif /* No ACLs. */
 +#endif /* _SMB_ACLS_H */
 +
 +#endif /* No ACLs. */
 +#endif /* _SMB_ACLS_H */
---- old/t_stub.c
-+++ new/t_stub.c
-@@ -79,3 +79,7 @@ struct filter_list_struct server_filter_
-     return NULL;
- }
-+ const char *who_am_i(void)
-+{
-+    return "test";
-+}
 --- old/testsuite/acls.test
 +++ new/testsuite/acls.test
 @@ -0,0 +1,34 @@
 --- old/testsuite/acls.test
 +++ new/testsuite/acls.test
 @@ -0,0 +1,34 @@
@@ -6422,7 +6533,7 @@ latest ACL-enabling patch to send files to an older ACL-enabled rsync.
  cat <<EOT >"$chkfile"
 -.d..t.... ./
 -cD..t.... block
  cat <<EOT >"$chkfile"
 -.d..t.... ./
 -cD..t.... block
--cD....... block2
+-cD        block2
 -cD+++++++ block3
 -hD+++++++ block2.5 => block3
 -cD+++++++ char
 -cD+++++++ block3
 -hD+++++++ block2.5 => block3
 -cD+++++++ char
@@ -6431,7 +6542,7 @@ latest ACL-enabling patch to send files to an older ACL-enabled rsync.
 -cS+++++++ fifo
 +.d..t...... ./
 +cD..t...... block
 -cS+++++++ fifo
 +.d..t...... ./
 +cD..t...... block
-+cD......... block2
++cD          block2
 +cD+++++++++ block3
 +hD+++++++++ block2.5 => block3
 +cD+++++++++ char
 +cD+++++++++ block3
 +hD+++++++++ block2.5 => block3
 +cD+++++++++ char
@@ -6441,12 +6552,38 @@ latest ACL-enabling patch to send files to an older ACL-enabled rsync.
  EOT
  if test ! -b "$fromdir/block2.5"; then
      sed -e '/block2\.5/d' \
  EOT
  if test ! -b "$fromdir/block2.5"; then
      sed -e '/block2\.5/d' \
+@@ -94,15 +94,15 @@ if test -b "$fromdir/block2.5"; then
+     $RSYNC -aii --link-dest="$todir" "$fromdir/" "$chkdir/" \
+       | tee "$outfile"
+     cat <<EOT >"$chkfile"
+-cd        ./
+-hD        block
+-hD        block2
+-hD        block2.5
+-hD        block3
+-hD        char
+-hD        char2
+-hD        char3
+-hS        fifo
++cd          ./
++hD          block
++hD          block2
++hD          block2.5
++hD          block3
++hD          char
++hD          char2
++hD          char3
++hS          fifo
+ EOT
+     diff $diffopt "$chkfile" "$outfile" || test_fail "test 4 failed"
+ fi
 --- old/testsuite/itemize.test
 +++ new/testsuite/itemize.test
 --- old/testsuite/itemize.test
 +++ new/testsuite/itemize.test
-@@ -29,14 +29,14 @@ ln "$fromdir/foo/config1" "$fromdir/foo/
+@@ -38,15 +38,15 @@ rm -f "$to2dir" "$to2dir.test"
  $RSYNC -iplr "$fromdir/" "$todir/" \
      | tee "$outfile"
  cat <<EOT >"$chkfile"
  $RSYNC -iplr "$fromdir/" "$todir/" \
      | tee "$outfile"
  cat <<EOT >"$chkfile"
+-cd+++++++ ./
 -cd+++++++ bar/
 -cd+++++++ bar/baz/
 ->f+++++++ bar/baz/rsync
 -cd+++++++ bar/
 -cd+++++++ bar/baz/
 ->f+++++++ bar/baz/rsync
@@ -6455,6 +6592,7 @@ latest ACL-enabling patch to send files to an older ACL-enabled rsync.
 ->f+++++++ foo/config2
 ->f+++++++ foo/extra
 -cL+++++++ foo/sym -> ../bar/baz/rsync
 ->f+++++++ foo/config2
 ->f+++++++ foo/extra
 -cL+++++++ foo/sym -> ../bar/baz/rsync
++cd+++++++++ ./
 +cd+++++++++ bar/
 +cd+++++++++ bar/baz/
 +>f+++++++++ bar/baz/rsync
 +cd+++++++++ bar/
 +cd+++++++++ bar/baz/
 +>f+++++++++ bar/baz/rsync
@@ -6466,7 +6604,7 @@ latest ACL-enabling patch to send files to an older ACL-enabled rsync.
  EOT
  diff $diffopt "$chkfile" "$outfile" || test_fail "test 1 failed"
  
  EOT
  diff $diffopt "$chkfile" "$outfile" || test_fail "test 1 failed"
  
-@@ -48,10 +48,10 @@ chmod 601 "$fromdir/foo/config2"
+@@ -58,10 +58,10 @@ chmod 601 "$fromdir/foo/config2"
  $RSYNC -iplrH "$fromdir/" "$todir/" \
      | tee "$outfile"
  cat <<EOT >"$chkfile"
  $RSYNC -iplrH "$fromdir/" "$todir/" \
      | tee "$outfile"
  cat <<EOT >"$chkfile"
@@ -6481,7 +6619,7 @@ latest ACL-enabling patch to send files to an older ACL-enabled rsync.
  EOT
  diff $diffopt "$chkfile" "$outfile" || test_fail "test 2 failed"
  
  EOT
  diff $diffopt "$chkfile" "$outfile" || test_fail "test 2 failed"
  
-@@ -68,11 +68,11 @@ chmod 777 "$todir/bar/baz/rsync"
+@@ -78,11 +78,11 @@ chmod 777 "$todir/bar/baz/rsync"
  $RSYNC -iplrtc "$fromdir/" "$todir/" \
      | tee "$outfile"
  cat <<EOT >"$chkfile"
  $RSYNC -iplrtc "$fromdir/" "$todir/" \
      | tee "$outfile"
  cat <<EOT >"$chkfile"
@@ -6498,7 +6636,7 @@ latest ACL-enabling patch to send files to an older ACL-enabled rsync.
  EOT
  diff $diffopt "$chkfile" "$outfile" || test_fail "test 3 failed"
  
  EOT
  diff $diffopt "$chkfile" "$outfile" || test_fail "test 3 failed"
  
-@@ -97,15 +97,15 @@ $RSYNC -ivvplrtH "$fromdir/" "$todir/" \
+@@ -107,15 +107,15 @@ $RSYNC -ivvplrtH "$fromdir/" "$todir/" \
      | tee "$outfile"
  filter_outfile
  cat <<EOT >"$chkfile"
      | tee "$outfile"
  filter_outfile
  cat <<EOT >"$chkfile"
@@ -6523,7 +6661,7 @@ latest ACL-enabling patch to send files to an older ACL-enabled rsync.
  EOT
  diff $diffopt "$chkfile" "$outfile" || test_fail "test 5 failed"
  
  EOT
  diff $diffopt "$chkfile" "$outfile" || test_fail "test 5 failed"
  
-@@ -124,8 +124,8 @@ touch "$todir/foo/config2"
+@@ -134,8 +134,8 @@ touch "$todir/foo/config2"
  $RSYNC -iplrtH "$fromdir/" "$todir/" \
      | tee "$outfile"
  cat <<EOT >"$chkfile"
  $RSYNC -iplrtH "$fromdir/" "$todir/" \
      | tee "$outfile"
  cat <<EOT >"$chkfile"
@@ -6534,123 +6672,87 @@ latest ACL-enabling patch to send files to an older ACL-enabled rsync.
  EOT
  diff $diffopt "$chkfile" "$outfile" || test_fail "test 7 failed"
  
  EOT
  diff $diffopt "$chkfile" "$outfile" || test_fail "test 7 failed"
  
-@@ -134,15 +134,15 @@ $RSYNC -ivvplrtH --copy-dest="$lddir" "$
+@@ -143,15 +143,15 @@ $RSYNC -ivvplrtH --copy-dest=../to "$fro
      | tee "$outfile"
  filter_outfile
  cat <<EOT >"$chkfile"
      | tee "$outfile"
  filter_outfile
  cat <<EOT >"$chkfile"
--.d..t.... ./
--cd+++++++ bar/
--cd+++++++ bar/baz/
+-cd        ./
+-cd        bar/
+-cd        bar/baz/
 -cf        bar/baz/rsync
 -cf        bar/baz/rsync
--cd+++++++ foo/
+-cd        foo/
 -cf        foo/config1
 -cf        foo/config2
 -hf        foo/extra => foo/config1
 -cf        foo/config1
 -cf        foo/config2
 -hf        foo/extra => foo/config1
--cL..T.... foo/sym -> ../bar/baz/rsync
-+.d..t...... ./
-+cd+++++++++ bar/
-+cd+++++++++ bar/baz/
+-cL        foo/sym -> ../bar/baz/rsync
++cd          ./
++cd          bar/
++cd          bar/baz/
 +cf          bar/baz/rsync
 +cf          bar/baz/rsync
-+cd+++++++++ foo/
++cd          foo/
 +cf          foo/config1
 +cf          foo/config2
 +hf          foo/extra => foo/config1
 +cf          foo/config1
 +cf          foo/config2
 +hf          foo/extra => foo/config1
-+cL..T...... foo/sym -> ../bar/baz/rsync
++cL          foo/sym -> ../bar/baz/rsync
  EOT
  diff $diffopt "$chkfile" "$outfile" || test_fail "test 8 failed"
  
  EOT
  diff $diffopt "$chkfile" "$outfile" || test_fail "test 8 failed"
  
-@@ -150,11 +150,11 @@ rm -rf "$todir"
- $RSYNC -iplrtH --copy-dest="$lddir" "$fromdir/" "$todir/" \
+@@ -159,7 +159,7 @@ rm -rf "$to2dir"
+ $RSYNC -iplrtH --copy-dest=../to "$fromdir/" "$to2dir/" \
      | tee "$outfile"
  cat <<EOT >"$chkfile"
      | tee "$outfile"
  cat <<EOT >"$chkfile"
--.d..t.... ./
--cd+++++++ bar/
--cd+++++++ bar/baz/
--cd+++++++ foo/
 -hf        foo/extra => foo/config1
 -hf        foo/extra => foo/config1
-+.d..t...... ./
-+cd+++++++++ bar/
-+cd+++++++++ bar/baz/
-+cd+++++++++ foo/
 +hf          foo/extra => foo/config1
  EOT
  diff $diffopt "$chkfile" "$outfile" || test_fail "test 9 failed"
  
 +hf          foo/extra => foo/config1
  EOT
  diff $diffopt "$chkfile" "$outfile" || test_fail "test 9 failed"
  
-@@ -181,15 +181,15 @@ $RSYNC -ivvplrtH --link-dest="$lddir" "$
+@@ -185,15 +185,15 @@ $RSYNC -ivvplrtH --link-dest="$todir" "$
      | tee "$outfile"
  filter_outfile
  cat <<EOT >"$chkfile"
      | tee "$outfile"
  filter_outfile
  cat <<EOT >"$chkfile"
--.d..t.... ./
--cd+++++++ bar/
--cd+++++++ bar/baz/
+-cd        ./
+-cd        bar/
+-cd        bar/baz/
 -hf        bar/baz/rsync
 -hf        bar/baz/rsync
--cd+++++++ foo/
+-cd        foo/
 -hf        foo/config1
 -hf        foo/config2
 -hf        foo/extra => foo/config1
 -hf        foo/config1
 -hf        foo/config2
 -hf        foo/extra => foo/config1
--hL        foo/sym -> ../bar/baz/rsync
-+.d..t...... ./
-+cd+++++++++ bar/
-+cd+++++++++ bar/baz/
+-$L        foo/sym -> ../bar/baz/rsync
++cd          ./
++cd          bar/
++cd          bar/baz/
 +hf          bar/baz/rsync
 +hf          bar/baz/rsync
-+cd+++++++++ foo/
++cd          foo/
 +hf          foo/config1
 +hf          foo/config2
 +hf          foo/extra => foo/config1
 +hf          foo/config1
 +hf          foo/config2
 +hf          foo/extra => foo/config1
-+hL          foo/sym -> ../bar/baz/rsync
++$L          foo/sym -> ../bar/baz/rsync
  EOT
  diff $diffopt "$chkfile" "$outfile" || test_fail "test 11 failed"
  
  EOT
  diff $diffopt "$chkfile" "$outfile" || test_fail "test 11 failed"
  
-@@ -197,10 +197,10 @@ rm -rf "$todir"
- $RSYNC -iplrtH --link-dest="$lddir" "$fromdir/" "$todir/" \
+@@ -233,15 +233,15 @@ $RSYNC -ivvplrtH --compare-dest="$todir"
      | tee "$outfile"
      | tee "$outfile"
+ filter_outfile
  cat <<EOT >"$chkfile"
  cat <<EOT >"$chkfile"
--.d..t.... ./
--cd+++++++ bar/
--cd+++++++ bar/baz/
--cd+++++++ foo/
-+.d..t...... ./
-+cd+++++++++ bar/
-+cd+++++++++ bar/baz/
-+cd+++++++++ foo/
- EOT
- diff $diffopt "$chkfile" "$outfile" || test_fail "test 12 failed"
-@@ -228,14 +228,14 @@ filter_outfile
- # TODO fix really-old problem when combining -H with --compare-dest:
- # missing output for foo/extra hard-link (and it might not be updated)!
- cat <<EOT >"$chkfile"
--.d..t.... ./
--cd+++++++ bar/
--cd+++++++ bar/baz/
+-cd        ./
+-cd        bar/
+-cd        bar/baz/
 -.f        bar/baz/rsync
 -.f        bar/baz/rsync
--cd+++++++ foo/
+-cd        foo/
 -.f        foo/config1
 -.f        foo/config2
 -.f        foo/config1
 -.f        foo/config2
+-.f        foo/extra
 -.L        foo/sym -> ../bar/baz/rsync
 -.L        foo/sym -> ../bar/baz/rsync
-+.d..t...... ./
-+cd+++++++++ bar/
-+cd+++++++++ bar/baz/
++cd          ./
++cd          bar/
++cd          bar/baz/
 +.f          bar/baz/rsync
 +.f          bar/baz/rsync
-+cd+++++++++ foo/
++cd          foo/
 +.f          foo/config1
 +.f          foo/config2
 +.f          foo/config1
 +.f          foo/config2
++.f          foo/extra
 +.L          foo/sym -> ../bar/baz/rsync
 +.L          foo/sym -> ../bar/baz/rsync
- EOT
- diff $diffopt "$chkfile" "$outfile" || test_fail "test 14 failed"
-@@ -243,10 +243,10 @@ rm -rf "$todir"
- $RSYNC -iplrtH --compare-dest="$lddir" "$fromdir/" "$todir/" \
-     | tee "$outfile"
- cat <<EOT >"$chkfile"
--.d..t.... ./
--cd+++++++ bar/
--cd+++++++ bar/baz/
--cd+++++++ foo/
-+.d..t...... ./
-+cd+++++++++ bar/
-+cd+++++++++ bar/baz/
-+cd+++++++++ foo/
  EOT
  diff $diffopt "$chkfile" "$outfile" || test_fail "test 15 failed"
  
  EOT
  diff $diffopt "$chkfile" "$outfile" || test_fail "test 15 failed"
  
@@ -6664,16 +6766,16 @@ latest ACL-enabling patch to send files to an older ACL-enabled rsync.
  extern int numeric_ids;
  extern int am_root;
  
  extern int numeric_ids;
  extern int am_root;
  
-@@ -275,7 +276,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) {
  
 -      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) {
-@@ -292,7 +293,7 @@ void send_uid_list(int f)
+@@ -287,7 +288,7 @@ void send_uid_list(int f)
                write_int(f, 0);
        }
  
                write_int(f, 0);
        }
  
@@ -6682,7 +6784,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)
                int len;
                for (list = gidlist; list; list = list->next) {
                        if (!list->name)
-@@ -313,7 +314,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;
  
        int id, i;
        char *name;
  
@@ -6691,7 +6793,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);
                /* read the uid list */
                while ((id = read_int(f)) != 0) {
                        int len = read_byte(f);
-@@ -325,7 +326,7 @@ void recv_uid_list(int f, struct file_li
+@@ -320,7 +321,7 @@ void recv_uid_list(int f, struct file_li
                }
        }
  
                }
        }
  
@@ -6700,7 +6802,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);
                /* read the gid list */
                while ((id = read_int(f)) != 0) {
                        int len = read_byte(f);
-@@ -337,6 +338,16 @@ void recv_uid_list(int f, struct file_li
+@@ -332,6 +333,16 @@ void recv_uid_list(int f, struct file_li
                }
        }
  
                }
        }
  
@@ -6719,7 +6821,7 @@ latest ACL-enabling patch to send files to an older ACL-enabled rsync.
                for (i = 0; i < flist->count; i++)
 --- old/util.c
 +++ new/util.c
                for (i = 0; i < flist->count; i++)
 --- old/util.c
 +++ new/util.c
-@@ -1555,3 +1555,31 @@ int bitbag_next_bit(struct bitbag *bb, i
+@@ -1467,3 +1467,31 @@ int bitbag_next_bit(struct bitbag *bb, i
  
        return -1;
  }
  
        return -1;
  }