X-Git-Url: https://mattmccutchen.net/rsync/rsync.git/blobdiff_plain/2daed024b17a2cafb956e12581c25119d07a5950..f6d530b3fc8d95427a93d51b49ef20f9e3ee5054:/flist.c diff --git a/flist.c b/flist.c index 83effc08..c0550ecb 100644 --- a/flist.c +++ b/flist.c @@ -52,6 +52,7 @@ extern int preserve_links; extern int preserve_hard_links; extern int preserve_devices; extern int preserve_specials; +extern int delete_missing_args; extern int uid_ndx; extern int gid_ndx; extern int eol_nulls; @@ -1097,8 +1098,10 @@ struct file_struct *make_file(const char *fname, struct file_list *flist, if (sanitize_paths) sanitize_path(thisname, thisname, "", 0, SP_DEFAULT); - if (stp && S_ISDIR(stp->st_mode)) { - st = *stp; /* Needed for "symlink/." with --relative. */ + if (stp && (S_ISDIR(stp->st_mode) || stp->st_mode == 0)) { + /* This is needed to handle a "symlink/." with a --relative + * dir, or a request to delete a specific file. */ + st = *stp; *linkname = '\0'; /* make IBM code checker happy */ } else if (readlink_stat(thisname, &st, linkname) != 0) { int save_errno = errno; @@ -1139,6 +1142,11 @@ struct file_struct *make_file(const char *fname, struct file_list *flist, full_fname(thisname)); } return NULL; + } else if (st.st_mode == 0) { + io_error |= IOERR_GENERAL; + rprintf(FINFO, "skipping file with bogus (zero) st_mode: %s\n", + full_fname(thisname)); + return NULL; } if (filter_level == NO_FILTERS) @@ -2133,10 +2141,15 @@ struct file_list *send_file_list(int f, int argc, char *argv[]) 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))) { - io_error |= IOERR_GENERAL; - rsyserr(FERROR_XFER, errno, "link_stat %s failed", - full_fname(fbuf)); - continue; + 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; + rsyserr(FERROR_XFER, errno, "link_stat %s failed", + full_fname(fbuf)); + continue; + } } /* A dot-dir should not be excluded! */