[PATCH 35/41] robocopy: add flag to prevent overwriting of changed files (/XC)

Florian Eder others.meder at gmail.com
Mon Sep 6 09:55:12 CDT 2021


Implements the /XC flag, which prevents the overwriting of files in
the destination folder with an identical timestamp, but a different
file size

Signed-off-by: Florian Eder <others.meder at gmail.com>
---
 programs/robocopy/main.c     | 21 ++++++++++++++++++++-
 programs/robocopy/robocopy.h |  1 +
 2 files changed, 21 insertions(+), 1 deletion(-)

diff --git a/programs/robocopy/main.c b/programs/robocopy/main.c
index 620154b58c8..a7c419e37d7 100644
--- a/programs/robocopy/main.c
+++ b/programs/robocopy/main.c
@@ -254,6 +254,11 @@ static void parse_arguments(int argc, WCHAR *argv[])
                 /* xd includes all following directories, until the next option / flag */
                 is_xd = TRUE;
             }
+            /* xc - Don't overwrite files that are changed */
+            else if (!wcsicmp(argv[i], L"/xc"))
+            {
+                options.dont_overwrite_changed_files = TRUE;
+            }
             /* xx - Ignore files in destination that are not also in source */
             else if (!wcsicmp(argv[i], L"/xx"))
             {
@@ -467,7 +472,7 @@ static void get_file_paths_in_folder(WCHAR *directory_path, struct list *paths,
 static BOOL is_valid_file(WCHAR *source, WCHAR *destination)
 {
     HANDLE source_handle, destination_handle;
-    LARGE_INTEGER source_size;
+    LARGE_INTEGER source_size, destination_size;
     FILETIME source_creation_time, source_access_time, source_modified_time,
              destination_creation_time, destination_access_time, destination_modified_time;
     source_handle = CreateFileW(source, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL);
@@ -498,6 +503,16 @@ static BOOL is_valid_file(WCHAR *source, WCHAR *destination)
         return TRUE;
     }
     GetFileTime(destination_handle, &destination_creation_time, &destination_access_time, &destination_modified_time);
+    GetFileSizeEx(destination_handle, &destination_size);
+    /* don't overwrite "changed" files (meaning "different file size but same filetime") if set to do so */
+    if (options.dont_overwrite_changed_files &&
+        destination_size.QuadPart != source_size.QuadPart &&
+        !CompareFileTime(&destination_creation_time, &source_creation_time))
+    {
+        CloseHandle(source_handle);
+        CloseHandle(destination_handle);
+        return FALSE;
+    }
     /* don't overwrite newer or older files if set to do so */
     if ((options.dont_overwrite_newer_files && CompareFileTime(&source_creation_time, &destination_creation_time) > 0) ||
         (options.dont_overwrite_older_files && CompareFileTime(&source_creation_time, &destination_creation_time) < 0))
@@ -684,6 +699,10 @@ static WCHAR *get_option_string(void)
     if (options.create_no_new_files)
         wcscat(temp_string, L"/XL ");
 
+    /* Ignore changed files */
+    if (options.dont_overwrite_changed_files)
+        wcscat(temp_string, L"/XC ");
+
     /* 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 376c466d907..67fbd9eb822 100644
--- a/programs/robocopy/robocopy.h
+++ b/programs/robocopy/robocopy.h
@@ -52,6 +52,7 @@ struct robocopy_options {
     FILETIME max_time;
     BOOL dont_overwrite_newer_files;
     BOOL dont_overwrite_older_files;
+    BOOL dont_overwrite_changed_files;
     BOOL exclude_files_not_in_source;
     BOOL create_no_new_files;
 };
-- 
2.32.0




More information about the wine-devel mailing list