]> git.sur5r.net Git - bacula/bacula/blob - bacula/patches/testing/runscript_with_multiple_command.patch
ebl Cleanup
[bacula/bacula] / bacula / patches / testing / runscript_with_multiple_command.patch
1 Index: patches/testing/runscript_with_multiple_command.patch
2 ===================================================================
3 --- patches/testing/runscript_with_multiple_command.patch       (révision 6170)
4 +++ patches/testing/runscript_with_multiple_command.patch       (copie de travail)
5 @@ -1,483 +0,0 @@
6 -Index: src/dird/fd_cmds.c
7 -===================================================================
8 ---- src/dird/fd_cmds.c (révision 6169)
9 -+++ src/dird/fd_cmds.c (copie de travail)
10 -@@ -537,29 +537,35 @@
11 -          Dmsg2(200, "bdird: runscript %s -> %s\n", cmd->target, ehost);
12
13 -          if (strcmp(ehost, jcr->client->name()) == 0) {
14 --            pm_strcpy(msg, cmd->command);
15 --            bash_spaces(msg);
16 -+            char *c;
17 -+            char *command, cmd_type;
18 -+            foreach_alist(c, cmd->commands) {
19 -+               cmd->get_command(c, &cmd_type, &command);
20 -+               if (cmd_type == SHELL_CMD) {
21 -+                  pm_strcpy(msg, command);
22 -+                  bash_spaces(msg);
23
24 --            Dmsg1(120, "bdird: sending runscripts to fd '%s'\n", cmd->command);
25 -+                  Dmsg1(120, "bdird: sending runscripts to fd '%s'\n", command);
26 -             
27 --            /* TODO: remove this with bacula 1.42 */
28 --            if (cmd->old_proto) {
29 --               result = send_runscript_with_old_proto(jcr, cmd->when, msg);
30 -+                  /* TODO: remove this with bacula 1.42 */
31 -+                  if (cmd->old_proto) {
32 -+                     result = send_runscript_with_old_proto(jcr, cmd->when, msg);
33 -+                     
34 -+                  } else {
35 -+                     fd->fsend(runscript, cmd->on_success, 
36 -+                                          cmd->on_failure,
37 -+                                          cmd->fail_on_error,
38 -+                                          cmd->when,
39 -+                                          msg);
40
41 --            } else {
42 --               fd->fsend(runscript, cmd->on_success, 
43 --                                    cmd->on_failure,
44 --                                    cmd->fail_on_error,
45 --                                    cmd->when,
46 --                                    msg);
47 --
48 --               result = response(jcr, fd, OKRunScript, "RunScript", DISPLAY_ERROR);
49 --               launch_before_cmd = true;
50 -+                     result = response(jcr, fd, OKRunScript, "RunScript", DISPLAY_ERROR);
51 -+                     launch_before_cmd = true;
52 -+                  }
53 -+                  if (!result) {
54 -+                     goto bail_out;
55 -+                  }
56 -+               }
57 -             }
58 --            
59 --            if (!result) {
60 --               goto bail_out;
61 --            }
62 -          }
63 -          /* TODO : we have to play with other client */
64 -          /*
65 -@@ -567,7 +573,7 @@
66 -            send command to an other client
67 -            }
68 -          */
69 --      }        
70 -+      }
71 -    } 
72
73 -    /* Tell the FD to execute the ClientRunBeforeJob */
74 -Index: src/dird/dird_conf.c
75 -===================================================================
76 ---- src/dird/dird_conf.c       (révision 6169)
77 -+++ src/dird/dird_conf.c       (copie de travail)
78 -@@ -651,16 +651,19 @@
79 -          }
80 -       }
81 -       if (res->res_job.RunScripts) {
82 --        RUNSCRIPT *script;
83 --        foreach_alist(script, res->res_job.RunScripts) {
84 --           sendit(sock, _(" --> RunScript\n"));
85 --           sendit(sock, _("  --> Command=%s\n"), NPRT(script->command));
86 --           sendit(sock, _("  --> Target=%s\n"),  NPRT(script->target));
87 --           sendit(sock, _("  --> RunOnSuccess=%u\n"),  script->on_success);
88 --           sendit(sock, _("  --> RunOnFailure=%u\n"),  script->on_failure);
89 --           sendit(sock, _("  --> FailJobOnError=%u\n"),  script->fail_on_error);
90 --           sendit(sock, _("  --> RunWhen=%u\n"),  script->when);
91 --        }
92 -+         char *c;
93 -+         RUNSCRIPT *script;
94 -+         foreach_alist(script, res->res_job.RunScripts) {
95 -+            sendit(sock, _(" --> RunScript\n"));
96 -+            foreach_alist(c, script->commands) {
97 -+               sendit(sock, _("  --> Command=%s\n"), NPRT(c));
98 -+            }
99 -+            sendit(sock, _("  --> Target=%s\n"),  NPRT(script->target));
100 -+            sendit(sock, _("  --> RunOnSuccess=%u\n"),  script->on_success);
101 -+            sendit(sock, _("  --> RunOnFailure=%u\n"),  script->on_failure);
102 -+            sendit(sock, _("  --> FailJobOnError=%u\n"),  script->fail_on_error);
103 -+            sendit(sock, _("  --> RunWhen=%u\n"),  script->when);
104 -+         }
105 -       }
106 -       if (res->res_job.pool) {
107 -          sendit(sock, _("  --> "));
108 -@@ -1724,14 +1727,14 @@
109 - }
110
111 - /*
112 -- * Store a runscript->command as a string
113 -+ * Store a runscript->commands as a alist(char + string)
114 -  */
115 - static void store_runscript_cmd(LEX *lc, RES_ITEM *item, int index, int pass)
116 - {
117 -    lex_get_token(lc, T_STRING);
118
119 -    if (pass == 2) {
120 --      ((RUNSCRIPT*)item->value)->set_command(lc->str, item->code);
121 -+      ((RUNSCRIPT*)item->value)->add_command(lc->str, item->code);
122 -    }
123 -    scan_to_eol(lc);
124 - }
125 -@@ -1745,7 +1748,7 @@
126 -       RUNSCRIPT *script = new_runscript();
127 -       script->set_job_code_callback(job_code_callback_filesetname);
128
129 --      script->set_command(lc->str);
130 -+      script->add_command(lc->str);
131
132 -       /* TODO: remove all script->old_proto with bacula 1.42 */
133
134 -@@ -1873,7 +1876,7 @@
135 -    }
136
137 -    if (pass == 2) {
138 --      if (res_runscript.command == NULL) {
139 -+      if (res_runscript.commands == NULL) {
140 -          scan_err2(lc, _("%s item is required in %s resource, but not found.\n"),
141 -                    "command", "runscript");
142 -       }
143 -@@ -1883,10 +1886,11 @@
144 -          res_runscript.set_target("%c");
145 -       }
146
147 --      RUNSCRIPT *script = new_runscript();
148 --      memcpy(script, &res_runscript, sizeof(RUNSCRIPT));
149 -+      RUNSCRIPT *script = copy_runscript(&res_runscript);
150 -+      res_runscript.reset_default(true);
151 -+
152 -       script->set_job_code_callback(job_code_callback_filesetname);
153 --      
154 -+
155 -       if (*runscripts == NULL) {
156 -         *runscripts = New(alist(10, not_owned_by_alist));
157 -       }
158 -Index: src/filed/job.c
159 -===================================================================
160 ---- src/filed/job.c    (révision 6169)
161 -+++ src/filed/job.c    (copie de travail)
162 -@@ -481,7 +481,7 @@
163
164 -    /* Run the command now */
165 -    script = new_runscript();
166 --   script->set_command(cmd);
167 -+   script->add_command(cmd);
168 -    script->when = SCRIPT_Before;
169 -    ok = script->run(jcr, "ClientRunBeforeJob");
170 -    free_runscript(script);
171 -@@ -529,7 +529,7 @@
172 -    unbash_spaces(msg);
173
174 -    cmd = new_runscript();
175 --   cmd->set_command(msg);
176 -+   cmd->add_command(msg);
177 -    cmd->on_success = true;
178 -    cmd->on_failure = false;
179 -    cmd->when = SCRIPT_After;
180 -@@ -567,7 +567,7 @@
181 -    cmd->fail_on_error = fail_on_error;
182 -    unbash_spaces(msg);
183
184 --   cmd->set_command(msg);
185 -+   cmd->add_command(msg);
186 -    cmd->debug();
187 -    jcr->RunScripts->append(cmd);
188
189 -Index: src/lib/runscript.h
190 -===================================================================
191 ---- src/lib/runscript.h        (révision 6169)
192 -+++ src/lib/runscript.h        (copie de travail)
193 -@@ -62,8 +62,8 @@
194 - };
195
196 - enum {
197 --   SHELL_CMD   = 1,
198 --   CONSOLE_CMD = 2 
199 -+   SHELL_CMD   = '|',
200 -+   CONSOLE_CMD = '@' 
201 - };
202
203 - /*
204 -@@ -71,10 +71,9 @@
205 -  */
206 - class RUNSCRIPT {
207 - public:
208 --   POOLMEM *command;            /* command string */
209 -+   alist *commands;             /* list of command/console string */
210 -    POOLMEM *target;             /* host target */
211 -    int  when;                   /* SCRIPT_Before|Script_After BEFORE/AFTER JOB*/
212 --   int  cmd_type;               /* Command type -- Shell, Console */
213 -    char level;                  /* Base|Full|Incr...|All (NYI) */
214 -    bool on_success;             /* execute command on job success (After) */
215 -    bool on_failure;             /* execute command on job failure (After) */
216 -@@ -85,8 +84,10 @@
217 -                                 /* Optional callback function passed to edit_job_code */
218
219 -    bool run(JCR *job, const char *name=""); /* name must contain "Before" or "After" keyword */
220 -+   bool run_command(const char *cmd, JCR *job, const char *name="");
221 -    bool can_run_at_level(int JobLevel) { return true;};        /* TODO */
222 --   void set_command(const POOLMEM *cmd, int cmd_type = SHELL_CMD);
223 -+   void add_command(const POOLMEM *cmd, char cmd_type = SHELL_CMD);
224 -+   void get_command(const char *cmd, char *cmd_type, char **cmd);
225 -    void set_target(const POOLMEM *client_name);
226 -    void reset_default(bool free_string = false);
227 -    bool is_local();             /* true if running on local host */
228 -Index: src/lib/runscript.c
229 -===================================================================
230 ---- src/lib/runscript.c        (révision 6169)
231 -+++ src/lib/runscript.c        (copie de travail)
232 -@@ -59,15 +59,20 @@
233
234 - void RUNSCRIPT::reset_default(bool free_strings)
235 - {
236 --   if (free_strings && command) {
237 --     free_pool_memory(command);
238 -+   char *c;
239 -+   if (free_strings && commands) {
240 -+      foreach_alist(c, commands) {
241 -+         free_pool_memory(c);
242 -+      }
243 -    }
244 -    if (free_strings && target) {
245 -      free_pool_memory(target);
246 -    }
247 --   
248 -    target = NULL;
249 --   command = NULL;
250 -+   if (commands) {
251 -+      delete commands;
252 -+      commands = NULL;
253 -+   }
254 -    on_success = true;
255 -    on_failure = false;
256 -    fail_on_error = true;
257 -@@ -76,17 +81,23 @@
258 -    job_code_callback = NULL;
259 - }
260
261 --RUNSCRIPT *copy_runscript(RUNSCRIPT *src)
262 -+Runscript *copy_runscript(RUNSCRIPT *src)
263 - {
264 -    Dmsg0(500, "runscript: creating new RUNSCRIPT object from other\n");
265
266 -    RUNSCRIPT *dst = (RUNSCRIPT *)malloc(sizeof(RUNSCRIPT));
267 -    memcpy(dst, src, sizeof(RUNSCRIPT));
268
269 --   dst->command = NULL;
270 -+   dst->commands =  New(alist(5, not_owned_by_alist));
271 -+   char *c;
272 -+   POOLMEM *m;
273 -+   foreach_alist(c, src->commands) {
274 -+      m = get_pool_memory(PM_FNAME);
275 -+      pm_strcpy(m, c);
276 -+      dst->commands->append(m);
277 -+   }
278 -+
279 -    dst->target = NULL;
280 --
281 --   dst->set_command(src->command, src->cmd_type);
282 -    dst->set_target(src->target);
283
284 -    return dst;   
285 -@@ -95,9 +106,12 @@
286 - void free_runscript(RUNSCRIPT *script)
287 - {
288 -    Dmsg0(500, "runscript: freeing RUNSCRIPT object\n");
289 --
290 --   if (script->command) {
291 --      free_pool_memory(script->command);
292 -+   POOLMEM *c;
293 -+   if (script->commands) {
294 -+      foreach_alist(c, script->commands) {
295 -+         free_pool_memory(c);
296 -+      }
297 -+      delete script->commands;
298 -    }
299 -    if (script->target) {
300 -       free_pool_memory(script->target);
301 -@@ -108,60 +122,15 @@
302 - int run_scripts(JCR *jcr, alist *runscripts, const char *label)
303 - {
304 -    Dmsg2(200, "runscript: running all RUNSCRIPT object (%s) JobStatus=%c\n", label, jcr->JobStatus);
305 --   
306 --   RUNSCRIPT *script;
307 --   bool runit;
308
309 --   int when;
310 --
311 --   if (strstr(label, NT_("Before"))) {
312 --      when = SCRIPT_Before;
313 --   } else {
314 --      when = SCRIPT_After;
315 --   }
316 --
317 -    if (runscripts == NULL) {
318 -       Dmsg0(100, "runscript: WARNING RUNSCRIPTS list is NULL\n");
319 -       return 0;
320 -    }
321 --
322 -+   
323 -+   RUNSCRIPT *script;
324 -    foreach_alist(script, runscripts) {
325 --      Dmsg2(200, "runscript: try to run %s:%s\n", NPRT(script->target), NPRT(script->command));
326 --      runit = false;
327 --
328 --      if ((script->when & SCRIPT_Before) && (when & SCRIPT_Before)) {
329 --         if ((script->on_success 
330 --            && (jcr->JobStatus == JS_Running || jcr->JobStatus == JS_Created))
331 --            || (script->on_failure && job_canceled(jcr))
332 --            )
333 --         {
334 --            Dmsg4(200, "runscript: Run it because SCRIPT_Before (%s,%i,%i,%c)\n", 
335 --                  script->command, script->on_success, script->on_failure,
336 --                  jcr->JobStatus );
337 --            runit = true;
338 --         }
339 --      }
340 --
341 --      if ((script->when & SCRIPT_After) && (when & SCRIPT_After)) {
342 --         if ((script->on_success && (jcr->JobStatus == JS_Terminated))
343 --             || (script->on_failure && job_canceled(jcr))
344 --            )
345 --         {
346 --            Dmsg4(200, "runscript: Run it because SCRIPT_After (%s,%i,%i,%c)\n", 
347 --                  script->command, script->on_success, script->on_failure,
348 --                  jcr->JobStatus );
349 --            runit = true;
350 --         }
351 --      }
352 --
353 --      if (!script->is_local()) {
354 --         runit = false;
355 --      }
356 --
357 --      /* we execute it */
358 --      if (runit) {
359 --         script->run(jcr, label);
360 --      }
361 -+      script->run(jcr, label);
362 -    }
363 -    return 1;
364 - }
365 -@@ -176,7 +145,7 @@
366 - }
367
368 - /* set this->command to cmd */
369 --void RUNSCRIPT::set_command(const POOLMEM *cmd, int acmd_type)
370 -+void RUNSCRIPT::add_command(const POOLMEM *cmd, char acmd_type)
371 - {
372 -    Dmsg1(500, "runscript: setting command = %s\n", NPRT(cmd));
373
374 -@@ -184,14 +153,21 @@
375 -       return;
376 -    }
377
378 --   if (!command) {
379 --      command = get_pool_memory(PM_FNAME);
380 -+   if (!commands) {
381 -+      commands = New(alist(5, not_owned_by_alist)); 
382 -    }
383
384 --   pm_strcpy(command, cmd);
385 --   cmd_type = acmd_type;
386 -+   POOLMEM *c = get_pool_memory(PM_FNAME);
387 -+   Mmsg(c, "%c%s", acmd_type, cmd);
388 -+   commands->append(c);
389 - }
390
391 -+void RUNSCRIPT::get_command(const char* command, char *acmd_type, char **cmd)
392 -+{
393 -+   *acmd_type = command[0];
394 -+   *cmd = (char *)command + 1;
395 -+}
396 -+
397 - /* set this->target to client_name */
398 - void RUNSCRIPT::set_target(const POOLMEM *client_name)
399 - {
400 -@@ -210,14 +186,71 @@
401
402 - bool RUNSCRIPT::run(JCR *jcr, const char *name)
403 - {
404 --   Dmsg1(100, "runscript: running a RUNSCRIPT object type=%d\n", cmd_type);
405 -+   char *c;
406 -+   bool runit;
407 -+
408 -+   int when;
409 -+
410 -+   if (strstr(name, NT_("Before"))) {
411 -+      when = SCRIPT_Before;
412 -+   } else {
413 -+      when = SCRIPT_After;
414 -+   }
415 -+
416 -+   foreach_alist(c, this->commands) {
417 -+      Dmsg2(200, "runscript: try to run %s:%s\n", NPRT(this->target), NPRT(c));
418 -+      runit = false;
419 -+
420 -+      if ((this->when & SCRIPT_Before) && (when & SCRIPT_Before)) {
421 -+         if ((this->on_success 
422 -+            && (jcr->JobStatus == JS_Running || jcr->JobStatus == JS_Created))
423 -+            || (this->on_failure && job_canceled(jcr))
424 -+            )
425 -+         {
426 -+            Dmsg4(200, "runscript: Run it because SCRIPT_Before (%s,%i,%i,%c)\n", 
427 -+                  c, this->on_success, this->on_failure,
428 -+                  jcr->JobStatus );
429 -+            runit = true;
430 -+         }
431 -+      }
432 -+
433 -+      if ((this->when & SCRIPT_After) && (when & SCRIPT_After)) {
434 -+         if ((this->on_success && (jcr->JobStatus == JS_Terminated))
435 -+             || (this->on_failure && job_canceled(jcr))
436 -+            )
437 -+         {
438 -+            Dmsg4(200, "runscript: Run it because SCRIPT_After (%s,%i,%i,%c)\n", 
439 -+                  c, this->on_success, this->on_failure,
440 -+                  jcr->JobStatus );
441 -+            runit = true;
442 -+         }
443 -+      }
444 -+
445 -+      if (!this->is_local()) {
446 -+         runit = false;
447 -+      }
448 -+
449 -+      /* we execute it */
450 -+      if (runit) {
451 -+         this->run_command(c, jcr, name);
452 -+      }
453 -+   }
454 -+   return 1;
455 -+}
456 -+
457 -+bool RUNSCRIPT::run_command(const char *command, JCR *jcr, const char *name)
458 -+{
459 -    POOLMEM *ecmd = get_pool_memory(PM_FNAME);
460 -    int status;
461 -    BPIPE *bpipe;
462 -    char line[MAXSTRING];
463 -+   char cmd_type;
464 -+   char *cmd;
465
466 --   ecmd = edit_job_codes(jcr, ecmd, this->command, "", this->job_code_callback);
467 --   Dmsg1(100, "runscript: running '%s'...\n", ecmd);
468 -+   this->get_command(command, &cmd_type, &cmd);
469 -+   ecmd = edit_job_codes(jcr, ecmd, cmd, "", this->job_code_callback);
470 -+
471 -+   Dmsg2(100, "runscript: running '%s' object type=%c...\n", ecmd, cmd_type);
472 -    Jmsg(jcr, M_INFO, 0, _("%s: run %s \"%s\"\n"), 
473 -         cmd_type==SHELL_CMD?"shell command":"console command", name, ecmd);
474
475 -@@ -278,9 +311,12 @@
476
477 - void RUNSCRIPT::debug()
478 - {
479 -+   char *c;
480 -    Dmsg0(200, "runscript: debug\n");
481 -    Dmsg0(200,  _(" --> RunScript\n"));
482 --   Dmsg1(200,  _("  --> Command=%s\n"), NPRT(command));
483 -+   foreach_alist(c, commands) {
484 -+      Dmsg1(200,  _("  --> Command=%s\n"), NPRT(c));
485 -+   }
486 -    Dmsg1(200,  _("  --> Target=%s\n"),  NPRT(target));
487 -    Dmsg1(200,  _("  --> RunOnSuccess=%u\n"),  on_success);
488 -    Dmsg1(200,  _("  --> RunOnFailure=%u\n"),  on_failure);
489 Index: src/dird/fd_cmds.c
490 ===================================================================
491 --- src/dird/fd_cmds.c  (révision 6169)
492 +++ src/dird/fd_cmds.c  (copie de travail)
493 @@ -527,7 +527,8 @@
494     RUNSCRIPT *cmd;
495     bool launch_before_cmd = false;
496     POOLMEM *ehost = get_pool_memory(PM_FNAME);
497 -   int result;
498 +   int result, cmd_type;
499 +   char *c, *command;
500  
501     Dmsg0(120, "bdird: sending runscripts to fd\n");
502     
503 @@ -537,29 +538,33 @@
504           Dmsg2(200, "bdird: runscript %s -> %s\n", cmd->target, ehost);
505  
506           if (strcmp(ehost, jcr->client->name()) == 0) {
507 -            pm_strcpy(msg, cmd->command);
508 -            bash_spaces(msg);
509 +            foreach_alist(c, cmd->commands) {
510 +               cmd->get_command(c, &cmd_type, &command);
511 +               if (cmd_type == SHELL_CMD) {
512 +                  pm_strcpy(msg, command);
513 +                  bash_spaces(msg);
514  
515 -            Dmsg1(120, "bdird: sending runscripts to fd '%s'\n", cmd->command);
516 +                  Dmsg1(120, "bdird: sending runscripts to fd '%s'\n", command);
517              
518 -            /* TODO: remove this with bacula 1.42 */
519 -            if (cmd->old_proto) {
520 -               result = send_runscript_with_old_proto(jcr, cmd->when, msg);
521 +                  /* TODO: remove this with bacula 1.42 */
522 +                  if (cmd->old_proto) {
523 +                     result = send_runscript_with_old_proto(jcr, cmd->when, msg);
524 +                     
525 +                  } else {
526 +                     fd->fsend(runscript, cmd->on_success, 
527 +                                          cmd->on_failure,
528 +                                          cmd->fail_on_error,
529 +                                          cmd->when,
530 +                                          msg);
531  
532 -            } else {
533 -               fd->fsend(runscript, cmd->on_success, 
534 -                                    cmd->on_failure,
535 -                                    cmd->fail_on_error,
536 -                                    cmd->when,
537 -                                    msg);
538 -
539 -               result = response(jcr, fd, OKRunScript, "RunScript", DISPLAY_ERROR);
540 -               launch_before_cmd = true;
541 +                     result = response(jcr, fd, OKRunScript, "RunScript", DISPLAY_ERROR);
542 +                     launch_before_cmd = true;
543 +                  }
544 +                  if (!result) {
545 +                     goto bail_out;
546 +                  }
547 +               }
548              }
549 -            
550 -            if (!result) {
551 -               goto bail_out;
552 -            }
553           }
554           /* TODO : we have to play with other client */
555           /*
556 @@ -567,7 +572,7 @@
557             send command to an other client
558             }
559           */
560 -      }        
561 +      }
562     } 
563  
564     /* Tell the FD to execute the ClientRunBeforeJob */
565 Index: src/dird/dird_conf.c
566 ===================================================================
567 --- src/dird/dird_conf.c        (révision 6169)
568 +++ src/dird/dird_conf.c        (copie de travail)
569 @@ -651,16 +651,19 @@
570           }
571        }
572        if (res->res_job.RunScripts) {
573 -        RUNSCRIPT *script;
574 -        foreach_alist(script, res->res_job.RunScripts) {
575 -           sendit(sock, _(" --> RunScript\n"));
576 -           sendit(sock, _("  --> Command=%s\n"), NPRT(script->command));
577 -           sendit(sock, _("  --> Target=%s\n"),  NPRT(script->target));
578 -           sendit(sock, _("  --> RunOnSuccess=%u\n"),  script->on_success);
579 -           sendit(sock, _("  --> RunOnFailure=%u\n"),  script->on_failure);
580 -           sendit(sock, _("  --> FailJobOnError=%u\n"),  script->fail_on_error);
581 -           sendit(sock, _("  --> RunWhen=%u\n"),  script->when);
582 -        }
583 +         char *c;
584 +         RUNSCRIPT *script;
585 +         foreach_alist(script, res->res_job.RunScripts) {
586 +            sendit(sock, _(" --> RunScript\n"));
587 +            foreach_alist(c, script->commands) {
588 +               sendit(sock, _("  --> Command=%s\n"), NPRT(c));
589 +            }
590 +            sendit(sock, _("  --> Target=%s\n"),  NPRT(script->target));
591 +            sendit(sock, _("  --> RunOnSuccess=%u\n"),  script->on_success);
592 +            sendit(sock, _("  --> RunOnFailure=%u\n"),  script->on_failure);
593 +            sendit(sock, _("  --> FailJobOnError=%u\n"),  script->fail_on_error);
594 +            sendit(sock, _("  --> RunWhen=%u\n"),  script->when);
595 +         }
596        }
597        if (res->res_job.pool) {
598           sendit(sock, _("  --> "));
599 @@ -1724,14 +1727,14 @@
600  }
601  
602  /*
603 - * Store a runscript->command as a string
604 + * Store a runscript->commands as a alist(char + string)
605   */
606  static void store_runscript_cmd(LEX *lc, RES_ITEM *item, int index, int pass)
607  {
608     lex_get_token(lc, T_STRING);
609  
610     if (pass == 2) {
611 -      ((RUNSCRIPT*)item->value)->set_command(lc->str, item->code);
612 +      ((RUNSCRIPT*)item->value)->add_command(lc->str, item->code);
613     }
614     scan_to_eol(lc);
615  }
616 @@ -1745,7 +1748,7 @@
617        RUNSCRIPT *script = new_runscript();
618        script->set_job_code_callback(job_code_callback_filesetname);
619  
620 -      script->set_command(lc->str);
621 +      script->add_command(lc->str);
622  
623        /* TODO: remove all script->old_proto with bacula 1.42 */
624  
625 @@ -1873,7 +1876,7 @@
626     }
627  
628     if (pass == 2) {
629 -      if (res_runscript.command == NULL) {
630 +      if (res_runscript.commands == NULL) {
631           scan_err2(lc, _("%s item is required in %s resource, but not found.\n"),
632                     "command", "runscript");
633        }
634 @@ -1886,7 +1889,7 @@
635        RUNSCRIPT *script = new_runscript();
636        memcpy(script, &res_runscript, sizeof(RUNSCRIPT));
637        script->set_job_code_callback(job_code_callback_filesetname);
638 -      
639 +
640        if (*runscripts == NULL) {
641          *runscripts = New(alist(10, not_owned_by_alist));
642        }
643 Index: src/filed/job.c
644 ===================================================================
645 --- src/filed/job.c     (révision 6169)
646 +++ src/filed/job.c     (copie de travail)
647 @@ -481,7 +481,7 @@
648  
649     /* Run the command now */
650     script = new_runscript();
651 -   script->set_command(cmd);
652 +   script->add_command(cmd);
653     script->when = SCRIPT_Before;
654     ok = script->run(jcr, "ClientRunBeforeJob");
655     free_runscript(script);
656 @@ -529,7 +529,7 @@
657     unbash_spaces(msg);
658  
659     cmd = new_runscript();
660 -   cmd->set_command(msg);
661 +   cmd->add_command(msg);
662     cmd->on_success = true;
663     cmd->on_failure = false;
664     cmd->when = SCRIPT_After;
665 @@ -567,7 +567,7 @@
666     cmd->fail_on_error = fail_on_error;
667     unbash_spaces(msg);
668  
669 -   cmd->set_command(msg);
670 +   cmd->add_command(msg);
671     cmd->debug();
672     jcr->RunScripts->append(cmd);
673  
674 Index: src/lib/runscript.h
675 ===================================================================
676 --- src/lib/runscript.h (révision 6169)
677 +++ src/lib/runscript.h (copie de travail)
678 @@ -62,8 +62,8 @@
679  };
680  
681  enum {
682 -   SHELL_CMD   = 1,
683 -   CONSOLE_CMD = 2 
684 +   SHELL_CMD   = '|',
685 +   CONSOLE_CMD = '@' 
686  };
687  
688  /*
689 @@ -71,10 +71,9 @@
690   */
691  class RUNSCRIPT {
692  public:
693 -   POOLMEM *command;            /* command string */
694 +   alist *commands;             /* list of command/console string */
695     POOLMEM *target;             /* host target */
696     int  when;                   /* SCRIPT_Before|Script_After BEFORE/AFTER JOB*/
697 -   int  cmd_type;               /* Command type -- Shell, Console */
698     char level;                  /* Base|Full|Incr...|All (NYI) */
699     bool on_success;             /* execute command on job success (After) */
700     bool on_failure;             /* execute command on job failure (After) */
701 @@ -86,19 +85,22 @@
702  
703     bool run(JCR *job, const char *name=""); /* name must contain "Before" or "After" keyword */
704     bool can_run_at_level(int JobLevel) { return true;};        /* TODO */
705 -   void set_command(const POOLMEM *cmd, int cmd_type = SHELL_CMD);
706 +   void add_command(const POOLMEM *cmd, char cmd_type = SHELL_CMD);
707 +   void get_command(const char *cmd, int *cmd_type, char **cmd);
708     void set_target(const POOLMEM *client_name);
709     void reset_default(bool free_string = false);
710     bool is_local();             /* true if running on local host */
711     void debug();
712 +   void set_job_code_callback(job_code_callback_t job_code_callback);
713  
714 -   void set_job_code_callback(job_code_callback_t job_code_callback);
715 +private:
716 +   bool run_command(const char *cmd, JCR *job, const char *name="");
717  };
718  
719  /* create new RUNSCRIPT (set all value to 0) */
720  RUNSCRIPT *new_runscript();           
721  
722 -/* create new RUNSCRIPT from an other */
723 +/* create new RUNSCRIPT from an other (deep copy) */
724  RUNSCRIPT *copy_runscript(RUNSCRIPT *src);
725  
726  /* launch each script from runscripts*/
727 Index: src/lib/runscript.c
728 ===================================================================
729 --- src/lib/runscript.c (révision 6169)
730 +++ src/lib/runscript.c (copie de travail)
731 @@ -59,15 +59,18 @@
732  
733  void RUNSCRIPT::reset_default(bool free_strings)
734  {
735 -   if (free_strings && command) {
736 -     free_pool_memory(command);
737 +   char *c;
738 +   if (free_strings && commands) {
739 +      foreach_alist(c, commands) {
740 +         free_pool_memory(c);
741 +      }
742 +      delete commands;
743     }
744     if (free_strings && target) {
745       free_pool_memory(target);
746     }
747 -   
748     target = NULL;
749 -   command = NULL;
750 +   commands = NULL;
751     on_success = true;
752     on_failure = false;
753     fail_on_error = true;
754 @@ -83,10 +86,16 @@
755     RUNSCRIPT *dst = (RUNSCRIPT *)malloc(sizeof(RUNSCRIPT));
756     memcpy(dst, src, sizeof(RUNSCRIPT));
757  
758 -   dst->command = NULL;
759 +   dst->commands =  New(alist(5, not_owned_by_alist));
760 +   char *c;
761 +   POOLMEM *m;
762 +   foreach_alist(c, src->commands) {
763 +      m = get_pool_memory(PM_FNAME);
764 +      pm_strcpy(m, c);
765 +      dst->commands->append(m);
766 +   }
767 +
768     dst->target = NULL;
769 -
770 -   dst->set_command(src->command, src->cmd_type);
771     dst->set_target(src->target);
772  
773     return dst;   
774 @@ -95,9 +104,12 @@
775  void free_runscript(RUNSCRIPT *script)
776  {
777     Dmsg0(500, "runscript: freeing RUNSCRIPT object\n");
778 -
779 -   if (script->command) {
780 -      free_pool_memory(script->command);
781 +   POOLMEM *c;
782 +   if (script->commands) {
783 +      foreach_alist(c, script->commands) {
784 +         free_pool_memory(c);
785 +      }
786 +      delete script->commands;
787     }
788     if (script->target) {
789        free_pool_memory(script->target);
790 @@ -108,60 +120,15 @@
791  int run_scripts(JCR *jcr, alist *runscripts, const char *label)
792  {
793     Dmsg2(200, "runscript: running all RUNSCRIPT object (%s) JobStatus=%c\n", label, jcr->JobStatus);
794 -   
795 -   RUNSCRIPT *script;
796 -   bool runit;
797  
798 -   int when;
799 -
800 -   if (strstr(label, NT_("Before"))) {
801 -      when = SCRIPT_Before;
802 -   } else {
803 -      when = SCRIPT_After;
804 -   }
805 -
806     if (runscripts == NULL) {
807        Dmsg0(100, "runscript: WARNING RUNSCRIPTS list is NULL\n");
808        return 0;
809     }
810 -
811 +   
812 +   RUNSCRIPT *script;
813     foreach_alist(script, runscripts) {
814 -      Dmsg2(200, "runscript: try to run %s:%s\n", NPRT(script->target), NPRT(script->command));
815 -      runit = false;
816 -
817 -      if ((script->when & SCRIPT_Before) && (when & SCRIPT_Before)) {
818 -         if ((script->on_success 
819 -            && (jcr->JobStatus == JS_Running || jcr->JobStatus == JS_Created))
820 -            || (script->on_failure && job_canceled(jcr))
821 -            )
822 -         {
823 -            Dmsg4(200, "runscript: Run it because SCRIPT_Before (%s,%i,%i,%c)\n", 
824 -                  script->command, script->on_success, script->on_failure,
825 -                  jcr->JobStatus );
826 -            runit = true;
827 -         }
828 -      }
829 -
830 -      if ((script->when & SCRIPT_After) && (when & SCRIPT_After)) {
831 -         if ((script->on_success && (jcr->JobStatus == JS_Terminated))
832 -             || (script->on_failure && job_canceled(jcr))
833 -            )
834 -         {
835 -            Dmsg4(200, "runscript: Run it because SCRIPT_After (%s,%i,%i,%c)\n", 
836 -                  script->command, script->on_success, script->on_failure,
837 -                  jcr->JobStatus );
838 -            runit = true;
839 -         }
840 -      }
841 -
842 -      if (!script->is_local()) {
843 -         runit = false;
844 -      }
845 -
846 -      /* we execute it */
847 -      if (runit) {
848 -         script->run(jcr, label);
849 -      }
850 +      script->run(jcr, label);
851     }
852     return 1;
853  }
854 @@ -175,23 +142,31 @@
855     }
856  }
857  
858 -/* set this->command to cmd */
859 -void RUNSCRIPT::set_command(const POOLMEM *cmd, int acmd_type)
860 +/* set add cmd to this->commands alist */
861 +void RUNSCRIPT::add_command(const POOLMEM *cmd, char acmd_type)
862  {
863 -   Dmsg1(500, "runscript: setting command = %s\n", NPRT(cmd));
864 +   Dmsg2(500, "runscript: setting command = %s type=%i\n", NPRT(cmd), acmd_type);
865  
866     if (!cmd) {
867        return;
868     }
869  
870 -   if (!command) {
871 -      command = get_pool_memory(PM_FNAME);
872 +   if (!commands) {
873 +      commands = New(alist(5, not_owned_by_alist)); 
874     }
875  
876 -   pm_strcpy(command, cmd);
877 -   cmd_type = acmd_type;
878 +   POOLMEM *c = get_pool_memory(PM_FNAME);
879 +   Mmsg(c, "%c%s", acmd_type, cmd);
880 +   commands->append(c);
881  }
882  
883 +/* command = ( SHELL_CMD | CONSOLE_CMD ) command */
884 +void RUNSCRIPT::get_command(const char* command, int *acmd_type, char **cmd)
885 +{
886 +   *acmd_type = (int) command[0];
887 +   *cmd = (char *)command + 1;
888 +}
889 +
890  /* set this->target to client_name */
891  void RUNSCRIPT::set_target(const POOLMEM *client_name)
892  {
893 @@ -210,14 +185,70 @@
894  
895  bool RUNSCRIPT::run(JCR *jcr, const char *name)
896  {
897 -   Dmsg1(100, "runscript: running a RUNSCRIPT object type=%d\n", cmd_type);
898 +   char *c;
899 +   bool runit;
900 +
901 +   int when;
902 +
903 +   if (strstr(name, NT_("Before"))) {
904 +      when = SCRIPT_Before;
905 +   } else {
906 +      when = SCRIPT_After;
907 +   }
908 +
909 +   foreach_alist(c, this->commands) {
910 +      Dmsg2(200, "runscript: try to run %s:%s\n", NPRT(this->target), NPRT(c));
911 +      runit = false;
912 +
913 +      if ((this->when & SCRIPT_Before) && (when & SCRIPT_Before)) {
914 +         if ((this->on_success 
915 +            && (jcr->JobStatus == JS_Running || jcr->JobStatus == JS_Created))
916 +            || (this->on_failure && job_canceled(jcr))
917 +            )
918 +         {
919 +            Dmsg4(200, "runscript: Run it because SCRIPT_Before (%s,%i,%i,%c)\n", 
920 +                  c, this->on_success, this->on_failure,
921 +                  jcr->JobStatus );
922 +            runit = true;
923 +         }
924 +      }
925 +
926 +      if ((this->when & SCRIPT_After) && (when & SCRIPT_After)) {
927 +         if ((this->on_success && (jcr->JobStatus == JS_Terminated))
928 +             || (this->on_failure && job_canceled(jcr))
929 +            )
930 +         {
931 +            Dmsg4(200, "runscript: Run it because SCRIPT_After (%s,%i,%i,%c)\n", 
932 +                  c, this->on_success, this->on_failure,
933 +                  jcr->JobStatus );
934 +            runit = true;
935 +         }
936 +      }
937 +
938 +      if (!this->is_local()) {
939 +         runit = false;
940 +      }
941 +
942 +      /* we execute it */
943 +      if (runit) {
944 +         this->run_command(c, jcr, name);
945 +      }
946 +   }
947 +   return 1;
948 +}
949 +
950 +/* run a command from the list */
951 +bool RUNSCRIPT::run_command(const char *command, JCR *jcr, const char *name)
952 +{
953     POOLMEM *ecmd = get_pool_memory(PM_FNAME);
954 -   int status;
955 +   int status, cmd_type;
956     BPIPE *bpipe;
957 -   char line[MAXSTRING];
958 +   char line[MAXSTRING], *cmd;
959  
960 -   ecmd = edit_job_codes(jcr, ecmd, this->command, "", this->job_code_callback);
961 -   Dmsg1(100, "runscript: running '%s'...\n", ecmd);
962 +   this->get_command(command, &cmd_type, &cmd);
963 +   ecmd = edit_job_codes(jcr, ecmd, cmd, "", this->job_code_callback);
964 +
965 +   Dmsg2(100, "runscript: running '%s' object type=%c...\n", ecmd, cmd_type);
966     Jmsg(jcr, M_INFO, 0, _("%s: run %s \"%s\"\n"), 
967          cmd_type==SHELL_CMD?"shell command":"console command", name, ecmd);
968  
969 @@ -278,9 +309,12 @@
970  
971  void RUNSCRIPT::debug()
972  {
973 +   char *c;
974     Dmsg0(200, "runscript: debug\n");
975     Dmsg0(200,  _(" --> RunScript\n"));
976 -   Dmsg1(200,  _("  --> Command=%s\n"), NPRT(command));
977 +   foreach_alist(c, commands) {
978 +      Dmsg1(200,  _("  --> Command=%s\n"), NPRT(c));
979 +   }
980     Dmsg1(200,  _("  --> Target=%s\n"),  NPRT(target));
981     Dmsg1(200,  _("  --> RunOnSuccess=%u\n"),  on_success);
982     Dmsg1(200,  _("  --> RunOnFailure=%u\n"),  on_failure);