From fe1c19dcdfa000c2461e85ed7bf712de49904377 Mon Sep 17 00:00:00 2001 From: Wayne Davison Date: Sun, 13 Feb 2005 22:48:38 +0000 Subject: [PATCH] In clean_flist(), if a duplicate is found for a dir and a non-dir, always dump the non-dir (because the dir might have contents in the list). --- flist.c | 48 ++++++++++++++++++++++++++++++++++++------------ 1 file changed, 36 insertions(+), 12 deletions(-) diff --git a/flist.c b/flist.c index 1bfe2df9..8f388087 100644 --- a/flist.c +++ b/flist.c @@ -1460,33 +1460,57 @@ static void clean_flist(struct file_list *flist, int strip_root, int no_dups) } flist->low = prev_i; while (++i < flist->count) { - int is_dup; + int j; struct file_struct *file = flist->files[i]; if (!file->basename) continue; - is_dup = f_name_cmp(file, flist->files[prev_i]) == 0; - if (!is_dup && protocol_version >= 29 && S_ISDIR(file->mode)) { + if (f_name_cmp(file, flist->files[prev_i]) == 0) + j = prev_i; + else if (protocol_version >= 29 && S_ISDIR(file->mode)) { int save_mode = file->mode; /* Make sure that this directory doesn't duplicate a * non-directory earlier in the list. */ - file->mode = S_IFREG; flist->high = prev_i; - is_dup = flist_find(flist, file) >= 0; + file->mode = S_IFREG; + j = flist_find(flist, file); file->mode = save_mode; - } - if (is_dup) { + } else + j = -1; + if (j >= 0) { + struct file_struct *fp = flist->files[j]; + int keep, drop; + /* If one is a dir and the other is not, we want to + * keep the dir because it might have contents in the + * list. */ + if (S_ISDIR(file->mode) != S_ISDIR(fp->mode)) { + if (S_ISDIR(file->mode)) + keep = i, drop = j; + else + keep = j, drop = i; + } else + keep = j, drop = i; if (verbose > 1 && !am_server) { rprintf(FINFO, - "removing duplicate name %s from file list %d\n", - safe_fname(f_name(file)), i); + "removing duplicate name %s from file list (%d)\n", + safe_fname(f_name(file)), drop); } /* Make sure that if we unduplicate '.', that we don't * lose track of a user-specified top directory. */ - if (file->flags & FLAG_TOP_DIR) - flist->files[prev_i]->flags |= FLAG_TOP_DIR; + if (flist->files[drop]->flags & FLAG_TOP_DIR) + flist->files[keep]->flags |= FLAG_TOP_DIR; + + clear_file(drop, flist); - clear_file(i, flist); + if (keep == i) { + if (flist->low == drop) { + for (j = drop + 1; + j < i && !flist->files[j]->basename; + j++) {} + flist->low = j; + } + prev_i = i; + } } else prev_i = i; } -- 2.34.1