1 Index: src/dird/fd_cmds.c
2 ===================================================================
3 --- src/dird/fd_cmds.c (révision 6169)
4 +++ src/dird/fd_cmds.c (copie de travail)
6 Dmsg2(200, "bdird: runscript %s -> %s\n", cmd->target, ehost);
8 if (strcmp(ehost, jcr->client->name()) == 0) {
9 - pm_strcpy(msg, cmd->command);
12 + char *command, cmd_type;
13 + foreach_alist(c, cmd->commands) {
14 + cmd->get_command(c, &cmd_type, &command);
15 + if (cmd_type == SHELL_CMD) {
16 + pm_strcpy(msg, command);
19 - Dmsg1(120, "bdird: sending runscripts to fd '%s'\n", cmd->command);
20 + Dmsg1(120, "bdird: sending runscripts to fd '%s'\n", command);
22 - /* TODO: remove this with bacula 1.42 */
23 - if (cmd->old_proto) {
24 - result = send_runscript_with_old_proto(jcr, cmd->when, msg);
25 + /* TODO: remove this with bacula 1.42 */
26 + if (cmd->old_proto) {
27 + result = send_runscript_with_old_proto(jcr, cmd->when, msg);
30 + fd->fsend(runscript, cmd->on_success,
37 - fd->fsend(runscript, cmd->on_success,
43 - result = response(jcr, fd, OKRunScript, "RunScript", DISPLAY_ERROR);
44 - launch_before_cmd = true;
45 + result = response(jcr, fd, OKRunScript, "RunScript", DISPLAY_ERROR);
46 + launch_before_cmd = true;
58 /* TODO : we have to play with other client */
61 send command to an other client
68 /* Tell the FD to execute the ClientRunBeforeJob */
69 Index: src/dird/dird_conf.c
70 ===================================================================
71 --- src/dird/dird_conf.c (révision 6169)
72 +++ src/dird/dird_conf.c (copie de travail)
76 if (res->res_job.RunScripts) {
78 - foreach_alist(script, res->res_job.RunScripts) {
79 - sendit(sock, _(" --> RunScript\n"));
80 - sendit(sock, _(" --> Command=%s\n"), NPRT(script->command));
81 - sendit(sock, _(" --> Target=%s\n"), NPRT(script->target));
82 - sendit(sock, _(" --> RunOnSuccess=%u\n"), script->on_success);
83 - sendit(sock, _(" --> RunOnFailure=%u\n"), script->on_failure);
84 - sendit(sock, _(" --> FailJobOnError=%u\n"), script->fail_on_error);
85 - sendit(sock, _(" --> RunWhen=%u\n"), script->when);
89 + foreach_alist(script, res->res_job.RunScripts) {
90 + sendit(sock, _(" --> RunScript\n"));
91 + foreach_alist(c, script->commands) {
92 + sendit(sock, _(" --> Command=%s\n"), NPRT(c));
94 + sendit(sock, _(" --> Target=%s\n"), NPRT(script->target));
95 + sendit(sock, _(" --> RunOnSuccess=%u\n"), script->on_success);
96 + sendit(sock, _(" --> RunOnFailure=%u\n"), script->on_failure);
97 + sendit(sock, _(" --> FailJobOnError=%u\n"), script->fail_on_error);
98 + sendit(sock, _(" --> RunWhen=%u\n"), script->when);
101 if (res->res_job.pool) {
102 sendit(sock, _(" --> "));
103 @@ -1724,14 +1727,14 @@
107 - * Store a runscript->command as a string
108 + * Store a runscript->commands as a alist(char + string)
110 static void store_runscript_cmd(LEX *lc, RES_ITEM *item, int index, int pass)
112 lex_get_token(lc, T_STRING);
115 - ((RUNSCRIPT*)item->value)->set_command(lc->str, item->code);
116 + ((RUNSCRIPT*)item->value)->add_command(lc->str, item->code);
120 @@ -1745,7 +1748,7 @@
121 RUNSCRIPT *script = new_runscript();
122 script->set_job_code_callback(job_code_callback_filesetname);
124 - script->set_command(lc->str);
125 + script->add_command(lc->str);
127 /* TODO: remove all script->old_proto with bacula 1.42 */
129 @@ -1873,7 +1876,7 @@
133 - if (res_runscript.command == NULL) {
134 + if (res_runscript.commands == NULL) {
135 scan_err2(lc, _("%s item is required in %s resource, but not found.\n"),
136 "command", "runscript");
138 @@ -1883,10 +1886,11 @@
139 res_runscript.set_target("%c");
142 - RUNSCRIPT *script = new_runscript();
143 - memcpy(script, &res_runscript, sizeof(RUNSCRIPT));
144 + RUNSCRIPT *script = copy_runscript(&res_runscript);
145 + res_runscript.reset_default(true);
147 script->set_job_code_callback(job_code_callback_filesetname);
150 if (*runscripts == NULL) {
151 *runscripts = New(alist(10, not_owned_by_alist));
153 Index: src/filed/job.c
154 ===================================================================
155 --- src/filed/job.c (révision 6169)
156 +++ src/filed/job.c (copie de travail)
159 /* Run the command now */
160 script = new_runscript();
161 - script->set_command(cmd);
162 + script->add_command(cmd);
163 script->when = SCRIPT_Before;
164 ok = script->run(jcr, "ClientRunBeforeJob");
165 free_runscript(script);
169 cmd = new_runscript();
170 - cmd->set_command(msg);
171 + cmd->add_command(msg);
172 cmd->on_success = true;
173 cmd->on_failure = false;
174 cmd->when = SCRIPT_After;
176 cmd->fail_on_error = fail_on_error;
179 - cmd->set_command(msg);
180 + cmd->add_command(msg);
182 jcr->RunScripts->append(cmd);
184 Index: src/lib/runscript.h
185 ===================================================================
186 --- src/lib/runscript.h (révision 6169)
187 +++ src/lib/runscript.h (copie de travail)
203 - POOLMEM *command; /* command string */
204 + alist *commands; /* list of command/console string */
205 POOLMEM *target; /* host target */
206 int when; /* SCRIPT_Before|Script_After BEFORE/AFTER JOB*/
207 - int cmd_type; /* Command type -- Shell, Console */
208 char level; /* Base|Full|Incr...|All (NYI) */
209 bool on_success; /* execute command on job success (After) */
210 bool on_failure; /* execute command on job failure (After) */
212 /* Optional callback function passed to edit_job_code */
214 bool run(JCR *job, const char *name=""); /* name must contain "Before" or "After" keyword */
215 + bool run_command(const char *cmd, JCR *job, const char *name="");
216 bool can_run_at_level(int JobLevel) { return true;}; /* TODO */
217 - void set_command(const POOLMEM *cmd, int cmd_type = SHELL_CMD);
218 + void add_command(const POOLMEM *cmd, char cmd_type = SHELL_CMD);
219 + void get_command(const char *cmd, char *cmd_type, char **cmd);
220 void set_target(const POOLMEM *client_name);
221 void reset_default(bool free_string = false);
222 bool is_local(); /* true if running on local host */
223 Index: src/lib/runscript.c
224 ===================================================================
225 --- src/lib/runscript.c (révision 6169)
226 +++ src/lib/runscript.c (copie de travail)
229 void RUNSCRIPT::reset_default(bool free_strings)
231 - if (free_strings && command) {
232 - free_pool_memory(command);
234 + if (free_strings && commands) {
235 + foreach_alist(c, commands) {
236 + free_pool_memory(c);
239 if (free_strings && target) {
240 free_pool_memory(target);
251 fail_on_error = true;
253 job_code_callback = NULL;
256 -RUNSCRIPT *copy_runscript(RUNSCRIPT *src)
257 +Runscript *copy_runscript(RUNSCRIPT *src)
259 Dmsg0(500, "runscript: creating new RUNSCRIPT object from other\n");
261 RUNSCRIPT *dst = (RUNSCRIPT *)malloc(sizeof(RUNSCRIPT));
262 memcpy(dst, src, sizeof(RUNSCRIPT));
264 - dst->command = NULL;
265 + dst->commands = New(alist(5, not_owned_by_alist));
268 + foreach_alist(c, src->commands) {
269 + m = get_pool_memory(PM_FNAME);
271 + dst->commands->append(m);
276 - dst->set_command(src->command, src->cmd_type);
277 dst->set_target(src->target);
281 void free_runscript(RUNSCRIPT *script)
283 Dmsg0(500, "runscript: freeing RUNSCRIPT object\n");
285 - if (script->command) {
286 - free_pool_memory(script->command);
288 + if (script->commands) {
289 + foreach_alist(c, script->commands) {
290 + free_pool_memory(c);
292 + delete script->commands;
294 if (script->target) {
295 free_pool_memory(script->target);
296 @@ -108,60 +122,15 @@
297 int run_scripts(JCR *jcr, alist *runscripts, const char *label)
299 Dmsg2(200, "runscript: running all RUNSCRIPT object (%s) JobStatus=%c\n", label, jcr->JobStatus);
306 - if (strstr(label, NT_("Before"))) {
307 - when = SCRIPT_Before;
309 - when = SCRIPT_After;
312 if (runscripts == NULL) {
313 Dmsg0(100, "runscript: WARNING RUNSCRIPTS list is NULL\n");
319 foreach_alist(script, runscripts) {
320 - Dmsg2(200, "runscript: try to run %s:%s\n", NPRT(script->target), NPRT(script->command));
323 - if ((script->when & SCRIPT_Before) && (when & SCRIPT_Before)) {
324 - if ((script->on_success
325 - && (jcr->JobStatus == JS_Running || jcr->JobStatus == JS_Created))
326 - || (script->on_failure && job_canceled(jcr))
329 - Dmsg4(200, "runscript: Run it because SCRIPT_Before (%s,%i,%i,%c)\n",
330 - script->command, script->on_success, script->on_failure,
336 - if ((script->when & SCRIPT_After) && (when & SCRIPT_After)) {
337 - if ((script->on_success && (jcr->JobStatus == JS_Terminated))
338 - || (script->on_failure && job_canceled(jcr))
341 - Dmsg4(200, "runscript: Run it because SCRIPT_After (%s,%i,%i,%c)\n",
342 - script->command, script->on_success, script->on_failure,
348 - if (!script->is_local()) {
352 - /* we execute it */
354 - script->run(jcr, label);
356 + script->run(jcr, label);
363 /* set this->command to cmd */
364 -void RUNSCRIPT::set_command(const POOLMEM *cmd, int acmd_type)
365 +void RUNSCRIPT::add_command(const POOLMEM *cmd, char acmd_type)
367 Dmsg1(500, "runscript: setting command = %s\n", NPRT(cmd));
369 @@ -184,14 +153,21 @@
374 - command = get_pool_memory(PM_FNAME);
376 + commands = New(alist(5, not_owned_by_alist));
379 - pm_strcpy(command, cmd);
380 - cmd_type = acmd_type;
381 + POOLMEM *c = get_pool_memory(PM_FNAME);
382 + Mmsg(c, "%c%s", acmd_type, cmd);
383 + commands->append(c);
386 +void RUNSCRIPT::get_command(const char* command, char *acmd_type, char **cmd)
388 + *acmd_type = command[0];
389 + *cmd = (char *)command + 1;
392 /* set this->target to client_name */
393 void RUNSCRIPT::set_target(const POOLMEM *client_name)
395 @@ -210,14 +186,71 @@
397 bool RUNSCRIPT::run(JCR *jcr, const char *name)
399 - Dmsg1(100, "runscript: running a RUNSCRIPT object type=%d\n", cmd_type);
405 + if (strstr(name, NT_("Before"))) {
406 + when = SCRIPT_Before;
408 + when = SCRIPT_After;
411 + foreach_alist(c, this->commands) {
412 + Dmsg2(200, "runscript: try to run %s:%s\n", NPRT(this->target), NPRT(c));
415 + if ((this->when & SCRIPT_Before) && (when & SCRIPT_Before)) {
416 + if ((this->on_success
417 + && (jcr->JobStatus == JS_Running || jcr->JobStatus == JS_Created))
418 + || (this->on_failure && job_canceled(jcr))
421 + Dmsg4(200, "runscript: Run it because SCRIPT_Before (%s,%i,%i,%c)\n",
422 + c, this->on_success, this->on_failure,
428 + if ((this->when & SCRIPT_After) && (when & SCRIPT_After)) {
429 + if ((this->on_success && (jcr->JobStatus == JS_Terminated))
430 + || (this->on_failure && job_canceled(jcr))
433 + Dmsg4(200, "runscript: Run it because SCRIPT_After (%s,%i,%i,%c)\n",
434 + c, this->on_success, this->on_failure,
440 + if (!this->is_local()) {
444 + /* we execute it */
446 + this->run_command(c, jcr, name);
452 +bool RUNSCRIPT::run_command(const char *command, JCR *jcr, const char *name)
454 POOLMEM *ecmd = get_pool_memory(PM_FNAME);
457 char line[MAXSTRING];
461 - ecmd = edit_job_codes(jcr, ecmd, this->command, "", this->job_code_callback);
462 - Dmsg1(100, "runscript: running '%s'...\n", ecmd);
463 + this->get_command(command, &cmd_type, &cmd);
464 + ecmd = edit_job_codes(jcr, ecmd, cmd, "", this->job_code_callback);
466 + Dmsg2(100, "runscript: running '%s' object type=%c...\n", ecmd, cmd_type);
467 Jmsg(jcr, M_INFO, 0, _("%s: run %s \"%s\"\n"),
468 cmd_type==SHELL_CMD?"shell command":"console command", name, ecmd);
472 void RUNSCRIPT::debug()
475 Dmsg0(200, "runscript: debug\n");
476 Dmsg0(200, _(" --> RunScript\n"));
477 - Dmsg1(200, _(" --> Command=%s\n"), NPRT(command));
478 + foreach_alist(c, commands) {
479 + Dmsg1(200, _(" --> Command=%s\n"), NPRT(c));
481 Dmsg1(200, _(" --> Target=%s\n"), NPRT(target));
482 Dmsg1(200, _(" --> RunOnSuccess=%u\n"), on_success);
483 Dmsg1(200, _(" --> RunOnFailure=%u\n"), on_failure);