[PATCH 28/41] robocopy: add min / max file size flag (/MIN, /MAX)
Florian Eder
others.meder at gmail.com
Mon Sep 6 09:55:05 CDT 2021
Implements the /MIN:n and /MAX:n switches, which causes only files
smaller or bigger than the set values to be included in any copy operation
Signed-off-by: Florian Eder <others.meder at gmail.com>
---
Both switches in one patch, as both are very closely connected and share
some code
---
programs/robocopy/main.c | 46 ++++++++++++++++++++++++++++++++++++
programs/robocopy/robocopy.h | 2 ++
2 files changed, 48 insertions(+)
diff --git a/programs/robocopy/main.c b/programs/robocopy/main.c
index 4f1b07e8954..47ed5a12371 100644
--- a/programs/robocopy/main.c
+++ b/programs/robocopy/main.c
@@ -141,6 +141,7 @@ static void parse_arguments(int argc, WCHAR *argv[])
/* default values */
options.max_subdirectories_depth = 1;
+ options.max_size = MAXLONGLONG;
for (i = 1; i < argc; i++)
{
@@ -216,6 +217,20 @@ static void parse_arguments(int argc, WCHAR *argv[])
options.user_limited_subdirectories_depth = TRUE;
}
}
+ /* max - Include only smaller files */
+ else if (!wcsnicmp(argv[i], L"/max:", 5))
+ {
+ LONGLONG value = 0;
+ if (swscanf(&(argv[i][5]), L"%lld", &value) == 1 && value >= 0)
+ options.max_size = value;
+ }
+ /* min - Include only bigger files */
+ else if (!wcsnicmp(argv[i], L"/min:", 5))
+ {
+ LONGLONG value = 0;
+ if (swscanf(&(argv[i][5]), L"%lld", &value) == 1 && value >= 0)
+ options.min_size = value;
+ }
else
{
WINE_FIXME("encountered an unknown robocopy flag: %S\n", argv[i]);
@@ -381,6 +396,24 @@ static void get_file_paths_in_folder(WCHAR *directory_path, struct list *paths,
}
}
+static BOOL is_valid_file(WCHAR *source)
+{
+ HANDLE source_handle;
+ LARGE_INTEGER source_size;
+ source_handle = CreateFileW(source, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL);
+ if (source_handle == INVALID_HANDLE_VALUE) return FALSE;
+ GetFileSizeEx(source_handle, &source_size);
+ /* ignore file if source is not within max / min size */
+ if (source_size.QuadPart < options.min_size ||
+ source_size.QuadPart > options.max_size)
+ {
+ CloseHandle(source_handle);
+ return FALSE;
+ }
+ CloseHandle(source_handle);
+ return TRUE;
+}
+
static BOOL perform_copy(struct robocopy_statistics *statistics)
{
struct list paths_source, paths_destination;
@@ -425,6 +458,9 @@ static BOOL perform_copy(struct robocopy_statistics *statistics)
}
else
{
+ /* ignore file if the file size is not within the allowed limits */
+ if (!is_valid_file(current_absolute_path)) continue;
+
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));
@@ -532,6 +568,16 @@ static WCHAR *get_option_string(void)
wcscat(temp_string, L"/MOV ");
}
+ /* Max File Size */
+ if (options.max_size != MAXLONGLONG)
+ swprintf(temp_string + wcslen(temp_string), ARRAY_SIZE(temp_string) - wcslen(temp_string),
+ L"/MAX:%lld ", options.max_size);
+
+ /* Min File Size */
+ if (options.min_size != 0)
+ swprintf(temp_string + wcslen(temp_string), ARRAY_SIZE(temp_string) - wcslen(temp_string),
+ L"/MIN:%lld ", options.min_size);
+
string = wcsdup(temp_string);
return string;
}
diff --git a/programs/robocopy/robocopy.h b/programs/robocopy/robocopy.h
index 9e3137109b8..0d498a9649c 100644
--- a/programs/robocopy/robocopy.h
+++ b/programs/robocopy/robocopy.h
@@ -46,6 +46,8 @@ struct robocopy_options {
BOOL purge_destination;
BOOL mirror;
BOOL dry_run;
+ LONGLONG min_size;
+ LONGLONG max_size;
};
struct robocopy_statistics {
--
2.32.0
More information about the wine-devel
mailing list