X-Git-Url: https://mattmccutchen.net/rsync/rsync.git/blobdiff_plain/8bd77e7098d9863f258070fb2274e324a446adbd..feb8dacc148d5428be2498e5748ef9aa2ea889a2:/generator.c diff --git a/generator.c b/generator.c index 9b371e85..6c7bf89f 100644 --- a/generator.c +++ b/generator.c @@ -4,7 +4,7 @@ * Copyright (C) 1996-2000 Andrew Tridgell * Copyright (C) 1996 Paul Mackerras * Copyright (C) 2002 Martin Pool - * 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); @@ -1953,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", @@ -2055,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; + } } } @@ -2072,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); @@ -2096,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) @@ -2129,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. */ @@ -2145,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; @@ -2171,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; @@ -2255,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) { @@ -2326,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;