Implements the /PURGE switch, which clears the destination directory and removes any extra files
Signed-off-by: Florian Eder others.meder@gmail.com --- programs/robocopy/main.c | 29 +++++++++++++++++++++++++++++ programs/robocopy/robocopy.h | 5 +++++ programs/robocopy/robocopy.rc | 4 ++++ 3 files changed, 38 insertions(+)
diff --git a/programs/robocopy/main.c b/programs/robocopy/main.c index 2d4195daaec..0bb0e83783c 100644 --- a/programs/robocopy/main.c +++ b/programs/robocopy/main.c @@ -157,6 +157,11 @@ static void parse_arguments(int argc, WCHAR *argv[]) if (!options.user_limited_subdirectories_depth) options.max_subdirectories_depth = 0; } + /* purge - Purge Destination */ + else if (!wcsicmp(argv[i], L"/purge")) + { + options.purge_destination = TRUE; + } /* mov - Delete files (but not folders) after copying them */ else if (!wcsicmp(argv[i], L"/mov")) { @@ -389,6 +394,26 @@ static BOOL perform_copy(struct robocopy_statistics *statistics) } if (found) continue; else statistics->extra_files = TRUE; + + /* if purge is specified (and xx is not set), we delete the (non-excluded) extra files and folders from the destination */ + if (options.purge_destination) + { + current_absolute_path = get_combined_path(options.destination, current_path->name); + /* only files or empty folders */ + if (!PathIsDirectoryW(current_absolute_path)) + { + if (!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)) + 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)); + } + } + else break; /* if purge's not set, we can just break LIST_FOR_EACH_ENTRY, no need to check further */ }
return TRUE; @@ -416,6 +441,10 @@ static WCHAR *get_option_string(void) if (options.copy_empty_subdirectories) wcscat(temp_string, L"/E ");
+ /* Purge */ + if (options.purge_destination) + wcscat(temp_string, L"/PURGE "); + /* Move files */ if (options.purge_source_files) wcscat(temp_string, L"/MOV "); diff --git a/programs/robocopy/robocopy.h b/programs/robocopy/robocopy.h index 677f88cb453..1417f8b0e1c 100644 --- a/programs/robocopy/robocopy.h +++ b/programs/robocopy/robocopy.h @@ -40,6 +40,7 @@ struct robocopy_options { BOOL copy_subdirectories; BOOL copy_empty_subdirectories; BOOL purge_source_files; + BOOL purge_destination; };
struct robocopy_statistics { @@ -65,7 +66,11 @@ struct robocopy_statistics { #define STRING_ERROR_READ_DIRECTORY 1011 #define STRING_ERROR_WRITE_DIRECTORY 1012 #define STRING_ERROR_WRITE_FILE 1014 +#define STRING_ERROR_DELETE_DIRECTORY 1016 +#define STRING_ERROR_DELETE_FILE 1017 #define STRING_STATISTICS 1018 #define STRING_CREATE_DIRECTORY 1019 +#define STRING_DELETE_DIRECTORY 1020 #define STRING_CREATE_FILE 1022 +#define STRING_DELETE_FILE 1023 #define STRING_MOVE_FILE 1024 \ No newline at end of file diff --git a/programs/robocopy/robocopy.rc b/programs/robocopy/robocopy.rc index b12501017e2..cdb03085315 100644 --- a/programs/robocopy/robocopy.rc +++ b/programs/robocopy/robocopy.rc @@ -35,9 +35,13 @@ STRINGTABLE STRING_ERROR_READ_DIRECTORY, "[%1] Error %2 (%3) occurred reading directory "%4":\n%5\n" STRING_ERROR_WRITE_DIRECTORY, "[%1] Error %2 (%3) occurred writing directory "%4":\n%5\n" STRING_ERROR_WRITE_FILE, "[%1] Error %2 (%3) occurred writing file "%4":\n%5\n" + STRING_ERROR_DELETE_DIRECTORY, "[%1] Error %2 (%3) occurred deleting directory "%4":\n%5\n" + STRING_ERROR_DELETE_FILE, "[%1] Error %2 (%3) occurred deleting file "%4":\n%5\n" STRING_STATISTICS, "\n Copied %1 directories and %2 files\n" STRING_CREATE_DIRECTORY, " Created Dir: %1\n" + STRING_DELETE_DIRECTORY, " Deleted Dir: %1\n" STRING_CREATE_FILE, " Copied File: %1\n" + STRING_DELETE_FILE, " Deleted File: %1\n" STRING_MOVE_FILE, " Moved File: %1\n" }