[PATCH 17/41] robocopy: modify exit code in case of extra files

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


Searches for files in the destination, that are not also in the
source folder and modifies the exit code in this case

Signed-off-by: Florian Eder <others.meder at gmail.com>
---
Also removed a wine_todo from tests
---
 programs/robocopy/main.c           | 23 ++++++++++++++++++++++-
 programs/robocopy/robocopy.h       |  2 ++
 programs/robocopy/tests/robocopy.c |  2 +-
 3 files changed, 25 insertions(+), 2 deletions(-)

diff --git a/programs/robocopy/main.c b/programs/robocopy/main.c
index 3bd8b784796..2d4195daaec 100644
--- a/programs/robocopy/main.c
+++ b/programs/robocopy/main.c
@@ -323,11 +323,12 @@ static void get_file_paths_in_folder(WCHAR *directory_path, struct list *paths,
 
 static BOOL perform_copy(struct robocopy_statistics *statistics)
 {
-    struct list paths_source;
+    struct list paths_source, paths_destination;
     struct path *current_path;
     WCHAR *current_absolute_path, *target_path;
 
     list_init(&paths_source);
+    list_init(&paths_destination);
 
     if (!PathIsDirectoryW(options.source))
     {
@@ -339,6 +340,7 @@ static BOOL perform_copy(struct robocopy_statistics *statistics)
     create_directory_path(options.destination);
 
     /* get files in the destination folder and source folder */
+    get_file_paths_in_folder(options.destination, &paths_destination, options.max_subdirectories_depth);
     get_file_paths_in_folder(options.source, &paths_source, options.max_subdirectories_depth);
 
     /* get files in the source folder */
@@ -371,6 +373,24 @@ static BOOL perform_copy(struct robocopy_statistics *statistics)
 
     }
 
+    /* search for extra files (files only in destination) to be able to return the correct exit code */
+    LIST_FOR_EACH_ENTRY_REV(current_path, &paths_destination, struct path, entry)
+    {
+        struct path *source_entry;
+        BOOL found = FALSE;
+        /* only extra files, so abort if the same relative path is also in the source folder */
+        LIST_FOR_EACH_ENTRY(source_entry, &paths_source, struct path, entry)
+        {
+            if (wcsicmp(source_entry->name, current_path->name) == 0)
+            {
+                found = TRUE;
+                break;
+            }
+        }
+        if (found) continue;
+        else statistics->extra_files = TRUE;
+    }
+
     return TRUE;
 }
 
@@ -460,5 +480,6 @@ int __cdecl wmain(int argc, WCHAR *argv[])
 
     exit_code = ROBOCOPY_NO_ERROR_NO_COPY;
     if (statistics.copied_files) exit_code += ROBOCOPY_NO_ERROR_FILES_COPIED;
+    if (statistics.extra_files) exit_code += ROBOCOPY_EXTRA_FILES_IN_DESTINATION;
     return exit_code;
 }
\ No newline at end of file
diff --git a/programs/robocopy/robocopy.h b/programs/robocopy/robocopy.h
index 6beac9dbc64..677f88cb453 100644
--- a/programs/robocopy/robocopy.h
+++ b/programs/robocopy/robocopy.h
@@ -45,11 +45,13 @@ struct robocopy_options {
 struct robocopy_statistics {
     UINT copied_directories;
     UINT copied_files;
+    BOOL extra_files;
 };
 
 /* Exit codes */
 #define ROBOCOPY_NO_ERROR_NO_COPY             0
 #define ROBOCOPY_NO_ERROR_FILES_COPIED        1
+#define ROBOCOPY_EXTRA_FILES_IN_DESTINATION   2
 #define ROBOCOPY_ERROR_NO_FILES_COPIED        16
 
 /* Resource strings */
diff --git a/programs/robocopy/tests/robocopy.c b/programs/robocopy/tests/robocopy.c
index ab482d6a845..d205127d56f 100644
--- a/programs/robocopy/tests/robocopy.c
+++ b/programs/robocopy/tests/robocopy.c
@@ -373,7 +373,7 @@ START_TEST(robocopy)
     create_test_folder(L"robocopy_destination");
     create_test_file(L"robocopy_destination\\fileA.a", 9000, 0, -10);
     create_test_file(L"robocopy_destination\\fileA2.a", 9000, 0, -10);
-    todo_wine execute_robocopy(L"robocopy.exe robocopy_source robocopy_destination /mov /r:1 /w:0", 3);
+    execute_robocopy(L"robocopy.exe robocopy_source robocopy_destination /mov /r:1 /w:0", 3);
     /* check whether fileA was overwritten / not identical anymore with fileA2.a */
     check_files_equal(L"robocopy_destination\\fileA2.a", L"robocopy_destination\\fileA.a", FALSE);
     check_file_and_delete(L"robocopy_destination\\fileA2.a", TRUE);
-- 
2.32.0




More information about the wine-devel mailing list