[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