Make sparse_seek an OFF_T (pointed out by Pedro Valasco).
[rsync/rsync.git] / generator.c
index 58ae82f..1db0fe0 100644 (file)
@@ -21,6 +21,7 @@
  */
 
 #include "rsync.h"
+#include "inums.h"
 
 extern int dry_run;
 extern int do_xfers;
@@ -53,6 +54,7 @@ extern int ignore_errors;
 extern int remove_source_files;
 extern int delay_updates;
 extern int update_only;
+extern int human_readable;
 extern int ignore_existing;
 extern int ignore_non_existing;
 extern int inplace;
@@ -102,7 +104,7 @@ int non_perishable_cnt = 0;
 int maybe_ATTRS_REPORT = 0;
 
 static dev_t dev_zero;
-static int deletion_count = 0; /* used to implement --max-delete */
+static int skipped_deletes = 0;
 static int deldelay_size = 0, deldelay_cnt = 0;
 static char *deldelay_buf = NULL;
 static int deldelay_fd = -1;
@@ -185,8 +187,10 @@ static enum delret delete_item(char *fbuf, uint16 mode, uint16 flags)
                /* OK: try to delete the directory. */
        }
 
-       if (!(flags & DEL_MAKE_ROOM) && max_delete >= 0 && ++deletion_count > max_delete)
+       if (!(flags & DEL_MAKE_ROOM) && max_delete >= 0 && stats.deleted_files >= max_delete) {
+               skipped_deletes++;
                return DR_AT_LIMIT;
+       }
 
        if (S_ISDIR(mode)) {
                what = "rmdir";
@@ -200,8 +204,22 @@ static enum delret delete_item(char *fbuf, uint16 mode, uint16 flags)
        }
 
        if (ok) {
-               if (!(flags & DEL_MAKE_ROOM))
+               if (!(flags & DEL_MAKE_ROOM)) {
                        log_delete(fbuf, mode);
+                       stats.deleted_files++;
+                       if (S_ISREG(mode)) {
+                               /* Nothing more to count */
+                       } else if (S_ISDIR(mode))
+                               stats.deleted_dirs++;
+#ifdef SUPPORT_LINKS
+                       else if (S_ISLNK(mode))
+                               stats.deleted_symlinks++;
+#endif
+                       else if (IS_DEVICE(mode))
+                               stats.deleted_symlinks++;
+                       else
+                               stats.deleted_specials++;
+               }
                ret = DR_SUCCESS;
        } else {
                if (S_ISDIR(mode) && errno == ENOTEMPTY) {
@@ -212,10 +230,8 @@ static enum delret delete_item(char *fbuf, uint16 mode, uint16 flags)
                        rsyserr(FERROR, errno, "delete_file: %s(%s) failed",
                                what, fbuf);
                        ret = DR_FAILURE;
-               } else {
-                       deletion_count--;
+               } else
                        ret = DR_SUCCESS;
-               }
        }
 
   check_ret:
@@ -519,7 +535,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;
@@ -806,8 +825,8 @@ static void sum_sizes_sqroot(struct sum_struct *sum, int64 len)
        if (sum->count && DEBUG_GTE(DELTASUM, 2)) {
                rprintf(FINFO,
                        "count=%s rem=%ld blength=%ld s2length=%d flength=%s\n",
-                       big_num(sum->count, 0), (long)sum->remainder, (long)sum->blength,
-                       sum->s2length, big_num(sum->flength, 0));
+                       big_num(sum->count), (long)sum->remainder, (long)sum->blength,
+                       sum->s2length, big_num(sum->flength));
        }
 }
 
@@ -858,7 +877,7 @@ static int generate_and_send_sums(int fd, OFF_T len, int f_out, int f_copy)
                if (DEBUG_GTE(DELTASUM, 3)) {
                        rprintf(FINFO,
                                "chunk[%s] offset=%s len=%ld sum1=%08lx\n",
-                               big_num(i, 0), big_num(offset - n1, 0), (long)n1,
+                               big_num(i), big_num(offset - n1), (long)n1,
                                (unsigned long)sum1);
                }
                write_int(f_out, sum1);
@@ -1199,6 +1218,7 @@ static void list_file_entry(struct file_struct *f)
 {
        char permbuf[PERMSTRING_SIZE];
        int64 len;
+       int colwidth = human_readable ? 14 : 11;
 
        if (!F_IS_ACTIVE(f)) {
                /* this can happen if duplicate names were removed */
@@ -1212,15 +1232,16 @@ static void list_file_entry(struct file_struct *f)
 
 #ifdef SUPPORT_LINKS
        if (preserve_links && S_ISLNK(f->mode)) {
-               rprintf(FINFO, "%s %11s %s %s -> %s\n",
-                       permbuf, big_num(len, 0), timestring(f->modtime),
-                       f_name(f, NULL), F_SYMLINK(f));
+               rprintf(FINFO, "%s %*s %s %s -> %s\n",
+                       permbuf, colwidth, comma_num(len),
+                       timestring(f->modtime), f_name(f, NULL),
+                       F_SYMLINK(f));
        } else
 #endif
        {
-               rprintf(FINFO, "%s %11s %s %s\n",
-                       permbuf, big_num(len, 0), timestring(f->modtime),
-                       f_name(f, NULL));
+               rprintf(FINFO, "%s %*s %s %s\n",
+                       permbuf, colwidth, comma_num(len),
+                       timestring(f->modtime), f_name(f, NULL));
        }
 }
 
@@ -1905,7 +1926,7 @@ static void recv_generator(char *fname, struct file_struct *file, int ndx,
 
        if (DEBUG_GTE(DELTASUM, 3)) {
                rprintf(FINFO, "gen mapped %s of size %s\n",
-                       fnamecmp, big_num(sx.st.st_size, 0));
+                       fnamecmp, big_num(sx.st.st_size));
        }
 
        if (DEBUG_GTE(DELTASUM, 2))
@@ -2076,8 +2097,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);
@@ -2100,7 +2120,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)
@@ -2282,6 +2302,9 @@ void generate_files(int f_out, const char *local_name)
                }
        } while ((cur_flist = cur_flist->next) != NULL);
 
+       if (read_batch && inc_recurse)
+               write_ndx(f_out, NDX_DONE);
+
        if (delete_during)
                delete_in_dir(NULL, NULL, &dev_zero);
        phase++;
@@ -2300,6 +2323,8 @@ void generate_files(int f_out, const char *local_name)
                rprintf(FINFO, "generate_files phase=%d\n", phase);
 
        write_ndx(f_out, NDX_DONE);
+       write_del_stats(f_out);
+
        /* Reduce round-trip lag-time for a useless delay-updates phase. */
        if (protocol_version >= 29 && !delay_updates)
                write_ndx(f_out, NDX_DONE);
@@ -2335,10 +2360,10 @@ void generate_files(int f_out, const char *local_name)
         && dir_tweaking && (!inc_recurse || delete_during == 2))
                touch_up_dirs(dir_flist, -1);
 
-       if (max_delete >= 0 && deletion_count > max_delete) {
-               rprintf(FINFO,
+       if (max_delete >= 0 && skipped_deletes) {
+               rprintf(FWARNING,
                        "Deletions stopped due to --max-delete limit (%d skipped)\n",
-                       deletion_count - max_delete);
+                       skipped_deletes);
                io_error |= IOERR_DEL_LIMIT;
        }