]> git.ipfire.org Git - thirdparty/bacula.git/commitdiff
allow double quote escaping in win32 bpipe
authornorbert.bizet <norbert.bizet@baculasystems.com>
Mon, 13 Mar 2023 14:54:04 +0000 (10:54 -0400)
committerEric Bollengier <eric@baculasystems.com>
Thu, 14 Sep 2023 11:57:01 +0000 (13:57 +0200)
bacula/src/lib/bpipe.c
bacula/src/lib/protos.h
bacula/src/win32/compat/compat.cpp

index 4eb05d442fb2700bad22f7d4112eeecd8d0fcd8e..e1833b32e8a2d8685507116b020936f0243d70f3 100644 (file)
@@ -512,7 +512,7 @@ int run_program(char *prog, int wait, POOLMEM *&results)
  *           non-zero on error == berrno status
  *
  */
-int run_program_full_output_and_error(char *prog, int wait, POOLMEM *&results, POOLMEM *&errors, char *env[])
+int run_program_full_output_and_error(char *prog, int wait, POOLMEM *&results, POOLMEM *&errors, char *env[], bool cmd_string_opt)
 {
    BPIPE *bpipe;
    int stat1=0, stat2=0, stat3=0;
@@ -536,7 +536,12 @@ int run_program_full_output_and_error(char *prog, int wait, POOLMEM *&results, P
       mode = (char *)"re";
    }
 
+#ifdef HAVE_WIN32
+   bpipe = open_bpipe(prog, wait, mode, env, cmd_string_opt);
+#else
+   (void) cmd_string_opt;
    bpipe = open_bpipe(prog, wait, mode, env);
+#endif
    if (!bpipe) {
       stat1 = ENOENT;
       goto bail_out;
@@ -635,7 +640,7 @@ bail_out:
 int run_program_full_output(char *prog, int wait, POOLMEM *&results, char *env[])
 {
    char *errors = NULL;
-   return run_program_full_output_and_error(prog, wait, results, errors, env);
+   return run_program_full_output_and_error(prog, wait, results, errors, env, false);
 }
 
 /*
index 644622b559c2fc50b449c62fde5106c2602afe22..ad2689171ecc3b375032523b36f3e79a73c6199f 100644 (file)
@@ -167,7 +167,12 @@ int        set_socket_errno(int sockstat);
 int      bget_msg(BSOCK *sock);
 
 /* bpipe.c */
+#ifdef HAVE_WIN32
+/* cmd_string_opt adds /s option to cmd invocation (win32 only)*/
+BPIPE *          open_bpipe(char *prog, int wait, const char *mode, char *envp[]=NULL, bool cmd_string_opt = false);
+#else
 BPIPE *          open_bpipe(char *prog, int wait, const char *mode, char *envp[]=NULL);
+#endif
 int              close_wpipe(BPIPE *bpipe);
 int              close_epipe(BPIPE *bpipe);
 int              close_bpipe(BPIPE *bpipe);
@@ -432,7 +437,7 @@ void             jobstatus_to_ascii      (int JobStatus, char *msg, int maxlen);
 void             jobstatus_to_ascii_gui  (int JobStatus, char *msg, int maxlen);
 int              run_program             (char *prog, int wait, POOLMEM *&results);
 int              run_program_full_output (char *prog, int wait, POOLMEM *&results, char *env[]=NULL);
-int              run_program_full_output_and_error(char *prog, int wait, POOLMEM *&results, POOLMEM *&errors, char *env[]=NULL);
+int              run_program_full_output_and_error(char *prog, int wait, POOLMEM *&results, POOLMEM *&errors, char *env[]=NULL, bool cmd_string_opt=false);
 char *           action_on_purge_to_string(int aop, POOL_MEM &ret);
 const char *     job_type_to_str         (int type);
 const char *     job_status_to_str       (int stat, int errors);
index 55407228d89f29b8a938d1a8619addeb9f4e5f10..2b16ca2328fd599e791e4476edd7cf4f882e757f 100644 (file)
@@ -2640,7 +2640,7 @@ CreateChildProcessA(const char *comspec, char *cmdLine,
  */
 HANDLE
 CreateChildProcess(const char *cmdline, HANDLE in, HANDLE out, HANDLE err,
-                    char * envp[] = NULL)
+                    char * envp[] = NULL, bool cmd_string_opt = false)
 {
    static const char *comspec = NULL;
    PROCESS_INFORMATION piProcInfo;
@@ -2676,7 +2676,18 @@ CreateChildProcess(const char *cmdline, HANDLE in, HANDLE out, HANDLE err,
    }
 
    POOL_MEM cmdLine(PM_FNAME);
-   Mmsg(cmdLine, "%s /c \"%s\"%s", comspec, exeFile, argStart);
+   if (cmd_string_opt) {
+      /* For working around multiple double quotes in the exe and arguments, we use the /s cmd option */
+      /* /s skips the parsing rules of /c and only strips the first and last quote so:
+      /*  cmd.exe /s /c ""C:\program files\myexe.exe" -file "C:\program files\args.txt"" will respect both */
+      /* "C:\program files\myexe.exe" and "C:\program files\args.txt" quotes */
+      Mmsg(cmdLine, "%s /s /c \"\"%s\"%s\"", comspec, exeFile, argStart);
+   } else { 
+      /* regular cmd call: cmd.exe /c "C:\program files\myexe.exe" -args C:\PROGR~1\args.txt */
+      /* arguments should not contain double quotes */
+      Mmsg(cmdLine, "%s /c \"%s\"%s", comspec, exeFile, argStart);
+   }
+   
 
    free(exeFile);
 
@@ -2737,7 +2748,7 @@ CloseHandleIfValid(HANDLE handle)
 #define MODE_NOSTDERR 16
 
 BPIPE *
-open_bpipe(char *prog, int wait, const char *mode, char *envp[])
+open_bpipe(char *prog, int wait, const char *mode, char *envp[], bool cmd_string_opt)
 {
     HANDLE hChildStdinRd, hChildStdinWr, hChildStdinWrDup,
         hChildStdoutRd, hChildStdoutWr, hChildStdoutRdDup,
@@ -2850,7 +2861,8 @@ open_bpipe(char *prog, int wait, const char *mode, char *envp[])
                            hChildStdoutWr,   // stdout HANDLE
                            (mode_map & MODE_STDERR || mode_map & MODE_NOSTDERR)
                                ? hChildStderrWr:hChildStdoutWr,   // stderr HANDLE
-                           envp); // envp  environment variables are added to the current process env var set.
+                           envp,
+                           cmd_string_opt); // envp  environment variables are added to the current process env var set.
 
     if ((HANDLE) bpipe->worker_pid == INVALID_HANDLE_VALUE) {
        ErrorExit("CreateChildProcess failed");