[PATCH 26/41] robocopy: add dry run flag (/L)

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


Implements the /L switch, which causes robocopy to do no real
copy / move / delete operation

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

diff --git a/programs/robocopy/main.c b/programs/robocopy/main.c
index 41ed29f1725..4f1b07e8954 100644
--- a/programs/robocopy/main.c
+++ b/programs/robocopy/main.c
@@ -177,6 +177,11 @@ static void parse_arguments(int argc, WCHAR *argv[])
                 if (!options.user_limited_subdirectories_depth)
                     options.max_subdirectories_depth = 0;
             }
+            /* l - Dry Run */
+            else if (!wcsicmp(argv[i], L"/l"))
+            {
+                options.dry_run = TRUE;
+            }
             /* mov - Delete files (but not folders) after copying them */
             else if (!wcsicmp(argv[i], L"/mov"))
             {
@@ -293,7 +298,7 @@ static BOOL create_directory_path(WCHAR *path)
     {
         if (!lstrcpynW(current_folder, path, pointer - path + 2)) return FALSE;
         /* try to create the folder, ignoring any failure due to ERROR_ALREADY_EXISTS */
-        if (!CreateDirectoryW(current_folder, NULL))
+        if (!options.dry_run && !CreateDirectoryW(current_folder, NULL))
         {
             if (GetLastError() != ERROR_ALREADY_EXISTS)
             {
@@ -413,13 +418,14 @@ static BOOL perform_copy(struct robocopy_statistics *statistics)
             if ((PathIsDirectoryEmptyW(current_absolute_path) && !options.copy_empty_subdirectories)) continue;
 
             /* Create the directory path and then create the directory itself */
-            if (!create_directory_path(target_path) || (!CreateDirectoryW(target_path, NULL) && GetLastError() != ERROR_ALREADY_EXISTS))
+            if (!options.dry_run && (!create_directory_path(target_path) ||
+                                    (!CreateDirectoryW(target_path, NULL) && GetLastError() != ERROR_ALREADY_EXISTS)))
                 output_error(STRING_ERROR_WRITE_DIRECTORY, GetLastError(), strip_path_prefix(target_path));
             else statistics->copied_directories++;
         }
         else
         {
-            if (copy_or_move_file(current_absolute_path, target_path, options.purge_source_files))
+            if (options.dry_run || copy_or_move_file(current_absolute_path, target_path, options.purge_source_files))
             {
                 output_message(options.purge_source_files ? STRING_MOVE_FILE : STRING_CREATE_FILE, strip_path_prefix(target_path));
                 statistics->copied_files++;
@@ -429,7 +435,7 @@ static BOOL perform_copy(struct robocopy_statistics *statistics)
     }
 
     /* if move is specified, we delete the empty remaining folders in the source */
-    if (options.purge_source)
+    if (!options.dry_run && options.purge_source)
     {
         LIST_FOR_EACH_ENTRY_REV(current_path, &paths_source, struct path, entry)
         {
@@ -465,13 +471,13 @@ static BOOL perform_copy(struct robocopy_statistics *statistics)
             /* only files or empty folders */
             if (!PathIsDirectoryW(current_absolute_path))
             {
-                if (!DeleteFileW(current_absolute_path))
+                if (!options.dry_run && !DeleteFileW(current_absolute_path))
                     output_error(STRING_ERROR_DELETE_FILE, GetLastError(), strip_path_prefix(current_absolute_path));
                 else output_message(STRING_DELETE_FILE, strip_path_prefix(current_absolute_path));
             }
             else if (PathIsDirectoryEmptyW(current_absolute_path))
             {
-                if (!RemoveDirectoryW(current_absolute_path))
+                if (!options.dry_run && !RemoveDirectoryW(current_absolute_path))
                     output_error(STRING_ERROR_DELETE_DIRECTORY, GetLastError(), strip_path_prefix(current_absolute_path));
                 else output_message(STRING_DELETE_DIRECTORY, strip_path_prefix(current_absolute_path));
             }
@@ -487,6 +493,10 @@ static WCHAR *get_option_string(void)
     WCHAR *string, temp_string[512];
     memset(temp_string, 0, sizeof(temp_string));
 
+    /* Dry Run */
+    if (options.dry_run)
+        wcscat(temp_string, L"/L ");
+
     /* If no files set, display *.* */
     if (options.files->size == 0)
         wcscat(temp_string, L"*.* ");
diff --git a/programs/robocopy/robocopy.h b/programs/robocopy/robocopy.h
index 1818fdf90f1..9e3137109b8 100644
--- a/programs/robocopy/robocopy.h
+++ b/programs/robocopy/robocopy.h
@@ -45,6 +45,7 @@ struct robocopy_options {
     BOOL purge_source;
     BOOL purge_destination;
     BOOL mirror;
+    BOOL dry_run;
 };
 
 struct robocopy_statistics {
-- 
2.32.0




More information about the wine-devel mailing list