Fixed the use of --xattrs with --only-write-batch.
[rsync/rsync.git] / generator.c
index 1fcdb4c..6c7bf89 100644 (file)
@@ -4,7 +4,7 @@
  * Copyright (C) 1996-2000 Andrew Tridgell
  * Copyright (C) 1996 Paul Mackerras
  * Copyright (C) 2002 Martin Pool <mbp@samba.org>
- * Copyright (C) 2003-2008 Wayne Davison
+ * Copyright (C) 2003-2009 Wayne Davison
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -108,7 +108,7 @@ static int deletion_count = 0; /* used to implement --max-delete */
 static int deldelay_size = 0, deldelay_cnt = 0;
 static char *deldelay_buf = NULL;
 static int deldelay_fd = -1;
-static int lull_mod;
+static int loopchk_limit;
 static int dir_tweaking;
 static int symlink_timeset_failed_flags;
 static int need_retouch_dir_times;
@@ -521,7 +521,10 @@ static void delete_in_dir(char *fbuf, struct file_struct *file, dev_t *fs_dev)
                                        f_name(fp, NULL));
                        continue;
                }
-               if (flist_find(cur_flist, fp) < 0) {
+               /* Here we want to match regardless of file type.  Replacement
+                * of a file with one of another type is handled separately by
+                * a delete_item call with a DEL_MAKE_ROOM flag. */
+               if (flist_find_ignore_dirness(cur_flist, fp) < 0) {
                        int flags = DEL_RECURSE;
                        if (!(fp->mode & S_IWUSR) && !am_root && (uid_t)F_OWNER(fp) == our_uid)
                                flags |= DEL_NO_UID_WRITE;
@@ -697,7 +700,7 @@ void itemize(const char *fnamecmp, struct file_struct *file, int ndx, int statre
                        if (iflags & ITEM_XNAME_FOLLOWS)
                                write_vstring(sock_f_out, xname, strlen(xname));
 #ifdef SUPPORT_XATTRS
-                       if (preserve_xattrs && !dry_run
+                       if (preserve_xattrs && do_xfers
                         && iflags & (ITEM_REPORT_XATTR|ITEM_TRANSFER)) {
                                send_xattr_request(NULL, file,
                                        iflags & ITEM_REPORT_XATTR ? sock_f_out : -1);
@@ -763,11 +766,12 @@ static void sum_sizes_sqroot(struct sum_struct *sum, int64 len)
        else if (len <= BLOCK_SIZE * BLOCK_SIZE)
                blength = BLOCK_SIZE;
        else {
+               int32 max_blength = protocol_version < 30 ? OLD_MAX_BLOCK_SIZE : MAX_BLOCK_SIZE;
                int32 c;
                int cnt;
                for (c = 1, l = len, cnt = 0; l >>= 2; c <<= 1, cnt++) {}
-               if (cnt >= 31 || c >= MAX_BLOCK_SIZE)
-                       blength = MAX_BLOCK_SIZE;
+               if (c < 0 || c >= max_blength)
+                       blength = max_blength;
                else {
                    blength = 0;
                    do {
@@ -1952,9 +1956,12 @@ static void recv_generator(char *fname, struct file_struct *file, int ndx,
        if (read_batch)
                goto cleanup;
 
-       if (statret != 0 || whole_file || sx.st.st_size <= 0)
+       if (statret != 0 || whole_file)
                write_sum_head(f_out, NULL);
-       else {
+       else if (sx.st.st_size <= 0) {
+               write_sum_head(f_out, NULL);
+               close(fd);
+       } else {
                if (generate_and_send_sums(fd, sx.st.st_size, f_out, f_copy) < 0) {
                        rprintf(FWARNING,
                            "WARNING: file is too large for checksum sending: %s\n",
@@ -2054,10 +2061,13 @@ static void touch_up_dirs(struct file_list *flist, int ndx)
                         && cmp_time(st.st_mtime, file->modtime) != 0)
                                set_modtime(fname, file->modtime, file->mode);
                }
-               if (allowed_lull && !(counter % lull_mod))
-                       maybe_send_keepalive();
-               else if (!(counter & 0xFF))
-                       maybe_flush_socket(0);
+               if (counter >= loopchk_limit) {
+                       if (allowed_lull)
+                               maybe_send_keepalive();
+                       else
+                               maybe_flush_socket(0);
+                       counter = 0;
+               }
        }
 }
 
@@ -2071,8 +2081,7 @@ void check_for_finished_files(int itemizing, enum logcode code, int check_redo)
        while (1) {
 #ifdef SUPPORT_HARD_LINKS
                if (preserve_hard_links && (ndx = get_hlink_num()) != -1) {
-                       flist = flist_for_ndx(ndx);
-                       assert(flist != NULL);
+                       flist = flist_for_ndx(ndx, "check_for_finished_files.1");
                        file = flist->files[ndx - flist->ndx_start];
                        assert(file->flags & FLAG_HLINKED);
                        finish_hard_link(file, f_name(file, fbuf), ndx, NULL, itemizing, code, -1);
@@ -2095,7 +2104,7 @@ void check_for_finished_files(int itemizing, enum logcode code, int check_redo)
                        ignore_times++;
 
                        flist = cur_flist;
-                       cur_flist = flist_for_ndx(ndx);
+                       cur_flist = flist_for_ndx(ndx, "check_for_finished_files.2");
 
                        file = cur_flist->files[ndx - cur_flist->ndx_start];
                        if (solo_file)
@@ -2128,10 +2137,9 @@ void check_for_finished_files(int itemizing, enum logcode code, int check_redo)
                if (first_flist->in_progress || first_flist->to_redo)
                        break;
 
-               if (!read_batch) {
-                       write_ndx(sock_f_out, NDX_DONE);
+               write_ndx(sock_f_out, NDX_DONE);
+               if (!read_batch)
                        maybe_flush_socket(1);
-               }
 
                if (delete_during == 2 || !dir_tweaking) {
                        /* Skip directory touch-up. */
@@ -2144,7 +2152,7 @@ void check_for_finished_files(int itemizing, enum logcode code, int check_redo)
 
 void generate_files(int f_out, const char *local_name)
 {
-       int i, ndx;
+       int i, ndx, next_loopchk = 0;
        char fbuf[MAXPATHLEN];
        int itemizing;
        enum logcode code;
@@ -2170,7 +2178,7 @@ void generate_files(int f_out, const char *local_name)
        solo_file = local_name;
        dir_tweaking = !(list_only || solo_file || dry_run);
        need_retouch_dir_times = preserve_times > 1;
-       lull_mod = allowed_lull * 5;
+       loopchk_limit = allowed_lull ? allowed_lull * 5 : 200;
        symlink_timeset_failed_flags = ITEM_REPORT_TIME
            | (protocol_version >= 30 || !am_server ? ITEM_REPORT_TIMEFAIL : 0);
        implied_dirs_are_missing = relative_paths && !implied_dirs && protocol_version < 30;
@@ -2254,10 +2262,13 @@ void generate_files(int f_out, const char *local_name)
 
                        check_for_finished_files(itemizing, code, 0);
 
-                       if (allowed_lull && !(i % lull_mod))
-                               maybe_send_keepalive();
-                       else if (!(i & 0xFF))
-                               maybe_flush_socket(0);
+                       if (i + cur_flist->ndx_start >= next_loopchk) {
+                               if (allowed_lull)
+                                       maybe_send_keepalive();
+                               else
+                                       maybe_flush_socket(0);
+                               next_loopchk += loopchk_limit;
+                       }
                }
 
                if (!inc_recurse) {
@@ -2325,7 +2336,7 @@ void generate_files(int f_out, const char *local_name)
                touch_up_dirs(dir_flist, -1);
 
        if (max_delete >= 0 && deletion_count > max_delete) {
-               rprintf(FINFO,
+               rprintf(FWARNING,
                        "Deletions stopped due to --max-delete limit (%d skipped)\n",
                        deletion_count - max_delete);
                io_error |= IOERR_DEL_LIMIT;