From: Florian Eder Subject: [PATCH 35/41] robocopy: add flag to prevent overwriting of changed files (/XC) Message-Id: <20210906145518.346132-35-others.meder@gmail.com> Date: Mon, 6 Sep 2021 14:55:12 +0000 In-Reply-To: <20210906145518.346132-1-others.meder@gmail.com> References: <20210906145518.346132-1-others.meder@gmail.com> 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 --- 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