[PATCH 07/41] robocopy: add max subdirectory depth (/LEV)

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


Implements the /LEV:n switch, which sets the max subdirectory depth
and sets default depth to 1

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

diff --git a/programs/robocopy/main.c b/programs/robocopy/main.c
index 050258ddab2..747c242e7de 100644
--- a/programs/robocopy/main.c
+++ b/programs/robocopy/main.c
@@ -136,10 +136,26 @@ static void parse_arguments(int argc, WCHAR *argv[])
     memset(&options, 0, sizeof(options));
     options.files = calloc(1, offsetof(struct path_array, array) + (argc * sizeof(WCHAR*)));
 
+    /* default values */
+    options.max_subdirectories_depth = 1;
+
     for (i = 1; i < argc; i++)
     {
         if (is_valid_robocopy_flag(argv[i]))
-            WINE_FIXME("encountered an unknown robocopy flag: %S\n", argv[i]);
+            /* lev - Limit depth of subdirectories */
+            if (!wcsnicmp(argv[i], L"/lev:", 5))
+            {
+                long value = 0;
+                value = wcstol(&(argv[i][5]), NULL, 10);
+                if (value >= 0)
+                {
+                    options.max_subdirectories_depth = (UINT)value;
+                }
+            }
+            else
+            {
+                WINE_FIXME("encountered an unknown robocopy flag: %S\n", argv[i]);
+            }
         else
         {
             /*
@@ -220,7 +236,7 @@ static BOOL create_directory_path(WCHAR *path)
     return TRUE;
 }
 
-static void get_file_paths_in_folder(WCHAR *directory_path, struct list *paths)
+static void get_file_paths_in_folder(WCHAR *directory_path, struct list *paths, UINT depth)
 {
     HANDLE temp_handle;
     struct path *new_path, *current_path;
@@ -232,6 +248,7 @@ static void get_file_paths_in_folder(WCHAR *directory_path, struct list *paths)
     /* initialize list with a empty relative path */
     new_path = calloc(1, sizeof(struct path));
     new_path->name = calloc(2, sizeof(WCHAR));
+    new_path->level = 1;
     list_add_tail(paths, &new_path->entry);
 
     LIST_FOR_EACH_ENTRY(current_path, paths, struct path, entry)
@@ -258,10 +275,11 @@ static void get_file_paths_in_folder(WCHAR *directory_path, struct list *paths)
 
                 /* If this entry is a matching file or empty directory, add it to the list of results */
                 if ((!PathIsDirectoryW(current_absolute_path) && matches_array_entry(entry_data.cFileName, options.files)) ||
-                     (PathIsDirectoryW(current_absolute_path)))
+                     (PathIsDirectoryW(current_absolute_path) && (!depth || depth > current_path->level)))
                 {
                     new_path = calloc(1, sizeof(struct path));
                     new_path->name = wcsdup(current_relative_path);
+                    new_path->level = current_path->level + 1;
                     list_add_tail(paths, &new_path->entry);
                 }
             }
@@ -288,7 +306,7 @@ static BOOL perform_copy(void)
     create_directory_path(options.destination);
 
     /* get files in the destination folder and source folder */
-    get_file_paths_in_folder(options.source, &paths_source);
+    get_file_paths_in_folder(options.source, &paths_source, options.max_subdirectories_depth);
 
     /* get files in the source folder */
     LIST_FOR_EACH_ENTRY(current_path, &paths_source, struct path, entry)
@@ -307,6 +325,7 @@ static BOOL perform_copy(void)
         }
         else
         {
+            create_directory_path(target_path);
             if (!CopyFileW(current_absolute_path, target_path, FALSE))
                 output_error(STRING_ERROR_WRITE_FILE, GetLastError(), strip_path_prefix(target_path));
             else
diff --git a/programs/robocopy/robocopy.h b/programs/robocopy/robocopy.h
index 1cd0a427c03..0e33effe331 100644
--- a/programs/robocopy/robocopy.h
+++ b/programs/robocopy/robocopy.h
@@ -23,6 +23,7 @@
 struct path {
     struct list entry;
     WCHAR *name;
+    UINT level;
 };
 
 struct path_array {
@@ -34,6 +35,7 @@ struct robocopy_options {
     WCHAR *destination;
     WCHAR *source;
     struct path_array* files;
+    UINT max_subdirectories_depth;
 };
 
 /* Resource strings */
-- 
2.32.0




More information about the wine-devel mailing list