]> git.sur5r.net Git - bacula/bacula/commitdiff
ebl New implementation for runscript with multiple command/console
authorEric Bollengier <eric@eb.homelinux.org>
Thu, 3 Jan 2008 22:24:35 +0000 (22:24 +0000)
committerEric Bollengier <eric@eb.homelinux.org>
Thu, 3 Jan 2008 22:24:35 +0000 (22:24 +0000)
git-svn-id: https://bacula.svn.sourceforge.net/svnroot/bacula/trunk@6193 91ce42f0-d328-0410-95d8-f526ca767f89

bacula/patches/testing/runscript_with_multiple_command.patch
bacula/patches/testing/runscript_with_multiple_command_v2.patch [new file with mode: 0644]

index 1d9251afc52ece965dd6c6eb7c2fc441e60a3d38..0b7e915d6b52056649a68ad560f862c405557289 100644 (file)
@@ -1,990 +1,3 @@
-Index: patches/testing/runscript_with_multiple_command.patch
-===================================================================
---- patches/testing/runscript_with_multiple_command.patch      (révision 6171)
-+++ patches/testing/runscript_with_multiple_command.patch      (copie de travail)
-@@ -1,982 +0,0 @@
--Index: patches/testing/runscript_with_multiple_command.patch
--===================================================================
----- patches/testing/runscript_with_multiple_command.patch     (révision 6170)
--+++ patches/testing/runscript_with_multiple_command.patch     (copie de travail)
--@@ -1,483 +0,0 @@
---Index: src/dird/fd_cmds.c
---===================================================================
------ src/dird/fd_cmds.c       (révision 6169)
---+++ src/dird/fd_cmds.c       (copie de travail)
---@@ -537,29 +537,35 @@
---          Dmsg2(200, "bdird: runscript %s -> %s\n", cmd->target, ehost);
--- 
---          if (strcmp(ehost, jcr->client->name()) == 0) {
----            pm_strcpy(msg, cmd->command);
----            bash_spaces(msg);
---+            char *c;
---+            char *command, cmd_type;
---+            foreach_alist(c, cmd->commands) {
---+               cmd->get_command(c, &cmd_type, &command);
---+               if (cmd_type == SHELL_CMD) {
---+                  pm_strcpy(msg, command);
---+                  bash_spaces(msg);
--- 
----            Dmsg1(120, "bdird: sending runscripts to fd '%s'\n", cmd->command);
---+                  Dmsg1(120, "bdird: sending runscripts to fd '%s'\n", command);
---             
----            /* TODO: remove this with bacula 1.42 */
----            if (cmd->old_proto) {
----               result = send_runscript_with_old_proto(jcr, cmd->when, msg);
---+                  /* TODO: remove this with bacula 1.42 */
---+                  if (cmd->old_proto) {
---+                     result = send_runscript_with_old_proto(jcr, cmd->when, msg);
---+                     
---+                  } else {
---+                     fd->fsend(runscript, cmd->on_success, 
---+                                          cmd->on_failure,
---+                                          cmd->fail_on_error,
---+                                          cmd->when,
---+                                          msg);
--- 
----            } else {
----               fd->fsend(runscript, cmd->on_success, 
----                                    cmd->on_failure,
----                                    cmd->fail_on_error,
----                                    cmd->when,
----                                    msg);
----
----               result = response(jcr, fd, OKRunScript, "RunScript", DISPLAY_ERROR);
----               launch_before_cmd = true;
---+                     result = response(jcr, fd, OKRunScript, "RunScript", DISPLAY_ERROR);
---+                     launch_before_cmd = true;
---+                  }
---+                  if (!result) {
---+                     goto bail_out;
---+                  }
---+               }
---             }
----            
----            if (!result) {
----               goto bail_out;
----            }
---          }
---          /* TODO : we have to play with other client */
---          /*
---@@ -567,7 +573,7 @@
---            send command to an other client
---            }
---          */
----      }        
---+      }
---    } 
--- 
---    /* Tell the FD to execute the ClientRunBeforeJob */
---Index: src/dird/dird_conf.c
---===================================================================
------ src/dird/dird_conf.c     (révision 6169)
---+++ src/dird/dird_conf.c     (copie de travail)
---@@ -651,16 +651,19 @@
---          }
---       }
---       if (res->res_job.RunScripts) {
----        RUNSCRIPT *script;
----        foreach_alist(script, res->res_job.RunScripts) {
----           sendit(sock, _(" --> RunScript\n"));
----           sendit(sock, _("  --> Command=%s\n"), NPRT(script->command));
----           sendit(sock, _("  --> Target=%s\n"),  NPRT(script->target));
----           sendit(sock, _("  --> RunOnSuccess=%u\n"),  script->on_success);
----           sendit(sock, _("  --> RunOnFailure=%u\n"),  script->on_failure);
----           sendit(sock, _("  --> FailJobOnError=%u\n"),  script->fail_on_error);
----           sendit(sock, _("  --> RunWhen=%u\n"),  script->when);
----        }
---+         char *c;
---+         RUNSCRIPT *script;
---+         foreach_alist(script, res->res_job.RunScripts) {
---+            sendit(sock, _(" --> RunScript\n"));
---+            foreach_alist(c, script->commands) {
---+               sendit(sock, _("  --> Command=%s\n"), NPRT(c));
---+            }
---+            sendit(sock, _("  --> Target=%s\n"),  NPRT(script->target));
---+            sendit(sock, _("  --> RunOnSuccess=%u\n"),  script->on_success);
---+            sendit(sock, _("  --> RunOnFailure=%u\n"),  script->on_failure);
---+            sendit(sock, _("  --> FailJobOnError=%u\n"),  script->fail_on_error);
---+            sendit(sock, _("  --> RunWhen=%u\n"),  script->when);
---+         }
---       }
---       if (res->res_job.pool) {
---          sendit(sock, _("  --> "));
---@@ -1724,14 +1727,14 @@
--- }
--- 
--- /*
---- * Store a runscript->command as a string
---+ * Store a runscript->commands as a alist(char + string)
---  */
--- static void store_runscript_cmd(LEX *lc, RES_ITEM *item, int index, int pass)
--- {
---    lex_get_token(lc, T_STRING);
--- 
---    if (pass == 2) {
----      ((RUNSCRIPT*)item->value)->set_command(lc->str, item->code);
---+      ((RUNSCRIPT*)item->value)->add_command(lc->str, item->code);
---    }
---    scan_to_eol(lc);
--- }
---@@ -1745,7 +1748,7 @@
---       RUNSCRIPT *script = new_runscript();
---       script->set_job_code_callback(job_code_callback_filesetname);
--- 
----      script->set_command(lc->str);
---+      script->add_command(lc->str);
--- 
---       /* TODO: remove all script->old_proto with bacula 1.42 */
--- 
---@@ -1873,7 +1876,7 @@
---    }
--- 
---    if (pass == 2) {
----      if (res_runscript.command == NULL) {
---+      if (res_runscript.commands == NULL) {
---          scan_err2(lc, _("%s item is required in %s resource, but not found.\n"),
---                    "command", "runscript");
---       }
---@@ -1883,10 +1886,11 @@
---          res_runscript.set_target("%c");
---       }
--- 
----      RUNSCRIPT *script = new_runscript();
----      memcpy(script, &res_runscript, sizeof(RUNSCRIPT));
---+      RUNSCRIPT *script = copy_runscript(&res_runscript);
---+      res_runscript.reset_default(true);
---+
---       script->set_job_code_callback(job_code_callback_filesetname);
----      
---+
---       if (*runscripts == NULL) {
---         *runscripts = New(alist(10, not_owned_by_alist));
---       }
---Index: src/filed/job.c
---===================================================================
------ src/filed/job.c  (révision 6169)
---+++ src/filed/job.c  (copie de travail)
---@@ -481,7 +481,7 @@
--- 
---    /* Run the command now */
---    script = new_runscript();
----   script->set_command(cmd);
---+   script->add_command(cmd);
---    script->when = SCRIPT_Before;
---    ok = script->run(jcr, "ClientRunBeforeJob");
---    free_runscript(script);
---@@ -529,7 +529,7 @@
---    unbash_spaces(msg);
--- 
---    cmd = new_runscript();
----   cmd->set_command(msg);
---+   cmd->add_command(msg);
---    cmd->on_success = true;
---    cmd->on_failure = false;
---    cmd->when = SCRIPT_After;
---@@ -567,7 +567,7 @@
---    cmd->fail_on_error = fail_on_error;
---    unbash_spaces(msg);
--- 
----   cmd->set_command(msg);
---+   cmd->add_command(msg);
---    cmd->debug();
---    jcr->RunScripts->append(cmd);
--- 
---Index: src/lib/runscript.h
---===================================================================
------ src/lib/runscript.h      (révision 6169)
---+++ src/lib/runscript.h      (copie de travail)
---@@ -62,8 +62,8 @@
--- };
--- 
--- enum {
----   SHELL_CMD   = 1,
----   CONSOLE_CMD = 2 
---+   SHELL_CMD   = '|',
---+   CONSOLE_CMD = '@' 
--- };
--- 
--- /*
---@@ -71,10 +71,9 @@
---  */
--- class RUNSCRIPT {
--- public:
----   POOLMEM *command;            /* command string */
---+   alist *commands;             /* list of command/console string */
---    POOLMEM *target;             /* host target */
---    int  when;                   /* SCRIPT_Before|Script_After BEFORE/AFTER JOB*/
----   int  cmd_type;               /* Command type -- Shell, Console */
---    char level;                  /* Base|Full|Incr...|All (NYI) */
---    bool on_success;             /* execute command on job success (After) */
---    bool on_failure;             /* execute command on job failure (After) */
---@@ -85,8 +84,10 @@
---                                 /* Optional callback function passed to edit_job_code */
--- 
---    bool run(JCR *job, const char *name=""); /* name must contain "Before" or "After" keyword */
---+   bool run_command(const char *cmd, JCR *job, const char *name="");
---    bool can_run_at_level(int JobLevel) { return true;};        /* TODO */
----   void set_command(const POOLMEM *cmd, int cmd_type = SHELL_CMD);
---+   void add_command(const POOLMEM *cmd, char cmd_type = SHELL_CMD);
---+   void get_command(const char *cmd, char *cmd_type, char **cmd);
---    void set_target(const POOLMEM *client_name);
---    void reset_default(bool free_string = false);
---    bool is_local();             /* true if running on local host */
---Index: src/lib/runscript.c
---===================================================================
------ src/lib/runscript.c      (révision 6169)
---+++ src/lib/runscript.c      (copie de travail)
---@@ -59,15 +59,20 @@
--- 
--- void RUNSCRIPT::reset_default(bool free_strings)
--- {
----   if (free_strings && command) {
----     free_pool_memory(command);
---+   char *c;
---+   if (free_strings && commands) {
---+      foreach_alist(c, commands) {
---+         free_pool_memory(c);
---+      }
---    }
---    if (free_strings && target) {
---      free_pool_memory(target);
---    }
----   
---    target = NULL;
----   command = NULL;
---+   if (commands) {
---+      delete commands;
---+      commands = NULL;
---+   }
---    on_success = true;
---    on_failure = false;
---    fail_on_error = true;
---@@ -76,17 +81,23 @@
---    job_code_callback = NULL;
--- }
--- 
----RUNSCRIPT *copy_runscript(RUNSCRIPT *src)
---+Runscript *copy_runscript(RUNSCRIPT *src)
--- {
---    Dmsg0(500, "runscript: creating new RUNSCRIPT object from other\n");
--- 
---    RUNSCRIPT *dst = (RUNSCRIPT *)malloc(sizeof(RUNSCRIPT));
---    memcpy(dst, src, sizeof(RUNSCRIPT));
--- 
----   dst->command = NULL;
---+   dst->commands =  New(alist(5, not_owned_by_alist));
---+   char *c;
---+   POOLMEM *m;
---+   foreach_alist(c, src->commands) {
---+      m = get_pool_memory(PM_FNAME);
---+      pm_strcpy(m, c);
---+      dst->commands->append(m);
---+   }
---+
---    dst->target = NULL;
----
----   dst->set_command(src->command, src->cmd_type);
---    dst->set_target(src->target);
--- 
---    return dst;   
---@@ -95,9 +106,12 @@
--- void free_runscript(RUNSCRIPT *script)
--- {
---    Dmsg0(500, "runscript: freeing RUNSCRIPT object\n");
----
----   if (script->command) {
----      free_pool_memory(script->command);
---+   POOLMEM *c;
---+   if (script->commands) {
---+      foreach_alist(c, script->commands) {
---+         free_pool_memory(c);
---+      }
---+      delete script->commands;
---    }
---    if (script->target) {
---       free_pool_memory(script->target);
---@@ -108,60 +122,15 @@
--- int run_scripts(JCR *jcr, alist *runscripts, const char *label)
--- {
---    Dmsg2(200, "runscript: running all RUNSCRIPT object (%s) JobStatus=%c\n", label, jcr->JobStatus);
----   
----   RUNSCRIPT *script;
----   bool runit;
--- 
----   int when;
----
----   if (strstr(label, NT_("Before"))) {
----      when = SCRIPT_Before;
----   } else {
----      when = SCRIPT_After;
----   }
----
---    if (runscripts == NULL) {
---       Dmsg0(100, "runscript: WARNING RUNSCRIPTS list is NULL\n");
---       return 0;
---    }
----
---+   
---+   RUNSCRIPT *script;
---    foreach_alist(script, runscripts) {
----      Dmsg2(200, "runscript: try to run %s:%s\n", NPRT(script->target), NPRT(script->command));
----      runit = false;
----
----      if ((script->when & SCRIPT_Before) && (when & SCRIPT_Before)) {
----         if ((script->on_success 
----            && (jcr->JobStatus == JS_Running || jcr->JobStatus == JS_Created))
----            || (script->on_failure && job_canceled(jcr))
----            )
----         {
----            Dmsg4(200, "runscript: Run it because SCRIPT_Before (%s,%i,%i,%c)\n", 
----                  script->command, script->on_success, script->on_failure,
----                  jcr->JobStatus );
----            runit = true;
----         }
----      }
----
----      if ((script->when & SCRIPT_After) && (when & SCRIPT_After)) {
----         if ((script->on_success && (jcr->JobStatus == JS_Terminated))
----             || (script->on_failure && job_canceled(jcr))
----            )
----         {
----            Dmsg4(200, "runscript: Run it because SCRIPT_After (%s,%i,%i,%c)\n", 
----                  script->command, script->on_success, script->on_failure,
----                  jcr->JobStatus );
----            runit = true;
----         }
----      }
----
----      if (!script->is_local()) {
----         runit = false;
----      }
----
----      /* we execute it */
----      if (runit) {
----         script->run(jcr, label);
----      }
---+      script->run(jcr, label);
---    }
---    return 1;
--- }
---@@ -176,7 +145,7 @@
--- }
--- 
--- /* set this->command to cmd */
----void RUNSCRIPT::set_command(const POOLMEM *cmd, int acmd_type)
---+void RUNSCRIPT::add_command(const POOLMEM *cmd, char acmd_type)
--- {
---    Dmsg1(500, "runscript: setting command = %s\n", NPRT(cmd));
--- 
---@@ -184,14 +153,21 @@
---       return;
---    }
--- 
----   if (!command) {
----      command = get_pool_memory(PM_FNAME);
---+   if (!commands) {
---+      commands = New(alist(5, not_owned_by_alist)); 
---    }
--- 
----   pm_strcpy(command, cmd);
----   cmd_type = acmd_type;
---+   POOLMEM *c = get_pool_memory(PM_FNAME);
---+   Mmsg(c, "%c%s", acmd_type, cmd);
---+   commands->append(c);
--- }
--- 
---+void RUNSCRIPT::get_command(const char* command, char *acmd_type, char **cmd)
---+{
---+   *acmd_type = command[0];
---+   *cmd = (char *)command + 1;
---+}
---+
--- /* set this->target to client_name */
--- void RUNSCRIPT::set_target(const POOLMEM *client_name)
--- {
---@@ -210,14 +186,71 @@
--- 
--- bool RUNSCRIPT::run(JCR *jcr, const char *name)
--- {
----   Dmsg1(100, "runscript: running a RUNSCRIPT object type=%d\n", cmd_type);
---+   char *c;
---+   bool runit;
---+
---+   int when;
---+
---+   if (strstr(name, NT_("Before"))) {
---+      when = SCRIPT_Before;
---+   } else {
---+      when = SCRIPT_After;
---+   }
---+
---+   foreach_alist(c, this->commands) {
---+      Dmsg2(200, "runscript: try to run %s:%s\n", NPRT(this->target), NPRT(c));
---+      runit = false;
---+
---+      if ((this->when & SCRIPT_Before) && (when & SCRIPT_Before)) {
---+         if ((this->on_success 
---+            && (jcr->JobStatus == JS_Running || jcr->JobStatus == JS_Created))
---+            || (this->on_failure && job_canceled(jcr))
---+            )
---+         {
---+            Dmsg4(200, "runscript: Run it because SCRIPT_Before (%s,%i,%i,%c)\n", 
---+                  c, this->on_success, this->on_failure,
---+                  jcr->JobStatus );
---+            runit = true;
---+         }
---+      }
---+
---+      if ((this->when & SCRIPT_After) && (when & SCRIPT_After)) {
---+         if ((this->on_success && (jcr->JobStatus == JS_Terminated))
---+             || (this->on_failure && job_canceled(jcr))
---+            )
---+         {
---+            Dmsg4(200, "runscript: Run it because SCRIPT_After (%s,%i,%i,%c)\n", 
---+                  c, this->on_success, this->on_failure,
---+                  jcr->JobStatus );
---+            runit = true;
---+         }
---+      }
---+
---+      if (!this->is_local()) {
---+         runit = false;
---+      }
---+
---+      /* we execute it */
---+      if (runit) {
---+         this->run_command(c, jcr, name);
---+      }
---+   }
---+   return 1;
---+}
---+
---+bool RUNSCRIPT::run_command(const char *command, JCR *jcr, const char *name)
---+{
---    POOLMEM *ecmd = get_pool_memory(PM_FNAME);
---    int status;
---    BPIPE *bpipe;
---    char line[MAXSTRING];
---+   char cmd_type;
---+   char *cmd;
--- 
----   ecmd = edit_job_codes(jcr, ecmd, this->command, "", this->job_code_callback);
----   Dmsg1(100, "runscript: running '%s'...\n", ecmd);
---+   this->get_command(command, &cmd_type, &cmd);
---+   ecmd = edit_job_codes(jcr, ecmd, cmd, "", this->job_code_callback);
---+
---+   Dmsg2(100, "runscript: running '%s' object type=%c...\n", ecmd, cmd_type);
---    Jmsg(jcr, M_INFO, 0, _("%s: run %s \"%s\"\n"), 
---         cmd_type==SHELL_CMD?"shell command":"console command", name, ecmd);
--- 
---@@ -278,9 +311,12 @@
--- 
--- void RUNSCRIPT::debug()
--- {
---+   char *c;
---    Dmsg0(200, "runscript: debug\n");
---    Dmsg0(200,  _(" --> RunScript\n"));
----   Dmsg1(200,  _("  --> Command=%s\n"), NPRT(command));
---+   foreach_alist(c, commands) {
---+      Dmsg1(200,  _("  --> Command=%s\n"), NPRT(c));
---+   }
---    Dmsg1(200,  _("  --> Target=%s\n"),  NPRT(target));
---    Dmsg1(200,  _("  --> RunOnSuccess=%u\n"),  on_success);
---    Dmsg1(200,  _("  --> RunOnFailure=%u\n"),  on_failure);
--Index: src/dird/fd_cmds.c
--===================================================================
----- src/dird/fd_cmds.c        (révision 6169)
--+++ src/dird/fd_cmds.c        (copie de travail)
--@@ -527,7 +527,8 @@
--    RUNSCRIPT *cmd;
--    bool launch_before_cmd = false;
--    POOLMEM *ehost = get_pool_memory(PM_FNAME);
---   int result;
--+   int result, cmd_type;
--+   char *c, *command;
-- 
--    Dmsg0(120, "bdird: sending runscripts to fd\n");
--    
--@@ -537,29 +538,33 @@
--          Dmsg2(200, "bdird: runscript %s -> %s\n", cmd->target, ehost);
-- 
--          if (strcmp(ehost, jcr->client->name()) == 0) {
---            pm_strcpy(msg, cmd->command);
---            bash_spaces(msg);
--+            foreach_alist(c, cmd->commands) {
--+               cmd->get_command(c, &cmd_type, &command);
--+               if (cmd_type == SHELL_CMD) {
--+                  pm_strcpy(msg, command);
--+                  bash_spaces(msg);
-- 
---            Dmsg1(120, "bdird: sending runscripts to fd '%s'\n", cmd->command);
--+                  Dmsg1(120, "bdird: sending runscripts to fd '%s'\n", command);
--             
---            /* TODO: remove this with bacula 1.42 */
---            if (cmd->old_proto) {
---               result = send_runscript_with_old_proto(jcr, cmd->when, msg);
--+                  /* TODO: remove this with bacula 1.42 */
--+                  if (cmd->old_proto) {
--+                     result = send_runscript_with_old_proto(jcr, cmd->when, msg);
--+                     
--+                  } else {
--+                     fd->fsend(runscript, cmd->on_success, 
--+                                          cmd->on_failure,
--+                                          cmd->fail_on_error,
--+                                          cmd->when,
--+                                          msg);
-- 
---            } else {
---               fd->fsend(runscript, cmd->on_success, 
---                                    cmd->on_failure,
---                                    cmd->fail_on_error,
---                                    cmd->when,
---                                    msg);
---
---               result = response(jcr, fd, OKRunScript, "RunScript", DISPLAY_ERROR);
---               launch_before_cmd = true;
--+                     result = response(jcr, fd, OKRunScript, "RunScript", DISPLAY_ERROR);
--+                     launch_before_cmd = true;
--+                  }
--+                  if (!result) {
--+                     goto bail_out;
--+                  }
--+               }
--             }
---            
---            if (!result) {
---               goto bail_out;
---            }
--          }
--          /* TODO : we have to play with other client */
--          /*
--@@ -567,7 +572,7 @@
--            send command to an other client
--            }
--          */
---      }        
--+      }
--    } 
-- 
--    /* Tell the FD to execute the ClientRunBeforeJob */
--Index: src/dird/dird_conf.c
--===================================================================
----- src/dird/dird_conf.c      (révision 6169)
--+++ src/dird/dird_conf.c      (copie de travail)
--@@ -651,16 +651,19 @@
--          }
--       }
--       if (res->res_job.RunScripts) {
---        RUNSCRIPT *script;
---        foreach_alist(script, res->res_job.RunScripts) {
---           sendit(sock, _(" --> RunScript\n"));
---           sendit(sock, _("  --> Command=%s\n"), NPRT(script->command));
---           sendit(sock, _("  --> Target=%s\n"),  NPRT(script->target));
---           sendit(sock, _("  --> RunOnSuccess=%u\n"),  script->on_success);
---           sendit(sock, _("  --> RunOnFailure=%u\n"),  script->on_failure);
---           sendit(sock, _("  --> FailJobOnError=%u\n"),  script->fail_on_error);
---           sendit(sock, _("  --> RunWhen=%u\n"),  script->when);
---        }
--+         char *c;
--+         RUNSCRIPT *script;
--+         foreach_alist(script, res->res_job.RunScripts) {
--+            sendit(sock, _(" --> RunScript\n"));
--+            foreach_alist(c, script->commands) {
--+               sendit(sock, _("  --> Command=%s\n"), NPRT(c));
--+            }
--+            sendit(sock, _("  --> Target=%s\n"),  NPRT(script->target));
--+            sendit(sock, _("  --> RunOnSuccess=%u\n"),  script->on_success);
--+            sendit(sock, _("  --> RunOnFailure=%u\n"),  script->on_failure);
--+            sendit(sock, _("  --> FailJobOnError=%u\n"),  script->fail_on_error);
--+            sendit(sock, _("  --> RunWhen=%u\n"),  script->when);
--+         }
--       }
--       if (res->res_job.pool) {
--          sendit(sock, _("  --> "));
--@@ -1724,14 +1727,14 @@
-- }
-- 
-- /*
--- * Store a runscript->command as a string
--+ * Store a runscript->commands as a alist(char + string)
--  */
-- static void store_runscript_cmd(LEX *lc, RES_ITEM *item, int index, int pass)
-- {
--    lex_get_token(lc, T_STRING);
-- 
--    if (pass == 2) {
---      ((RUNSCRIPT*)item->value)->set_command(lc->str, item->code);
--+      ((RUNSCRIPT*)item->value)->add_command(lc->str, item->code);
--    }
--    scan_to_eol(lc);
-- }
--@@ -1745,7 +1748,7 @@
--       RUNSCRIPT *script = new_runscript();
--       script->set_job_code_callback(job_code_callback_filesetname);
-- 
---      script->set_command(lc->str);
--+      script->add_command(lc->str);
-- 
--       /* TODO: remove all script->old_proto with bacula 1.42 */
-- 
--@@ -1873,7 +1876,7 @@
--    }
-- 
--    if (pass == 2) {
---      if (res_runscript.command == NULL) {
--+      if (res_runscript.commands == NULL) {
--          scan_err2(lc, _("%s item is required in %s resource, but not found.\n"),
--                    "command", "runscript");
--       }
--@@ -1886,7 +1889,7 @@
--       RUNSCRIPT *script = new_runscript();
--       memcpy(script, &res_runscript, sizeof(RUNSCRIPT));
--       script->set_job_code_callback(job_code_callback_filesetname);
---      
--+
--       if (*runscripts == NULL) {
--         *runscripts = New(alist(10, not_owned_by_alist));
--       }
--Index: src/filed/job.c
--===================================================================
----- src/filed/job.c   (révision 6169)
--+++ src/filed/job.c   (copie de travail)
--@@ -481,7 +481,7 @@
-- 
--    /* Run the command now */
--    script = new_runscript();
---   script->set_command(cmd);
--+   script->add_command(cmd);
--    script->when = SCRIPT_Before;
--    ok = script->run(jcr, "ClientRunBeforeJob");
--    free_runscript(script);
--@@ -529,7 +529,7 @@
--    unbash_spaces(msg);
-- 
--    cmd = new_runscript();
---   cmd->set_command(msg);
--+   cmd->add_command(msg);
--    cmd->on_success = true;
--    cmd->on_failure = false;
--    cmd->when = SCRIPT_After;
--@@ -567,7 +567,7 @@
--    cmd->fail_on_error = fail_on_error;
--    unbash_spaces(msg);
-- 
---   cmd->set_command(msg);
--+   cmd->add_command(msg);
--    cmd->debug();
--    jcr->RunScripts->append(cmd);
-- 
--Index: src/lib/runscript.h
--===================================================================
----- src/lib/runscript.h       (révision 6169)
--+++ src/lib/runscript.h       (copie de travail)
--@@ -62,8 +62,8 @@
-- };
-- 
-- enum {
---   SHELL_CMD   = 1,
---   CONSOLE_CMD = 2 
--+   SHELL_CMD   = '|',
--+   CONSOLE_CMD = '@' 
-- };
-- 
-- /*
--@@ -71,10 +71,9 @@
--  */
-- class RUNSCRIPT {
-- public:
---   POOLMEM *command;            /* command string */
--+   alist *commands;             /* list of command/console string */
--    POOLMEM *target;             /* host target */
--    int  when;                   /* SCRIPT_Before|Script_After BEFORE/AFTER JOB*/
---   int  cmd_type;               /* Command type -- Shell, Console */
--    char level;                  /* Base|Full|Incr...|All (NYI) */
--    bool on_success;             /* execute command on job success (After) */
--    bool on_failure;             /* execute command on job failure (After) */
--@@ -86,19 +85,22 @@
-- 
--    bool run(JCR *job, const char *name=""); /* name must contain "Before" or "After" keyword */
--    bool can_run_at_level(int JobLevel) { return true;};        /* TODO */
---   void set_command(const POOLMEM *cmd, int cmd_type = SHELL_CMD);
--+   void add_command(const POOLMEM *cmd, char cmd_type = SHELL_CMD);
--+   void get_command(const char *cmd, int *cmd_type, char **cmd);
--    void set_target(const POOLMEM *client_name);
--    void reset_default(bool free_string = false);
--    bool is_local();             /* true if running on local host */
--    void debug();
--+   void set_job_code_callback(job_code_callback_t job_code_callback);
-- 
---   void set_job_code_callback(job_code_callback_t job_code_callback);
--+private:
--+   bool run_command(const char *cmd, JCR *job, const char *name="");
-- };
-- 
-- /* create new RUNSCRIPT (set all value to 0) */
-- RUNSCRIPT *new_runscript();           
-- 
---/* create new RUNSCRIPT from an other */
--+/* create new RUNSCRIPT from an other (deep copy) */
-- RUNSCRIPT *copy_runscript(RUNSCRIPT *src);
-- 
-- /* launch each script from runscripts*/
--Index: src/lib/runscript.c
--===================================================================
----- src/lib/runscript.c       (révision 6169)
--+++ src/lib/runscript.c       (copie de travail)
--@@ -59,15 +59,18 @@
-- 
-- void RUNSCRIPT::reset_default(bool free_strings)
-- {
---   if (free_strings && command) {
---     free_pool_memory(command);
--+   char *c;
--+   if (free_strings && commands) {
--+      foreach_alist(c, commands) {
--+         free_pool_memory(c);
--+      }
--+      delete commands;
--    }
--    if (free_strings && target) {
--      free_pool_memory(target);
--    }
---   
--    target = NULL;
---   command = NULL;
--+   commands = NULL;
--    on_success = true;
--    on_failure = false;
--    fail_on_error = true;
--@@ -83,10 +86,16 @@
--    RUNSCRIPT *dst = (RUNSCRIPT *)malloc(sizeof(RUNSCRIPT));
--    memcpy(dst, src, sizeof(RUNSCRIPT));
-- 
---   dst->command = NULL;
--+   dst->commands =  New(alist(5, not_owned_by_alist));
--+   char *c;
--+   POOLMEM *m;
--+   foreach_alist(c, src->commands) {
--+      m = get_pool_memory(PM_FNAME);
--+      pm_strcpy(m, c);
--+      dst->commands->append(m);
--+   }
--+
--    dst->target = NULL;
---
---   dst->set_command(src->command, src->cmd_type);
--    dst->set_target(src->target);
-- 
--    return dst;   
--@@ -95,9 +104,12 @@
-- void free_runscript(RUNSCRIPT *script)
-- {
--    Dmsg0(500, "runscript: freeing RUNSCRIPT object\n");
---
---   if (script->command) {
---      free_pool_memory(script->command);
--+   POOLMEM *c;
--+   if (script->commands) {
--+      foreach_alist(c, script->commands) {
--+         free_pool_memory(c);
--+      }
--+      delete script->commands;
--    }
--    if (script->target) {
--       free_pool_memory(script->target);
--@@ -108,60 +120,15 @@
-- int run_scripts(JCR *jcr, alist *runscripts, const char *label)
-- {
--    Dmsg2(200, "runscript: running all RUNSCRIPT object (%s) JobStatus=%c\n", label, jcr->JobStatus);
---   
---   RUNSCRIPT *script;
---   bool runit;
-- 
---   int when;
---
---   if (strstr(label, NT_("Before"))) {
---      when = SCRIPT_Before;
---   } else {
---      when = SCRIPT_After;
---   }
---
--    if (runscripts == NULL) {
--       Dmsg0(100, "runscript: WARNING RUNSCRIPTS list is NULL\n");
--       return 0;
--    }
---
--+   
--+   RUNSCRIPT *script;
--    foreach_alist(script, runscripts) {
---      Dmsg2(200, "runscript: try to run %s:%s\n", NPRT(script->target), NPRT(script->command));
---      runit = false;
---
---      if ((script->when & SCRIPT_Before) && (when & SCRIPT_Before)) {
---         if ((script->on_success 
---            && (jcr->JobStatus == JS_Running || jcr->JobStatus == JS_Created))
---            || (script->on_failure && job_canceled(jcr))
---            )
---         {
---            Dmsg4(200, "runscript: Run it because SCRIPT_Before (%s,%i,%i,%c)\n", 
---                  script->command, script->on_success, script->on_failure,
---                  jcr->JobStatus );
---            runit = true;
---         }
---      }
---
---      if ((script->when & SCRIPT_After) && (when & SCRIPT_After)) {
---         if ((script->on_success && (jcr->JobStatus == JS_Terminated))
---             || (script->on_failure && job_canceled(jcr))
---            )
---         {
---            Dmsg4(200, "runscript: Run it because SCRIPT_After (%s,%i,%i,%c)\n", 
---                  script->command, script->on_success, script->on_failure,
---                  jcr->JobStatus );
---            runit = true;
---         }
---      }
---
---      if (!script->is_local()) {
---         runit = false;
---      }
---
---      /* we execute it */
---      if (runit) {
---         script->run(jcr, label);
---      }
--+      script->run(jcr, label);
--    }
--    return 1;
-- }
--@@ -175,23 +142,31 @@
--    }
-- }
-- 
---/* set this->command to cmd */
---void RUNSCRIPT::set_command(const POOLMEM *cmd, int acmd_type)
--+/* set add cmd to this->commands alist */
--+void RUNSCRIPT::add_command(const POOLMEM *cmd, char acmd_type)
-- {
---   Dmsg1(500, "runscript: setting command = %s\n", NPRT(cmd));
--+   Dmsg2(500, "runscript: setting command = %s type=%i\n", NPRT(cmd), acmd_type);
-- 
--    if (!cmd) {
--       return;
--    }
-- 
---   if (!command) {
---      command = get_pool_memory(PM_FNAME);
--+   if (!commands) {
--+      commands = New(alist(5, not_owned_by_alist)); 
--    }
-- 
---   pm_strcpy(command, cmd);
---   cmd_type = acmd_type;
--+   POOLMEM *c = get_pool_memory(PM_FNAME);
--+   Mmsg(c, "%c%s", acmd_type, cmd);
--+   commands->append(c);
-- }
-- 
--+/* command = ( SHELL_CMD | CONSOLE_CMD ) command */
--+void RUNSCRIPT::get_command(const char* command, int *acmd_type, char **cmd)
--+{
--+   *acmd_type = (int) command[0];
--+   *cmd = (char *)command + 1;
--+}
--+
-- /* set this->target to client_name */
-- void RUNSCRIPT::set_target(const POOLMEM *client_name)
-- {
--@@ -210,14 +185,70 @@
-- 
-- bool RUNSCRIPT::run(JCR *jcr, const char *name)
-- {
---   Dmsg1(100, "runscript: running a RUNSCRIPT object type=%d\n", cmd_type);
--+   char *c;
--+   bool runit;
--+
--+   int when;
--+
--+   if (strstr(name, NT_("Before"))) {
--+      when = SCRIPT_Before;
--+   } else {
--+      when = SCRIPT_After;
--+   }
--+
--+   foreach_alist(c, this->commands) {
--+      Dmsg2(200, "runscript: try to run %s:%s\n", NPRT(this->target), NPRT(c));
--+      runit = false;
--+
--+      if ((this->when & SCRIPT_Before) && (when & SCRIPT_Before)) {
--+         if ((this->on_success 
--+            && (jcr->JobStatus == JS_Running || jcr->JobStatus == JS_Created))
--+            || (this->on_failure && job_canceled(jcr))
--+            )
--+         {
--+            Dmsg4(200, "runscript: Run it because SCRIPT_Before (%s,%i,%i,%c)\n", 
--+                  c, this->on_success, this->on_failure,
--+                  jcr->JobStatus );
--+            runit = true;
--+         }
--+      }
--+
--+      if ((this->when & SCRIPT_After) && (when & SCRIPT_After)) {
--+         if ((this->on_success && (jcr->JobStatus == JS_Terminated))
--+             || (this->on_failure && job_canceled(jcr))
--+            )
--+         {
--+            Dmsg4(200, "runscript: Run it because SCRIPT_After (%s,%i,%i,%c)\n", 
--+                  c, this->on_success, this->on_failure,
--+                  jcr->JobStatus );
--+            runit = true;
--+         }
--+      }
--+
--+      if (!this->is_local()) {
--+         runit = false;
--+      }
--+
--+      /* we execute it */
--+      if (runit) {
--+         this->run_command(c, jcr, name);
--+      }
--+   }
--+   return 1;
--+}
--+
--+/* run a command from the list */
--+bool RUNSCRIPT::run_command(const char *command, JCR *jcr, const char *name)
--+{
--    POOLMEM *ecmd = get_pool_memory(PM_FNAME);
---   int status;
--+   int status, cmd_type;
--    BPIPE *bpipe;
---   char line[MAXSTRING];
--+   char line[MAXSTRING], *cmd;
-- 
---   ecmd = edit_job_codes(jcr, ecmd, this->command, "", this->job_code_callback);
---   Dmsg1(100, "runscript: running '%s'...\n", ecmd);
--+   this->get_command(command, &cmd_type, &cmd);
--+   ecmd = edit_job_codes(jcr, ecmd, cmd, "", this->job_code_callback);
--+
--+   Dmsg2(100, "runscript: running '%s' object type=%c...\n", ecmd, cmd_type);
--    Jmsg(jcr, M_INFO, 0, _("%s: run %s \"%s\"\n"), 
--         cmd_type==SHELL_CMD?"shell command":"console command", name, ecmd);
-- 
--@@ -278,9 +309,12 @@
-- 
-- void RUNSCRIPT::debug()
-- {
--+   char *c;
--    Dmsg0(200, "runscript: debug\n");
--    Dmsg0(200,  _(" --> RunScript\n"));
---   Dmsg1(200,  _("  --> Command=%s\n"), NPRT(command));
--+   foreach_alist(c, commands) {
--+      Dmsg1(200,  _("  --> Command=%s\n"), NPRT(c));
--+   }
--    Dmsg1(200,  _("  --> Target=%s\n"),  NPRT(target));
--    Dmsg1(200,  _("  --> RunOnSuccess=%u\n"),  on_success);
--    Dmsg1(200,  _("  --> RunOnFailure=%u\n"),  on_failure);
 Index: src/dird/fd_cmds.c
 ===================================================================
 --- src/dird/fd_cmds.c (révision 6169)
diff --git a/bacula/patches/testing/runscript_with_multiple_command_v2.patch b/bacula/patches/testing/runscript_with_multiple_command_v2.patch
new file mode 100644 (file)
index 0000000..0c5fc63
--- /dev/null
@@ -0,0 +1,88 @@
+Index: src/dird/dird_conf.c
+===================================================================
+--- src/dird/dird_conf.c       (révision 6192)
++++ src/dird/dird_conf.c       (copie de travail)
+@@ -1678,6 +1678,8 @@
+ /* We build RunScripts items here */
+ static RUNSCRIPT res_runscript;
++static alist *res_runscript_cmd;
++static alist *res_runscript_type;
+ /* Store a runscript->when in a bit field */
+ static void store_runscript_when(LEX *lc, RES_ITEM *item, int index, int pass)
+@@ -1731,7 +1733,10 @@
+    lex_get_token(lc, T_STRING);
+    if (pass == 2) {
+-      ((RUNSCRIPT*)item->value)->set_command(lc->str, item->code);
++      POOLMEM *c = get_pool_memory(PM_FNAME);
++      pm_strcpy(c, lc->str);
++      res_runscript_cmd->prepend(c);
++      res_runscript_type->prepend((void*) item->code);
+    }
+    scan_to_eol(lc);
+ }
+@@ -1833,7 +1838,8 @@
+  */
+ static void store_runscript(LEX *lc, RES_ITEM *item, int index, int pass)
+ {
+-   int token, i;
++   char *c;
++   int token, i, t;
+    alist **runscripts = (alist **)(item->value) ;
+    Dmsg1(200, "store_runscript: begin store_runscript pass=%i\n", pass);
+@@ -1846,6 +1852,11 @@
+       scan_err1(lc, _("Expecting open brace. Got %s"), lc->str);
+    }
+    
++   if (pass == 2) {
++      res_runscript_cmd = New(alist(10, not_owned_by_alist));
++      res_runscript_type = New(alist(10, not_owned_by_alist));
++   }
++
+    while ((token = lex_get_token(lc, T_SKIP_EOL)) != T_EOF) {
+       if (token == T_EOB) {
+         break;
+@@ -1873,26 +1884,26 @@
+    }
+    if (pass == 2) {
+-      if (res_runscript.command == NULL) {
+-         scan_err2(lc, _("%s item is required in %s resource, but not found.\n"),
+-                   "command", "runscript");
+-      }
+-
+       /* run on client by default */
+       if (res_runscript.target == NULL) {
+          res_runscript.set_target("%c");
+       }
+-
+-      RUNSCRIPT *script = new_runscript();
+-      memcpy(script, &res_runscript, sizeof(RUNSCRIPT));
+-      script->set_job_code_callback(job_code_callback_filesetname);
+-      
+       if (*runscripts == NULL) {
+-        *runscripts = New(alist(10, not_owned_by_alist));
++         *runscripts = New(alist(10, not_owned_by_alist));
+       }
+-      
+-      (*runscripts)->append(script);
+-      script->debug();
++      while ((c=(char*)res_runscript_cmd->pop()) != NULL) {
++         t = (int) res_runscript_type->pop();
++         RUNSCRIPT *script = new_runscript();
++         memcpy(script, &res_runscript, sizeof(RUNSCRIPT));
++         script->set_job_code_callback(job_code_callback_filesetname);
++         script->command = c;
++         script->cmd_type = t;
++
++         (*runscripts)->append(script);
++         script->debug();
++      }
++      delete res_runscript_type;
++      delete res_runscript_cmd;
+    }
+    scan_to_eol(lc);