files on the receiver that don't exist on the sender.
control over what is output. Added an extra type of --progress output
using --info=progress2.
+ - Added the --delete-missing option to delete user-specified files on the
+ receiver that are missing on the sender (normally the absence of user-
+ specified files generates an error).
+
- Added a "T" (terabyte) category to the --human-readable size suffixes.
- Enhanced the --stats output: 1) to mention how many files were created
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;
stats.num_symlinks++;
else if (IS_DEVICE(file->mode))
stats.num_devices++;
- else
+ else if (IS_SPECIAL(file->mode))
stats.num_specials++;
xflags = 0;
}
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;
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)
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! */
extern int delete_before;
extern int delete_during;
extern int delete_after;
+extern int delete_missing_args;
extern int msgdone_cnt;
extern int ignore_errors;
extern int remove_source_files;
stat_errno = errno;
}
+ if (delete_missing_args && file->mode == 0) {
+ if (statret == 0)
+ delete_item(fname, sx.st.st_mode, del_opts);
+ return;
+ }
+
if (ignore_non_existing > 0 && statret == -1 && stat_errno == ENOENT) {
if (is_dir) {
if (is_dir < 0)
int delete_before = 0;
int delete_after = 0;
int delete_excluded = 0;
+int delete_missing_args = 0;
int remove_source_files = 0;
int one_file_system = 0;
int protocol_version = PROTOCOL_VERSION;
rprintf(F," --delete-delay find deletions during, delete after\n");
rprintf(F," --delete-after receiver deletes after transfer, not during\n");
rprintf(F," --delete-excluded also delete excluded files from destination dirs\n");
+ rprintf(F," --delete-missing-args receiver deletes each missing source arg\n");
rprintf(F," --ignore-errors delete even if there are I/O errors\n");
rprintf(F," --force force deletion of directories even if not empty\n");
rprintf(F," --max-delete=NUM don't delete more than NUM files\n");
{"delete-delay", 0, POPT_ARG_VAL, &delete_during, 2, 0, 0 },
{"delete-after", 0, POPT_ARG_NONE, &delete_after, 0, 0, 0 },
{"delete-excluded", 0, POPT_ARG_NONE, &delete_excluded, 0, 0, 0 },
+ {"delete-missing-args",0,POPT_ARG_NONE, &delete_missing_args, 0, 0, 0 },
{"remove-sent-files",0, POPT_ARG_VAL, &remove_source_files, 2, 0, 0 }, /* deprecated */
{"remove-source-files",0,POPT_ARG_VAL, &remove_source_files, 1, 0, 0 },
{"force", 0, POPT_ARG_VAL, &force_delete, 1, 0, 0 },
return 0;
}
- if (delete_mode && refused_delete) {
+ if (refused_delete && (delete_mode || delete_missing_args)) {
create_refuse_error(refused_delete);
return 0;
}
}
}
+ if (delete_missing_args)
+ args[ac++] = "--delete-missing-args";
+
if (modify_window_set) {
if (asprintf(&arg, "--modify-window=%d", modify_window) < 0)
goto oom;
--delete-delay find deletions during, delete after
--delete-after receiver deletes after transfer, not before
--delete-excluded also delete excluded files from dest dirs
+ --delete-missing-args receiver deletes each missing source arg
--ignore-errors delete even if there are I/O errors
--force force deletion of dirs even if not empty
--max-delete=NUM don't delete more than NUM files
bf(--delete-excluded).
See bf(--delete) (which is implied) for more details on file-deletion.
+dit(bf(--delete-missing-args)) Any source arg that is found to me missing is
+treated as a request to delete the file by the receiver rather than the sender
+generating a missing-file error. Does not affect vanished files discovered
+through recursive scanning of directories, just the args mentioned on the
+command-line or in the bf(--files-from) list. Can be used with or without any
+other type of delete processing.
+
dit(bf(--ignore-errors)) Tells bf(--delete) to go ahead and delete files
even when there are I/O errors.