2 Bacula® - The Network Backup Solution
4 Copyright (C) 2006-2007 Free Software Foundation Europe e.V.
6 The main author of Bacula is Kern Sibbald, with contributions from
7 many others, a complete list can be found in the file AUTHORS.
8 This program is Free Software; you can redistribute it and/or
9 modify it under the terms of version two of the GNU General Public
10 License as published by the Free Software Foundation and included
13 This program is distributed in the hope that it will be useful, but
14 WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with this program; if not, write to the Free Software
20 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
23 Bacula® is a registered trademark of John Walker.
24 The licensor of Bacula is the Free Software Foundation Europe
25 (FSFE), Fiduciary Program, Sumatrastrasse 25, 8006 Zürich,
26 Switzerland, email:ftf@fsfeurope.org.
29 * Manipulation routines for RunScript list
31 * Eric Bollengier, May 2006
41 #include "runscript.h"
43 RUNSCRIPT *new_runscript()
45 Dmsg0(500, "runscript: creating new RUNSCRIPT object\n");
46 RUNSCRIPT *cmd = (RUNSCRIPT *)malloc(sizeof(RUNSCRIPT));
47 memset(cmd, 0, sizeof(RUNSCRIPT));
53 void RUNSCRIPT::reset_default(bool free_strings)
55 if (free_strings && command) {
56 free_pool_memory(command);
58 if (free_strings && target) {
59 free_pool_memory(target);
68 old_proto = false; /* TODO: drop this with bacula 1.42 */
71 RUNSCRIPT *copy_runscript(RUNSCRIPT *src)
73 Dmsg0(500, "runscript: creating new RUNSCRIPT object from other\n");
75 RUNSCRIPT *dst = (RUNSCRIPT *)malloc(sizeof(RUNSCRIPT));
76 memcpy(dst, src, sizeof(RUNSCRIPT));
81 dst->set_command(src->command);
82 dst->set_target(src->target);
87 void free_runscript(RUNSCRIPT *script)
89 Dmsg0(500, "runscript: freeing RUNSCRIPT object\n");
91 if (script->command) {
92 free_pool_memory(script->command);
95 free_pool_memory(script->target);
100 int run_scripts(JCR *jcr, alist *runscripts, const char *label)
102 Dmsg2(200, "runscript: running all RUNSCRIPT object (%s) JobStatus=%c\n", label, jcr->JobStatus);
109 if (strstr(label, NT_("Before"))) {
110 when = SCRIPT_Before;
115 if (runscripts == NULL) {
116 Dmsg0(100, "runscript: WARNING RUNSCRIPTS list is NULL\n");
120 foreach_alist(script, runscripts) {
121 Dmsg2(200, "runscript: try to run %s:%s\n", NPRT(script->target), NPRT(script->command));
124 if ((script->when & SCRIPT_Before) && (when & SCRIPT_Before)) {
125 if ((script->on_success
126 && (jcr->JobStatus == JS_Running || jcr->JobStatus == JS_Created))
127 || (script->on_failure && job_canceled(jcr))
130 Dmsg4(200, "runscript: Run it because SCRIPT_Before (%s,%i,%i,%c)\n",
131 script->command, script->on_success, script->on_failure,
137 if ((script->when & SCRIPT_After) && (when & SCRIPT_After)) {
138 if ((script->on_success && (jcr->JobStatus == JS_Terminated))
139 || (script->on_failure && job_canceled(jcr))
142 Dmsg4(200, "runscript: Run it because SCRIPT_After (%s,%i,%i,%c)\n",
143 script->command, script->on_success, script->on_failure,
149 if (!script->is_local()) {
155 script->run(jcr, label);
161 bool RUNSCRIPT::is_local()
163 if (!target || (strcmp(target, "") == 0)) {
170 /* set this->command to cmd */
171 void RUNSCRIPT::set_command(const POOLMEM *cmd)
173 Dmsg1(500, "runscript: setting command = %s\n", NPRT(cmd));
180 command = get_pool_memory(PM_FNAME);
183 pm_strcpy(command, cmd);
186 /* set this->target to client_name */
187 void RUNSCRIPT::set_target(const POOLMEM *client_name)
189 Dmsg1(500, "runscript: setting target = %s\n", NPRT(client_name));
196 target = get_pool_memory(PM_FNAME);
199 pm_strcpy(target, client_name);
202 bool RUNSCRIPT::run(JCR *jcr, const char *name)
204 Dmsg0(200, "runscript: running a RUNSCRIPT object\n");
205 POOLMEM *ecmd = get_pool_memory(PM_FNAME);
208 char line[MAXSTRING];
210 ecmd = edit_job_codes(jcr, ecmd, this->command, "");
211 Dmsg1(100, "runscript: running '%s'...\n", ecmd);
212 Jmsg(jcr, M_INFO, 0, _("%s: run command \"%s\"\n"), name, ecmd);
214 bpipe = open_bpipe(ecmd, 0, "r");
215 free_pool_memory(ecmd);
218 Jmsg(jcr, M_ERROR, 0, _("Runscript: %s could not execute. ERR=%s\n"), name,
222 while (fgets(line, sizeof(line), bpipe->rfd)) {
223 int len = strlen(line);
224 if (len > 0 && line[len-1] == '\n') {
227 Jmsg(jcr, M_INFO, 0, _("%s: %s\n"), name, line);
229 status = close_bpipe(bpipe);
232 Jmsg(jcr, M_ERROR, 0, _("Runscript: %s returned non-zero status=%d. ERR=%s\n"), name,
233 be.code(status), be.bstrerror(status));
236 Dmsg0(100, "runscript OK\n");
240 /* cancel running job properly */
242 set_jcr_job_status(jcr, JS_ErrorTerminated);
244 Dmsg1(100, "runscript failed. fail_on_error=%d\n", fail_on_error);
248 void free_runscripts(alist *runscripts)
250 Dmsg0(500, "runscript: freeing all RUNSCRIPTS object\n");
253 foreach_alist(elt, runscripts) {
258 void RUNSCRIPT::debug()
260 Dmsg0(200, "runscript: debug\n");
261 Dmsg0(200, _(" --> RunScript\n"));
262 Dmsg1(200, _(" --> Command=%s\n"), NPRT(command));
263 Dmsg1(200, _(" --> Target=%s\n"), NPRT(target));
264 Dmsg1(200, _(" --> RunOnSuccess=%u\n"), on_success);
265 Dmsg1(200, _(" --> RunOnFailure=%u\n"), on_failure);
266 Dmsg1(200, _(" --> FailJobOnError=%u\n"), fail_on_error);
267 Dmsg1(200, _(" --> RunWhen=%u\n"), when);