[PATCH 39/41] robocopy: add write to logfile flag (/LOG, /LOG+)

Florian Eder others.meder at gmail.com
Mon Sep 6 09:55:16 CDT 2021


Implements the /LOG:<path> and /LOG+:<path> arguments, which redirect
all output to a logfile

Signed-off-by: Florian Eder <others.meder at gmail.com>
---
 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




More information about the wine-devel mailing list