mirror of
https://github.com/RsyncProject/rsync.git
synced 2026-05-19 04:15:56 -04:00
Add flist_find_ignore_dirness() and change delete_in_dir() to use it.
This fixes an issue with -K noticed by eric casteleijn, avoids some inconsistent itemizing when a file/dir is replaced by a dir/file, and removes a now-obsolete chunk of code from make_file().
This commit is contained in:
committed by
Wayne Davison
parent
3ce3cabe34
commit
d4d56eed8a
41
flist.c
41
flist.c
@@ -1332,25 +1332,6 @@ struct file_struct *make_file(const char *fname, struct file_list *flist,
|
||||
else if (!pool)
|
||||
F_DEPTH(file) = extra_len / EXTRA_LEN;
|
||||
|
||||
/* This code is only used by the receiver when it is building
|
||||
* a list of files for a delete pass. */
|
||||
if (keep_dirlinks && linkname_len && flist) {
|
||||
STRUCT_STAT st2;
|
||||
int save_mode = file->mode;
|
||||
file->mode = S_IFDIR; /* Find a directory with our name. */
|
||||
if (flist_find(dir_flist, file) >= 0
|
||||
&& x_stat(thisname, &st2, NULL) == 0 && S_ISDIR(st2.st_mode)) {
|
||||
file->modtime = st2.st_mtime;
|
||||
file->len32 = 0;
|
||||
file->mode = st2.st_mode;
|
||||
if (uid_ndx)
|
||||
F_OWNER(file) = st2.st_uid;
|
||||
if (gid_ndx)
|
||||
F_GROUP(file) = st2.st_gid;
|
||||
} else
|
||||
file->mode = save_mode;
|
||||
}
|
||||
|
||||
if (basename_len == 0+1) {
|
||||
if (!pool)
|
||||
unmake_file(file);
|
||||
@@ -2533,6 +2514,28 @@ int flist_find(struct file_list *flist, struct file_struct *f)
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Search for an identically-named item in the file list. Differs from
|
||||
* flist_find in that an item that agrees with "f" in directory-ness is
|
||||
* preferred but one that does not is still found. */
|
||||
int flist_find_ignore_dirness(struct file_list *flist, struct file_struct *f)
|
||||
{
|
||||
mode_t save_mode;
|
||||
int ndx;
|
||||
|
||||
/* First look for an item that agrees in directory-ness. */
|
||||
ndx = flist_find(flist, f);
|
||||
if (ndx >= 0)
|
||||
return ndx;
|
||||
|
||||
/* Temporarily flip f->mode to look for an item of opposite
|
||||
* directory-ness. */
|
||||
save_mode = f->mode;
|
||||
f->mode = S_ISDIR(f->mode) ? S_IFREG : S_IFDIR;
|
||||
ndx = flist_find(flist, f);
|
||||
f->mode = save_mode;
|
||||
return ndx;
|
||||
}
|
||||
|
||||
/*
|
||||
* Free up any resources a file_struct has allocated
|
||||
* and clear the file.
|
||||
|
||||
@@ -535,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;
|
||||
|
||||
Reference in New Issue
Block a user