[PATCH 34/41] robocopy: add flag to exclude files only found in source / destination (/XX, /XL)
Florian Eder
others.meder at gmail.com
Mon Sep 6 09:55:11 CDT 2021
Implements the /XX and /XL flags, which prevent the overwriting / deletion of files
that only exist in the source, but not the destination, or only the destination, but not
the source, by flags like /PURGE or /MOVE
Signed-off-by: Florian Eder <others.meder at gmail.com>
---
programs/robocopy/main.c | 26 ++++++++++++++++++++++++--
programs/robocopy/robocopy.h | 2 ++
2 files changed, 26 insertions(+), 2 deletions(-)
diff --git a/programs/robocopy/main.c b/programs/robocopy/main.c
index 2fc0c39503d..620154b58c8 100644
--- a/programs/robocopy/main.c
+++ b/programs/robocopy/main.c
@@ -254,6 +254,16 @@ static void parse_arguments(int argc, WCHAR *argv[])
/* xd includes all following directories, until the next option / flag */
is_xd = TRUE;
}
+ /* xx - Ignore files in destination that are not also in source */
+ else if (!wcsicmp(argv[i], L"/xx"))
+ {
+ options.exclude_files_not_in_source = TRUE;
+ }
+ /* xl - Create no new files in destination folder */
+ else if (!wcsicmp(argv[i], L"/xl"))
+ {
+ options.create_no_new_files = TRUE;
+ }
/* lev - Limit depth of subdirectories */
else if (!wcsnicmp(argv[i], L"/lev:", 5))
{
@@ -483,6 +493,8 @@ static BOOL is_valid_file(WCHAR *source, WCHAR *destination)
if (destination_handle == INVALID_HANDLE_VALUE)
{
CloseHandle(source_handle);
+ /* ignore file if no file at the destination path exist and no no files should be created */
+ if (options.create_no_new_files) return FALSE;
return TRUE;
}
GetFileTime(destination_handle, &destination_creation_time, &destination_access_time, &destination_modified_time);
@@ -533,7 +545,9 @@ static BOOL perform_copy(struct robocopy_statistics *statistics)
if (PathIsDirectoryW(current_absolute_path))
{
/* ignore empty directories if empty subdirectories are not copied */
- if ((PathIsDirectoryEmptyW(current_absolute_path) && !options.copy_empty_subdirectories)) continue;
+ if ((PathIsDirectoryEmptyW(current_absolute_path) && !options.copy_empty_subdirectories) ||
+ options.create_no_new_files)
+ continue;
/* Create the directory path and then create the directory itself */
if (!options.dry_run && (!create_directory_path(target_path) ||
@@ -586,7 +600,7 @@ static BOOL perform_copy(struct robocopy_statistics *statistics)
else statistics->extra_files = TRUE;
/* if purge is specified (and xx is not set), we delete the (non-excluded) extra files and folders from the destination */
- if (options.purge_destination)
+ if (options.purge_destination && !options.exclude_files_not_in_source)
{
current_absolute_path = get_combined_path(options.destination, current_path->name);
/* only files or empty folders */
@@ -662,6 +676,14 @@ static WCHAR *get_option_string(void)
if (options.dont_overwrite_older_files)
wcscat(temp_string, L"/XO ");
+ /* Ignore files in destination only */
+ if (options.exclude_files_not_in_source)
+ wcscat(temp_string, L"/XX ");
+
+ /* No new files */
+ if (options.create_no_new_files)
+ wcscat(temp_string, L"/XL ");
+
/* Max File Size */
if (options.max_size != MAXLONGLONG)
swprintf(temp_string + wcslen(temp_string), ARRAY_SIZE(temp_string) - wcslen(temp_string),
diff --git a/programs/robocopy/robocopy.h b/programs/robocopy/robocopy.h
index cf396f88dfc..376c466d907 100644
--- a/programs/robocopy/robocopy.h
+++ b/programs/robocopy/robocopy.h
@@ -52,6 +52,8 @@ struct robocopy_options {
FILETIME max_time;
BOOL dont_overwrite_newer_files;
BOOL dont_overwrite_older_files;
+ BOOL exclude_files_not_in_source;
+ BOOL create_no_new_files;
};
struct robocopy_statistics {
--
2.32.0
More information about the wine-devel
mailing list