Implements the /L switch, which causes robocopy to do no real copy / move / delete operation
Signed-off-by: Florian Eder others.meder@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 {