X-Git-Url: https://mattmccutchen.net/rsync/rsync.git/blobdiff_plain/301fb56ce9f7b0a47ede7d03c27ad64ed3ccce15..bdedced84b7f446f818efd4d25b8985285a50009:/flist.c diff --git a/flist.c b/flist.c index a8308687..ad02b898 100644 --- a/flist.c +++ b/flist.c @@ -69,6 +69,7 @@ int io_error; dev_t filesystem_dev; /* used to implement -x */ static char empty_sum[MD4_SUM_LENGTH]; +static int flist_count_offset; static unsigned int file_struct_len; static struct file_list *sorting_flist; @@ -98,16 +99,16 @@ static void start_filelist_progress(char *kind) } -static void emit_filelist_progress(const struct file_list *flist) +static void emit_filelist_progress(int count) { - rprintf(FINFO, " %d files...\r", flist->count); + rprintf(FINFO, " %d files...\r", count); } -static void maybe_emit_filelist_progress(const struct file_list *flist) +static void maybe_emit_filelist_progress(int count) { - if (do_progress && show_filelist_p() && (flist->count % 100) == 0) - emit_filelist_progress(flist); + if (do_progress && show_filelist_p() && (count % 100) == 0) + emit_filelist_progress(count); } @@ -654,6 +655,9 @@ static struct file_struct *receive_file_entry(struct file_list *flist, if (flags & XMIT_TOP_DIR) { in_del_hier = 1; del_hier_name_len = file->dir.depth == 0 ? 0 : l1 + l2; + if (relative_paths && del_hier_name_len > 2 + && basename_len == 1+1 && *basename == '.') + del_hier_name_len -= 2; file->flags |= FLAG_TOP_DIR | FLAG_DEL_HERE; } else if (in_del_hier) { if (!relative_paths || !del_hier_name_len @@ -971,7 +975,7 @@ static struct file_struct *send_file_name(int f, struct file_list *flist, if (!file) return NULL; - maybe_emit_filelist_progress(flist); + maybe_emit_filelist_progress(flist->count + flist_count_offset); flist_expand(flist); @@ -1007,7 +1011,7 @@ static void send_if_directory(int f, struct file_list *flist, /* This function is normally called by the sender, but the receiving side also - * calls it from delete_in_dir() with f set to -1 so that we just construct the + * calls it from get_dirlist() with f set to -1 so that we just construct the * file list in memory without sending it over the wire. Also, get_dirlist() * might call this with f set to -2, which also indicates that local filter * rules should be ignored. */ @@ -1116,11 +1120,21 @@ struct file_list *send_file_list(int f, int argc, char *argv[]) if (l == 2 && fname[0] == '.') { /* Turn "./" into just "." rather than "./." */ fname[1] = '\0'; - } else if (l < MAXPATHLEN) { + } else { + if (l + 1 >= MAXPATHLEN) + overflow("send_file_list"); fname[l++] = '.'; fname[l] = '\0'; } is_dot_dir = 1; + } else if (l > 1 && fname[l-1] == '.' && fname[l-2] == '.' + && (l == 2 || fname[l-3] == '/')) { + if (l + 2 >= MAXPATHLEN) + overflow("send_file_list"); + fname[l++] = '/'; + fname[l++] = '.'; + fname[l] = '\0'; + is_dot_dir = 1; } else { is_dot_dir = fname[l-1] == '.' && (l == 1 || fname[l-2] == '/'); @@ -1309,7 +1323,7 @@ struct file_list *recv_file_list(int f) flist->files[flist->count++] = file; - maybe_emit_filelist_progress(flist); + maybe_emit_filelist_progress(flist->count); if (verbose > 2) { rprintf(FINFO, "recv_file_name(%s)\n", @@ -1772,6 +1786,8 @@ struct file_list *get_dirlist(char *dirname, int dlen, recurse = 0; send_directory(ignore_filter_rules ? -2 : -1, dirlist, dirname, dlen); recurse = save_recurse; + if (do_progress) + flist_count_offset += dirlist->count; clean_flist(dirlist, 0, 0);