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@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);