]> git.sur5r.net Git - bacula/bacula/blob - bacula/src/lib/runscript.c
Update copyrights
[bacula/bacula] / bacula / src / lib / runscript.c
1 /*
2  * Manipulation routines for RunScript list
3  *
4  *  Eric Bollengier, May 2006
5  *
6  *  Version $Id$
7  *
8  */
9 /*
10    Bacula® - The Network Backup Solution
11
12    Copyright (C) 2006-2006 Free Software Foundation Europe e.V.
13
14    The main author of Bacula is Kern Sibbald, with contributions from
15    many others, a complete list can be found in the file AUTHORS.
16    This program is Free Software; you can redistribute it and/or
17    modify it under the terms of version two of the GNU General Public
18    License as published by the Free Software Foundation plus additions
19    that are listed in the file LICENSE.
20
21    This program is distributed in the hope that it will be useful, but
22    WITHOUT ANY WARRANTY; without even the implied warranty of
23    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
24    General Public License for more details.
25
26    You should have received a copy of the GNU General Public License
27    along with this program; if not, write to the Free Software
28    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
29    02110-1301, USA.
30
31    Bacula® is a registered trademark of John Walker.
32    The licensor of Bacula is the Free Software Foundation Europe
33    (FSFE), Fiduciary Program, Sumatrastrasse 25, 8006 Zürich,
34    Switzerland, email:ftf@fsfeurope.org.
35 */
36
37
38 #include "bacula.h"
39 #include "jcr.h"
40
41 #include "runscript.h"
42
43 RUNSCRIPT *new_runscript()
44 {
45    Dmsg0(500, "runscript: creating new RUNSCRIPT object\n");
46    RUNSCRIPT *cmd = (RUNSCRIPT *)malloc(sizeof(RUNSCRIPT));
47    memset(cmd, 0, sizeof(RUNSCRIPT));
48    cmd->reset_default();
49    
50    return cmd;
51 }
52
53 void RUNSCRIPT::reset_default(bool free_strings)
54 {
55    if (free_strings && command) {
56      free_pool_memory(command);
57    }
58    if (free_strings && target) {
59      free_pool_memory(target);
60    }
61    
62    target = NULL;
63    command = NULL;
64    on_success = true;
65    on_failure = false;
66    abort_on_error = true;
67    when = SCRIPT_Never;
68    old_proto = false;        /* TODO: drop this with bacula 1.42 */
69 }
70
71 RUNSCRIPT *copy_runscript(RUNSCRIPT *src)
72 {
73    Dmsg0(500, "runscript: creating new RUNSCRIPT object from other\n");
74
75    RUNSCRIPT *dst = (RUNSCRIPT *)malloc(sizeof(RUNSCRIPT));
76    memcpy(dst, src, sizeof(RUNSCRIPT));
77
78    dst->command = NULL;
79    dst->target = NULL;
80
81    dst->set_command(src->command);
82    dst->set_target(src->target);
83
84    return dst;   
85 }
86
87 void free_runscript(RUNSCRIPT *script)
88 {
89    Dmsg0(500, "runscript: freeing RUNSCRIPT object\n");
90
91    if (script->command) {
92       free_pool_memory(script->command);
93    }
94    if (script->target) {
95       free_pool_memory(script->target);
96    }
97    free(script);
98 }
99
100 int run_scripts(JCR *jcr, alist *runscripts, const char *label)
101 {
102    Dmsg2(200, "runscript: running all RUNSCRIPT object (%s) JobStatus=%c\n", label, jcr->JobStatus);
103    
104    RUNSCRIPT *script;
105    bool runit;
106    bool status;
107
108    if (runscripts == NULL) {
109       Dmsg0(100, "runscript: WARNING RUNSCRIPTS list is NULL\n");
110       return 0;
111    }
112
113    foreach_alist(script, runscripts) {
114       Dmsg2(200, "runscript: try to run %s:%s\n", NPRT(script->target), NPRT(script->command));
115       runit=false;
116
117       if ((script->when & SCRIPT_Before) && (jcr->JobStatus == JS_Created)) {
118         Dmsg0(200, "runscript: Run it because SCRIPT_Before\n");
119         runit = true;
120       }
121
122       if ((script->when & SCRIPT_Before) && (jcr->JobStatus == JS_Running)) {
123         Dmsg0(200, "runscript: Run it because SCRIPT_Before\n");
124         runit = true;
125       }
126
127       if (script->when & SCRIPT_After) {
128         if (  (script->on_success && (jcr->JobStatus == JS_Terminated))
129             ||
130               (script->on_failure && job_canceled(jcr))
131            )
132         {
133            Dmsg4(200, "runscript: Run it because SCRIPT_After (%s,%i,%i,%c)\n", script->command,
134                                                                                 script->on_success,
135                                                                                 script->on_failure,
136                                                                                 jcr->JobStatus );
137            runit = true;
138         }
139       }
140
141       if (!script->is_local()) {
142          runit=false;
143       }
144
145       /* we execute it */
146       if (runit) {
147         status = script->run(jcr, label);
148
149         /* cancel running job properly */
150         if (   script->abort_on_error 
151             && (status == false) 
152             && (jcr->JobStatus == JS_Created || jcr->JobStatus == JS_Running)
153            )
154         {
155            set_jcr_job_status(jcr, JS_ErrorTerminated);
156         }
157       }
158    }
159    return 1;
160 }
161
162 bool RUNSCRIPT::is_local()
163 {
164    if (!target || (strcmp(target, "") == 0)) {
165       return true;
166    } else {
167       return false;
168    }
169 }
170
171 /* set this->command to cmd */
172 void RUNSCRIPT::set_command(const POOLMEM *cmd)
173 {
174    Dmsg1(500, "runscript: setting command = %s\n", NPRT(cmd));
175
176    if (!cmd) {
177       return;
178    }
179
180    if (!command) {
181       command = get_pool_memory(PM_FNAME);
182    }
183
184    pm_strcpy(command, cmd);
185 }
186
187 /* set this->target to client_name */
188 void RUNSCRIPT::set_target(const POOLMEM *client_name)
189 {
190    Dmsg1(500, "runscript: setting target\n", NPRT(client_name));
191
192    if (!client_name) {
193       return;
194    }
195
196    if (!target) {
197       target = get_pool_memory(PM_FNAME);
198    }
199
200    pm_strcpy(target, client_name);
201 }
202
203 int RUNSCRIPT::run(JCR *jcr, const char *name)
204 {
205    Dmsg0(200, "runscript: running a RUNSCRIPT object\n");
206    POOLMEM *ecmd = get_pool_memory(PM_FNAME);
207    int status;
208    BPIPE *bpipe;
209    char line[MAXSTRING];
210
211    ecmd = edit_job_codes(jcr, ecmd, this->command, "");
212    Dmsg1(100, "runscript: running '%s'...\n", ecmd);
213    Jmsg(jcr, M_INFO, 0, _("%s: run command \"%s\"\n"), name, ecmd);
214
215    bpipe = open_bpipe(ecmd, 0, "r");
216    free_pool_memory(ecmd);
217    if (bpipe == NULL) {
218       berrno be;
219       Jmsg(jcr, M_ERROR, 0, _("Runscript: %s could not execute. ERR=%s\n"), name,
220          be.strerror());
221       return false;
222    }
223    while (fgets(line, sizeof(line), bpipe->rfd)) {
224       int len = strlen(line);
225       if (len > 0 && line[len-1] == '\n') {
226          line[len-1] = 0;
227       }
228       Jmsg(jcr, M_INFO, 0, _("%s: %s\n"), name, line);
229    }
230    status = close_bpipe(bpipe);
231    if (status != 0) {
232       berrno be;
233       Jmsg(jcr, M_ERROR, 0, _("Runscript: %s returned non-zero status=%d. ERR=%s\n"), name,
234          be.code(status), be.strerror(status));
235       return false;
236    }
237    return true;
238 }
239
240 void free_runscripts(alist *runscripts)
241 {
242    Dmsg0(500, "runscript: freeing all RUNSCRIPTS object\n");
243
244    RUNSCRIPT *elt;
245    foreach_alist(elt, runscripts) {
246       free_runscript(elt);
247    }
248 }
249
250 void RUNSCRIPT::debug()
251 {
252    Dmsg0(200, "runscript: debug\n");
253    Dmsg0(200,  _(" --> RunScript\n"));
254    Dmsg1(200,  _("  --> Command=%s\n"), NPRT(command));
255    Dmsg1(200,  _("  --> Target=%s\n"),  NPRT(target));
256    Dmsg1(200,  _("  --> RunOnSuccess=%u\n"),  on_success);
257    Dmsg1(200,  _("  --> RunOnFailure=%u\n"),  on_failure);
258    Dmsg1(200,  _("  --> AbortJobOnError=%u\n"),  abort_on_error);
259    Dmsg1(200,  _("  --> RunWhen=%u\n"),  when);
260 }