X-Git-Url: https://git.sur5r.net/?a=blobdiff_plain;f=bacula%2Fsrc%2Flib%2Frunscript.c;h=47a55c631bafa35069becc5dba1b2dc4d88f4d37;hb=4132c9f33642f579d89700f36caced609d374d51;hp=1041be32450a222b4eef45eab7a67f92a5025bab;hpb=51f62acce0e2633b1fca669680e25a84f99137ff;p=bacula%2Fbacula diff --git a/bacula/src/lib/runscript.c b/bacula/src/lib/runscript.c index 1041be3245..47a55c631b 100644 --- a/bacula/src/lib/runscript.c +++ b/bacula/src/lib/runscript.c @@ -6,7 +6,7 @@ The main author of Bacula is Kern Sibbald, with contributions from many others, a complete list can be found in the file AUTHORS. This program is Free Software; you can redistribute it and/or - modify it under the terms of version two of the GNU General Public + modify it under the terms of version three of the GNU Affero General Public License as published by the Free Software Foundation and included in the file LICENSE. @@ -15,12 +15,12 @@ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. - You should have received a copy of the GNU General Public License + You should have received a copy of the GNU Affero General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - Bacula® is a registered trademark of John Walker. + Bacula® is a registered trademark of Kern Sibbald. The licensor of Bacula is the Free Software Foundation Europe (FSFE), Fiduciary Program, Sumatrastrasse 25, 8006 Zürich, Switzerland, email:ftf@fsfeurope.org. @@ -38,6 +38,14 @@ #include "bacula.h" #include "jcr.h" #include "runscript.h" + +/* + * This function pointer is set only by the Director (dird.c), + * and is not set in the File daemon, because the File + * daemon cannot run console commands. + */ +bool (*console_command)(JCR *jcr, const char *cmd) = NULL; + RUNSCRIPT *new_runscript() { @@ -78,7 +86,7 @@ RUNSCRIPT *copy_runscript(RUNSCRIPT *src) dst->command = NULL; dst->target = NULL; - dst->set_command(src->command); + dst->set_command(src->command, src->cmd_type); dst->set_target(src->target); return dst; @@ -108,6 +116,8 @@ int run_scripts(JCR *jcr, alist *runscripts, const char *label) if (strstr(label, NT_("Before"))) { when = SCRIPT_Before; + } else if (bstrcmp(label, NT_("ClientAfterVSS"))) { + when = SCRIPT_AfterVSS; } else { when = SCRIPT_After; } @@ -122,9 +132,10 @@ int run_scripts(JCR *jcr, alist *runscripts, const char *label) 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)) + if ((script->on_success && + (jcr->JobStatus == JS_Running || jcr->JobStatus == JS_Created)) + || (script->on_failure && + (job_canceled(jcr) || jcr->JobStatus == JS_Differences)) ) { Dmsg4(200, "runscript: Run it because SCRIPT_Before (%s,%i,%i,%c)\n", @@ -134,9 +145,23 @@ int run_scripts(JCR *jcr, alist *runscripts, const char *label) } } + if ((script->when & SCRIPT_AfterVSS) && (when & SCRIPT_AfterVSS)) { + if ((script->on_success && (jcr->JobStatus == JS_Blocked)) + || (script->on_failure && job_canceled(jcr)) + ) + { + Dmsg4(200, "runscript: Run it because SCRIPT_AfterVSS (%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)) + if ((script->on_success && + (jcr->JobStatus == JS_Terminated || jcr->JobStatus == JS_Warnings)) + || (script->on_failure && + (job_canceled(jcr) || jcr->JobStatus == JS_Differences)) ) { Dmsg4(200, "runscript: Run it because SCRIPT_After (%s,%i,%i,%c)\n", @@ -168,7 +193,7 @@ bool RUNSCRIPT::is_local() } /* set this->command to cmd */ -void RUNSCRIPT::set_command(const POOLMEM *cmd) +void RUNSCRIPT::set_command(const char *cmd, int acmd_type) { Dmsg1(500, "runscript: setting command = %s\n", NPRT(cmd)); @@ -181,10 +206,11 @@ void RUNSCRIPT::set_command(const POOLMEM *cmd) } pm_strcpy(command, cmd); + cmd_type = acmd_type; } /* set this->target to client_name */ -void RUNSCRIPT::set_target(const POOLMEM *client_name) +void RUNSCRIPT::set_target(const char *client_name) { Dmsg1(500, "runscript: setting target = %s\n", NPRT(client_name)); @@ -201,7 +227,7 @@ void RUNSCRIPT::set_target(const POOLMEM *client_name) bool RUNSCRIPT::run(JCR *jcr, const char *name) { - Dmsg0(200, "runscript: running a RUNSCRIPT object\n"); + Dmsg1(100, "runscript: running a RUNSCRIPT object type=%d\n", cmd_type); POOLMEM *ecmd = get_pool_memory(PM_FNAME); int status; BPIPE *bpipe; @@ -209,31 +235,43 @@ bool RUNSCRIPT::run(JCR *jcr, const char *name) ecmd = edit_job_codes(jcr, ecmd, this->command, "", this->job_code_callback); Dmsg1(100, "runscript: running '%s'...\n", ecmd); - Jmsg(jcr, M_INFO, 0, _("%s: run command \"%s\"\n"), name, ecmd); - - bpipe = open_bpipe(ecmd, 0, "r"); - free_pool_memory(ecmd); - if (bpipe == NULL) { - berrno be; - Jmsg(jcr, M_ERROR, 0, _("Runscript: %s could not execute. ERR=%s\n"), name, - be.bstrerror()); - goto bail_out; - } - while (fgets(line, sizeof(line), bpipe->rfd)) { - int len = strlen(line); - if (len > 0 && line[len-1] == '\n') { - line[len-1] = 0; + Jmsg(jcr, M_INFO, 0, _("%s: run %s \"%s\"\n"), + cmd_type==SHELL_CMD?"shell command":"console command", name, ecmd); + + switch (cmd_type) { + case SHELL_CMD: + bpipe = open_bpipe(ecmd, 0, "r"); + free_pool_memory(ecmd); + if (bpipe == NULL) { + berrno be; + Jmsg(jcr, M_ERROR, 0, _("Runscript: %s could not execute. ERR=%s\n"), name, + be.bstrerror()); + goto bail_out; } - Jmsg(jcr, M_INFO, 0, _("%s: %s\n"), name, line); - } - status = close_bpipe(bpipe); - if (status != 0) { - berrno be; - Jmsg(jcr, M_ERROR, 0, _("Runscript: %s returned non-zero status=%d. ERR=%s\n"), name, - be.code(status), be.bstrerror(status)); - goto bail_out; + while (fgets(line, sizeof(line), bpipe->rfd)) { + int len = strlen(line); + if (len > 0 && line[len-1] == '\n') { + line[len-1] = 0; + } + Jmsg(jcr, M_INFO, 0, _("%s: %s\n"), name, line); + } + status = close_bpipe(bpipe); + if (status != 0) { + berrno be; + Jmsg(jcr, M_ERROR, 0, _("Runscript: %s returned non-zero status=%d. ERR=%s\n"), name, + be.code(status), be.bstrerror(status)); + goto bail_out; + } + Dmsg0(100, "runscript OK\n"); + break; + case CONSOLE_CMD: + if (console_command) { /* can we run console command? */ + if (!console_command(jcr, ecmd)) { /* yes, do so */ + goto bail_out; + } + } + break; } - Dmsg0(100, "runscript OK\n"); return true; bail_out: @@ -268,7 +306,6 @@ void RUNSCRIPT::debug() } void RUNSCRIPT::set_job_code_callback(job_code_callback_t arg_job_code_callback) - { this->job_code_callback = arg_job_code_callback; }