]> git.sur5r.net Git - bacula/bacula/commitdiff
o initial add
authorEric Bollengier <eric@eb.homelinux.org>
Sat, 27 May 2006 17:24:10 +0000 (17:24 +0000)
committerEric Bollengier <eric@eb.homelinux.org>
Sat, 27 May 2006 17:24:10 +0000 (17:24 +0000)
git-svn-id: https://bacula.svn.sourceforge.net/svnroot/bacula/trunk@3035 91ce42f0-d328-0410-95d8-f526ca767f89

bacula/src/lib/runscript.c [new file with mode: 0644]
bacula/src/lib/runscript.h [new file with mode: 0644]

diff --git a/bacula/src/lib/runscript.c b/bacula/src/lib/runscript.c
new file mode 100644 (file)
index 0000000..8b9b92c
--- /dev/null
@@ -0,0 +1,249 @@
+/*
+ * Manipulation routines for RunScript list
+ *
+ *  Eric Bollengier, May 2006
+ *
+ *  Version $Id$
+ *
+ */
+/*
+   Copyright (C) 2000-2006 Kern Sibbald
+
+   This program is free software; you can redistribute it and/or
+   modify it under the terms of the GNU General Public License
+   version 2 as amended with additional clauses defined in the
+   file LICENSE in the main source directory.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 
+   the file LICENSE for additional details.
+
+ */
+
+
+#include "bacula.h"
+#include "jcr.h"
+
+#define USE_RUNSCRIPT
+
+#include "runscript.h"
+
+RUNSCRIPT *new_runscript()
+{
+   Dmsg0(500, "runscript: creating new RUNSCRIPT object\n");
+   RUNSCRIPT *cmd = (RUNSCRIPT *)malloc(sizeof(RUNSCRIPT));
+   memset(cmd, 0, sizeof(RUNSCRIPT));
+   cmd->reset_default();
+   
+   return cmd;
+}
+
+void RUNSCRIPT::reset_default(bool free_strings)
+{
+   if (free_strings && command) {
+     free_pool_memory(command);
+   }
+   if (free_strings && target) {
+     free_pool_memory(target);
+   }
+   
+   target = NULL;
+   command = NULL;
+   on_success = true;
+   on_failure = false;
+   abort_on_error = true;
+   when = SCRIPT_Never;
+}
+
+RUNSCRIPT *copy_runscript(RUNSCRIPT *src)
+{
+   Dmsg0(500, "runscript: creating new RUNSCRIPT object from other\n");
+
+   RUNSCRIPT *dst = (RUNSCRIPT *)malloc(sizeof(RUNSCRIPT));
+   memcpy(dst, src, sizeof(RUNSCRIPT));
+
+   dst->command = NULL;
+   dst->target = NULL;
+
+   dst->set_command(src->command);
+   dst->set_target(src->target);
+
+   return dst;   
+}
+
+void free_runscript(RUNSCRIPT *script)
+{
+   Dmsg0(500, "runscript: freeing RUNSCRIPT object\n");
+
+   if (script->command) {
+      free_pool_memory(script->command);
+   }
+   if (script->target) {
+      free_pool_memory(script->target);
+   }
+   free(script);
+}
+
+int run_scripts(JCR *jcr, alist *runscripts, const char *label)
+{
+   Dmsg2(200, "runscript: running all RUNSCRIPT object (%s) JobStatus=%c\n", label, jcr->JobStatus);
+   
+   RUNSCRIPT *script;
+   bool runit;
+   bool status;
+
+   if (runscripts == NULL) {
+      Dmsg0(100, "runscript: WARNING RUNSCRIPTS list is NULL\n");
+      return 0;
+   }
+
+   foreach_alist(script, runscripts) {
+      Dmsg2(200, "runscript: try to run %s:%s\n", NPRT(script->target), NPRT(script->command));
+      runit=false;
+
+      if ((script->when & SCRIPT_Before) && (jcr->JobStatus == JS_Created)) {
+        Dmsg0(200, "runscript: Run it because SCRIPT_Before\n");
+        runit = true;
+      }
+
+      if ((script->when & SCRIPT_Before) && (jcr->JobStatus == JS_Running)) {
+        Dmsg0(200, "runscript: Run it because SCRIPT_Before\n");
+        runit = true;
+      }
+
+      if (script->when & SCRIPT_After) {
+        if (  (script->on_success && (jcr->JobStatus == JS_Terminated))
+            ||
+              (script->on_failure && job_canceled(jcr))
+           )
+        {
+           Dmsg4(200, "runscript: Run it because SCRIPT_After (%s,%i,%i,%c)\n", script->command,
+                                                                                script->on_success,
+                                                                                script->on_failure,
+                                                                                jcr->JobStatus );
+           script->when ^= SCRIPT_After; /* reset SCRIPT_After bit */
+           runit = true;
+        }
+      }
+
+      if (!script->is_local()) {
+         runit=false;
+      }
+
+      /* we execute it */
+      if (runit) {
+        status = script->run(jcr, label);
+
+        /* cancel running job properly */
+        if (   script->abort_on_error 
+            && (status == false) 
+            && (jcr->JobStatus == JS_Created)
+           )
+        {
+           set_jcr_job_status(jcr, JS_ErrorTerminated);
+        }
+      }
+   }
+   return 1;
+}
+
+bool RUNSCRIPT::is_local()
+{
+   if (!target || (strcmp(target, "") == 0)) {
+      return true;
+   } else {
+      return false;
+   }
+}
+
+/* set this->command to cmd */
+void RUNSCRIPT::set_command(const POOLMEM *cmd)
+{
+   Dmsg1(500, "runscript: setting command = %s\n", NPRT(cmd));
+
+   if (!cmd) {
+      return;
+   }
+
+   if (!command) {
+      command = get_pool_memory(PM_FNAME);
+   }
+
+   pm_strcpy(command, cmd);
+}
+
+/* set this->target to client_name */
+void RUNSCRIPT::set_target(const POOLMEM *client_name)
+{
+   Dmsg1(500, "runscript: setting target\n", NPRT(client_name));
+
+   if (!client_name) {
+      return;
+   }
+
+   if (!target) {
+      target = get_pool_memory(PM_FNAME);
+   }
+
+   pm_strcpy(target, client_name);
+}
+
+int RUNSCRIPT::run(JCR *jcr, const char *name)
+{
+   Dmsg0(200, "runscript: running a RUNSCRIPT object\n");
+   POOLMEM *ecmd = get_pool_memory(PM_FNAME);
+   int status;
+   BPIPE *bpipe;
+   char line[MAXSTRING];
+
+   ecmd = edit_job_codes(jcr, ecmd, this->command, "");
+   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_FATAL, 0, _("%s could not execute. ERR=%s\n"), name,
+         be.strerror());
+      return false;
+   }
+   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_FATAL, 0, _("%s returned non-zero status=%d. ERR=%s\n"), name,
+         status, be.strerror(status));
+      return false;
+   }
+   return true;
+}
+
+void free_runscripts(alist *runscripts)
+{
+   Dmsg0(500, "runscript: freeing all RUNSCRIPTS object\n");
+
+   RUNSCRIPT *elt;
+   foreach_alist(elt, runscripts) {
+      free_runscript(elt);
+   }
+}
+
+void RUNSCRIPT::debug()
+{
+   Dmsg0(200, "runscript: debug\n");
+   Dmsg0(200,  _(" --> RunScript\n"));
+   Dmsg1(200,  _("  --> Command=%s\n"), NPRT(command));
+   Dmsg1(200,  _("  --> Target=%s\n"),  NPRT(target));
+   Dmsg1(200,  _("  --> RunOnSuccess=%u\n"),  on_success);
+   Dmsg1(200,  _("  --> RunOnFailure=%u\n"),  on_failure);
+   Dmsg1(200,  _("  --> AbortJobOnError=%u\n"),  abort_on_error);
+   Dmsg1(200,  _("  --> RunWhen=%u\n"),  when);
+}
diff --git a/bacula/src/lib/runscript.h b/bacula/src/lib/runscript.h
new file mode 100644 (file)
index 0000000..3d43608
--- /dev/null
@@ -0,0 +1,94 @@
+/*
+ * Bacula RUNSCRIPT Structure definition for FileDaemon and Director
+ * Eric Bollengier May 2006
+ * Version $Id$
+ */
+/*
+   Copyright (C) 2000-2006 Kern Sibbald
+
+   This program is free software; you can redistribute it and/or
+   modify it under the terms of the GNU General Public License
+   version 2 as amended with additional clauses defined in the
+   file LICENSE in the main source directory.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 
+   the file LICENSE for additional details.
+
+ */
+
+
+#ifndef __RUNSCRIPT_H_
+#define __RUNSCRIPT_H_ 1
+
+#if defined(FILE_DAEMON) || defined(DIRECTOR_DAEMON)
+# define USE_RUNSCRIPT
+#endif
+
+#ifdef USE_RUNSCRIPT
+
+/* Usage:
+ *
+ * #define USE_RUNSCRIPT
+ * #include "lib/runscript.h"
+ * 
+ * RUNSCRIPT *script = new_runscript();
+ * script->set_command("/bin/sleep 20");
+ * script->on_failure = true;
+ * script->when = SCRIPT_After;
+ * 
+ * script->run("Label");
+ * free_runscript(script);
+ */
+
+/* 
+ * RUNSCRIPT->when can take following value : 
+ */
+enum {
+   SCRIPT_Never  = 0,
+   SCRIPT_After  = 1,          /* AfterJob */
+   SCRIPT_Before = 2,          /* BeforeJob */
+   SCRIPT_Any    = 3                   /* Before and After */
+};
+
+/*
+ * Structure for RunScript ressource
+ */
+class RUNSCRIPT {
+public:
+   POOLMEM *command;           /* command string */
+   POOLMEM *target;            /* host target */
+   char level;                 /* Base|Full|Incr...|All (NYI) */
+   bool on_success;            /* executre command on job success (After) */
+   bool on_failure;             /* executre command on job failure (After) */
+   bool abort_on_error;         /* abort job on error (Before) */
+   int  when;                   /* SCRIPT_Before|Script_After BEFORE/AFTER JOB*/
+
+   int run(JCR *job, const char *name="");
+   bool can_run_at_level(int JobLevel) { return true;};        /* TODO */
+   void set_command(const POOLMEM *cmd);
+   void set_target(const POOLMEM *client_name);
+   void reset_default(bool free_string = false);
+   bool is_local();            /* true if running on local host */
+   void debug();
+};
+
+/* create new RUNSCRIPT (set all value to 0) */
+RUNSCRIPT *new_runscript();           
+
+/* create new RUNSCRIPT from an other */
+RUNSCRIPT *copy_runscript(RUNSCRIPT *src);
+
+/* launch each script from runscripts*/
+int run_scripts(JCR *jcr, alist *runscripts, const char *name); 
+
+/* free RUNSCRIPT (and all POOLMEM) */
+void free_runscript(RUNSCRIPT *script);
+
+/* foreach_alist free RUNSCRIPT */
+void free_runscripts(alist *runscripts); /* you have to free alist */
+
+#endif /* USE_RUNSCRIPT */
+
+#endif /* __RUNSCRIPT_H_ */