+ }
+
+ flist_free(dirlist);
+
+ if (!save_uid_ndx) {
+ --file_extra_cnt;
+ uid_ndx = 0;
+ }
+}
+
+/* This deletes any files on the receiving side that are not present on the
+ * sending side. This is used by --delete-before and --delete-after. */
+static void do_delete_pass(void)
+{
+ char fbuf[MAXPATHLEN];
+ STRUCT_STAT st;
+ int j;
+
+ /* dry_run is incremented when the destination doesn't exist yet. */
+ if (dry_run > 1 || list_only)
+ return;
+
+ for (j = 0; j < cur_flist->used; j++) {
+ struct file_struct *file = cur_flist->sorted[j];
+
+ if (!(file->flags & FLAG_CONTENT_DIR))
+ continue;
+
+ f_name(file, fbuf);
+ if (verbose > 1 && file->flags & FLAG_TOP_DIR)
+ rprintf(FINFO, "deleting in %s\n", fbuf);
+
+ if (link_stat(fbuf, &st, keep_dirlinks) < 0
+ || !S_ISDIR(st.st_mode))
+ continue;
+
+ delete_in_dir(fbuf, file, &st.st_dev);
+ }
+ delete_in_dir(NULL, NULL, &dev_zero);
+
+ if (do_progress && !am_server)
+ rprintf(FINFO, " \r");
+}
+
+int unchanged_attrs(const char *fname, struct file_struct *file, stat_x *sxp)
+{
+#if !defined HAVE_LUTIMES || !defined HAVE_UTIMES
+ if (S_ISLNK(file->mode)) {
+ ;
+ } else
+#endif
+ if (preserve_times && cmp_time(sxp->st.st_mtime, file->modtime) != 0)
+ return 0;
+
+ if (preserve_perms) {
+ if (!BITS_EQUAL(sxp->st.st_mode, file->mode, CHMOD_BITS))
+ return 0;
+ } else if (preserve_executability
+ && ((sxp->st.st_mode & 0111 ? 1 : 0) ^ (file->mode & 0111 ? 1 : 0)))
+ return 0;
+
+ if (am_root && uid_ndx && sxp->st.st_uid != (uid_t)F_OWNER(file))
+ return 0;
+
+ if (gid_ndx && !(file->flags & FLAG_SKIP_GROUP) && sxp->st.st_gid != (gid_t)F_GROUP(file))
+ return 0;
+
+#ifdef SUPPORT_ACLS
+ if (preserve_acls && !S_ISLNK(file->mode)) {
+ if (!ACL_READY(*sxp))
+ get_acl(fname, sxp);
+ if (set_acl(NULL, file, sxp) == 0)
+ return 0;
+ }
+#endif
+#ifdef SUPPORT_XATTRS
+ if (preserve_xattrs) {
+ if (!XATTR_READY(*sxp))
+ get_xattr(fname, sxp);
+ if (xattr_diff(file, sxp, 0))
+ return 0;
+ }
+#endif
+
+ return 1;
+}
+
+void itemize(const char *fnamecmp, struct file_struct *file, int ndx, int statret,
+ stat_x *sxp, int32 iflags, uchar fnamecmp_type,
+ const char *xname)
+{
+ if (statret >= 0) { /* A from-dest-dir statret can == 1! */
+ int keep_time = !preserve_times ? 0
+ : S_ISDIR(file->mode) ? preserve_times > 1 :
+#if defined HAVE_LUTIMES && defined HAVE_UTIMES
+ 1;
+#else
+ !S_ISLNK(file->mode);
+#endif
+
+ if (S_ISREG(file->mode) && F_LENGTH(file) != sxp->st.st_size)
+ iflags |= ITEM_REPORT_SIZE;
+ if (file->flags & FLAG_TIME_FAILED) { /* symlinks only */
+ if (iflags & ITEM_LOCAL_CHANGE)
+ iflags |= symlink_timeset_failed_flags;
+ } else if (keep_time
+ ? cmp_time(file->modtime, sxp->st.st_mtime) != 0
+ : iflags & (ITEM_TRANSFER|ITEM_LOCAL_CHANGE) && !(iflags & ITEM_MATCHED)
+ && (!(iflags & ITEM_XNAME_FOLLOWS) || *xname))
+ iflags |= ITEM_REPORT_TIME;
+#if !defined HAVE_LCHMOD && !defined HAVE_SETATTRLIST
+ if (S_ISLNK(file->mode)) {
+ ;
+ } else
+#endif
+ if (preserve_perms) {
+ if (!BITS_EQUAL(sxp->st.st_mode, file->mode, CHMOD_BITS))
+ iflags |= ITEM_REPORT_PERMS;
+ } else if (preserve_executability
+ && ((sxp->st.st_mode & 0111 ? 1 : 0) ^ (file->mode & 0111 ? 1 : 0)))
+ iflags |= ITEM_REPORT_PERMS;
+ if (uid_ndx && am_root && (uid_t)F_OWNER(file) != sxp->st.st_uid)
+ iflags |= ITEM_REPORT_OWNER;
+ if (gid_ndx && !(file->flags & FLAG_SKIP_GROUP)
+ && sxp->st.st_gid != (gid_t)F_GROUP(file))
+ iflags |= ITEM_REPORT_GROUP;
+#ifdef SUPPORT_ACLS
+ if (preserve_acls && !S_ISLNK(file->mode)) {
+ if (!ACL_READY(*sxp))
+ get_acl(fnamecmp, sxp);
+ if (set_acl(NULL, file, sxp) == 0)
+ iflags |= ITEM_REPORT_ACL;
+ }
+#endif
+#ifdef SUPPORT_XATTRS
+ if (preserve_xattrs) {
+ if (!XATTR_READY(*sxp))
+ get_xattr(fnamecmp, sxp);
+ if (xattr_diff(file, sxp, 1))
+ iflags |= ITEM_REPORT_XATTR;
+ }
+#endif