X-Git-Url: https://mattmccutchen.net/rsync/rsync.git/blobdiff_plain/5a18b34de343eca4b5537443e9bb207d91524d7e..2df20057e34db58c8caa37def9321e33acfa56fd:/generator.c diff --git a/generator.c b/generator.c index 7735e1e7..1db0fe01 100644 --- a/generator.c +++ b/generator.c @@ -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; @@ -74,7 +76,6 @@ extern int fuzzy_basis; extern int always_checksum; extern int checksum_len; extern char *partial_dir; -extern char *basis_dir[]; extern int compare_dest; extern int copy_dest; extern int link_dest; @@ -94,6 +95,7 @@ extern uid_t our_uid; extern char *backup_dir; extern char *backup_suffix; extern int backup_suffix_len; +extern char *basis_dir[MAX_BASIS_DIRS+1]; extern struct file_list *cur_flist, *first_flist, *dir_flist; extern struct filter_list_struct daemon_filter_list; @@ -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; }