From: Florian Eder Subject: [PATCH 39/41] robocopy: add write to logfile flag (/LOG, /LOG+) Message-Id: <20210906145518.346132-39-others.meder@gmail.com> Date: Mon, 6 Sep 2021 14:55:16 +0000 In-Reply-To: <20210906145518.346132-1-others.meder@gmail.com> References: <20210906145518.346132-1-others.meder@gmail.com> Implements the /LOG: and /LOG+: arguments, which redirect all output to a logfile Signed-off-by: Florian Eder --- programs/robocopy/main.c | 39 ++++++++++++++++++++++++++++++++++-- programs/robocopy/robocopy.h | 2 ++ 2 files changed, 39 insertions(+), 2 deletions(-) diff --git a/programs/robocopy/main.c b/programs/robocopy/main.c index c54d7d9360c..5c3c51d052a 100644 --- a/programs/robocopy/main.c +++ b/programs/robocopy/main.c @@ -28,6 +28,7 @@ WINE_DEFAULT_DEBUG_CHANNEL(robocopy); #include "robocopy.h" struct robocopy_options options; +HANDLE logfile_handle; static void output_message(UINT format_string_id, ...) { @@ -52,8 +53,21 @@ static void output_message(UINT format_string_id, ...) return; } - /* If WriteConsole fails, the output is being redirected to a file */ - if (!WriteConsoleW(GetStdHandle(STD_OUTPUT_HANDLE), string, wcslen(string), &bytes_written, NULL)) + /* If a logfile handle is set, the output is written to this file / handle */ + if (logfile_handle != INVALID_HANDLE_VALUE) + { + CHAR *string_unicode; + DWORD length_unicode; + + length_unicode = WideCharToMultiByte(GetConsoleOutputCP(), 0, string, wcslen(string), NULL, 0, NULL, NULL); + string_unicode = malloc(length_unicode); + + WideCharToMultiByte(CP_UTF8, 0, string, wcslen(string), string_unicode, length_unicode, NULL, NULL); + WriteFile(logfile_handle, string_unicode, length_unicode, &bytes_written, NULL); + free(string_unicode); + } + /* Otherwise, if WriteConsole fails, the output is being redirected to a file */ + else if (!WriteConsoleW(GetStdHandle(STD_OUTPUT_HANDLE), string, wcslen(string), &bytes_written, NULL)) { CHAR *string_multibyte; DWORD length_multibyte; @@ -331,6 +345,21 @@ static void parse_arguments(int argc, WCHAR *argv[]) { parse_date_to_filetime(&(argv[i][8]), &options.min_time); } + /* log - output to logfile */ + else if (!wcsnicmp(argv[i], L"/log:", 5)) + { + if (wcslen(argv[i]) > 5) + options.logfile = wcsdup(&(argv[i][5])); + } + /* log+ - output to (appended) logfile */ + else if (!wcsnicmp(argv[i], L"/log+:", 6)) + { + if (wcslen(argv[i]) > 6) + { + options.logfile = wcsdup(&(argv[i][6])); + options.log_append = TRUE; + } + } else { WINE_FIXME("encountered an unknown robocopy flag: %S\n", argv[i]); @@ -796,6 +825,12 @@ int __cdecl wmain(int argc, WCHAR *argv[]) parse_arguments(argc, argv); + /* Open or create logfile if (and as) specified */ + if (options.logfile != NULL) + logfile_handle = CreateFileW(options.logfile, options.log_append ? FILE_APPEND_DATA : GENERIC_WRITE, + FILE_SHARE_READ, NULL, OPEN_ALWAYS, 0, NULL); + else logfile_handle = INVALID_HANDLE_VALUE; + /* If no file filters are set, set *.* to include all files */ if (options.files->size == 0) { diff --git a/programs/robocopy/robocopy.h b/programs/robocopy/robocopy.h index 459e5a7f8f7..c0bdd836e31 100644 --- a/programs/robocopy/robocopy.h +++ b/programs/robocopy/robocopy.h @@ -55,6 +55,8 @@ struct robocopy_options { BOOL dont_overwrite_changed_files; BOOL exclude_files_not_in_source; BOOL create_no_new_files; + WCHAR *logfile; + BOOL log_append; }; struct robocopy_statistics { -- 2.32.0