extern int preserve_hard_links;
extern int preserve_devices;
extern int preserve_specials;
-extern int delete_missing_args;
+extern int missing_args;
extern int uid_ndx;
extern int gid_ndx;
extern int eol_nulls;
if (!(xflags & XMIT_SAME_MODE))
mode = from_wire_mode(read_int(f));
- if (chmod_modes && !S_ISLNK(mode))
+ if (chmod_modes && !S_ISLNK(mode) && mode)
mode = tweak_mode(mode, chmod_modes);
if (preserve_uid && !(xflags & XMIT_SAME_UID)) {
if (!file)
return NULL;
- if (chmod_modes && !S_ISLNK(file->mode))
+ if (chmod_modes && !S_ISLNK(file->mode) && file->mode)
file->mode = tweak_mode(file->mode, chmod_modes);
if (f >= 0) {
if (link_stat(fbuf, &st, copy_dirlinks || name_type != NORMAL_NAME) != 0
|| (name_type != DOTDIR_NAME && is_daemon_excluded(fbuf, S_ISDIR(st.st_mode)))
|| (relative_paths && path_is_daemon_excluded(fbuf, 1))) {
- if (errno == ENOENT && delete_missing_args) {
- /* Rsync will treat a mode of 0 as deleted. */
- memset(&st, 0, sizeof st);
- } else {
- io_error |= IOERR_GENERAL;
+ if (errno != ENOENT || missing_args == 0) {
+ /* This is a transfer error, but inhibit deletion
+ * only if we might be omitting an existing file. */
+ if (errno != ENOENT)
+ io_error |= IOERR_GENERAL;
rsyserr(FERROR_XFER, errno, "link_stat %s failed",
full_fname(fbuf));
continue;
+ } else if (missing_args == 1) {
+ /* Just ignore the arg. */
+ continue;
+ } else /* (missing_args == 2) */ {
+ /* Send the arg as a "missing" entry with
+ * mode 0, which tells the generator to delete it. */
+ memset(&st, 0, sizeof st);
}
}
/* A dot-dir should not be excluded! */
- if (name_type != DOTDIR_NAME
+ if (name_type != DOTDIR_NAME && st.st_mode != 0
&& is_excluded(fbuf, S_ISDIR(st.st_mode) != 0, ALL_FILTERS))
continue;