extern int preserve_specials;
extern int preserve_hard_links;
extern int preserve_perms;
+extern int preserve_executability;
extern int preserve_uid;
extern int preserve_gid;
extern int preserve_times;
extern int omit_dir_times;
+extern int delete_mode;
extern int delete_before;
extern int delete_during;
extern int delete_after;
return -1;
}
- zap_dir = flags & DEL_FORCE_RECURSE || (force_delete && recurse);
+ zap_dir = flags & DEL_FORCE_RECURSE || force_delete;
if ((max_delete && ++deletion_count > max_delete)
|| (dry_run && zap_dir)) {
ok = 0;
&& (!(iflags & ITEM_XNAME_FOLLOWS) || *xname))
|| (keep_time && cmp_modtime(file->modtime, st->st_mtime) != 0))
iflags |= ITEM_REPORT_TIME;
- if (preserve_perms
+ if ((preserve_perms || preserve_executability)
&& (file->mode & CHMOD_BITS) != (st->st_mode & CHMOD_BITS))
iflags |= ITEM_REPORT_PERMS;
if (preserve_uid && am_root && file->uid != st->st_uid)
char *fnamecmp, *partialptr, *backupptr = NULL;
char fnamecmpbuf[MAXPATHLEN];
uchar fnamecmp_type;
+ int del_opts = DEL_TERSE | (delete_mode ? DEL_FORCE_RECURSE : 0);
if (list_only)
return;
return;
}
- if (statret == 0 && !preserve_perms
- && S_ISDIR(st.st_mode) == S_ISDIR(file->mode)) {
- /* if the file exists already and we aren't perserving
- * permissions then act as though the remote end sent
- * us the file permissions we already have */
- file->mode = (file->mode & ~CHMOD_BITS)
- | (st.st_mode & CHMOD_BITS);
+ /* If we're not preserving permissions, change the file-list's
+ * mode based on the local permissions and some heuristics. */
+ if (!preserve_perms) {
+ int exists = statret == 0
+ && S_ISDIR(st.st_mode) == S_ISDIR(file->mode);
+ file->mode = dest_mode(file->mode, st.st_mode, exists);
}
if (S_ISDIR(file->mode)) {
* we need to delete it. If it doesn't exist, then
* (perhaps recursively) create it. */
if (statret == 0 && !S_ISDIR(st.st_mode)) {
- if (delete_item(fname, st.st_mode, DEL_TERSE) < 0)
+ if (delete_item(fname, st.st_mode, del_opts) < 0)
return;
statret = -1;
}
}
/* Not the right symlink (or not a symlink), so
* delete it. */
- if (delete_item(fname, st.st_mode, DEL_TERSE) < 0)
+ if (delete_item(fname, st.st_mode, del_opts) < 0)
return;
if (!S_ISLNK(st.st_mode))
statret = -1;
|| (st.st_mode & ~CHMOD_BITS) != (file->mode & ~CHMOD_BITS)
|| st.st_rdev != file->u.rdev) {
if (statret == 0
- && delete_item(fname, st.st_mode, DEL_TERSE) < 0)
+ && delete_item(fname, st.st_mode, del_opts) < 0)
return;
if (preserve_hard_links && file->link_u.links
&& hard_link_check(file, ndx, fname, -1, &st,
fnamecmp_type = FNAMECMP_FNAME;
if (statret == 0 && !S_ISREG(st.st_mode)) {
- if (delete_item(fname, st.st_mode, DEL_TERSE) != 0)
+ if (delete_item(fname, st.st_mode, del_opts) != 0)
return;
statret = -1;
stat_errno = ENOENT;