]> git.sur5r.net Git - bacula/bacula/commitdiff
- Remove a few HAVE_TLS #ifdefs
authorKern Sibbald <kern@sibbald.com>
Sat, 30 Apr 2005 14:47:49 +0000 (14:47 +0000)
committerKern Sibbald <kern@sibbald.com>
Sat, 30 Apr 2005 14:47:49 +0000 (14:47 +0000)
- Implement final Python style interface. More implemention to
  be done, but the interface should change little if at all.

git-svn-id: https://bacula.svn.sourceforge.net/svnroot/bacula/trunk@1968 91ce42f0-d328-0410-95d8-f526ca767f89

21 files changed:
bacula/examples/python/DirStartUp.py
bacula/examples/python/FDStartUp.py
bacula/examples/python/SDStartUp.py
bacula/src/baconfig.h
bacula/src/console/console.c
bacula/src/dird/Makefile.in
bacula/src/dird/dird.c
bacula/src/dird/python.c [deleted file]
bacula/src/dird/pythondir.c [new file with mode: 0644]
bacula/src/filed/Makefile.in
bacula/src/filed/filed.c
bacula/src/filed/python.c [deleted file]
bacula/src/filed/pythonfd.c [new file with mode: 0644]
bacula/src/lib/pythonlib.c
bacula/src/stored/Makefile.in
bacula/src/stored/dircmd.c
bacula/src/stored/job.c
bacula/src/stored/python.c [deleted file]
bacula/src/stored/pythonsd.c [new file with mode: 0644]
bacula/src/stored/stored.c
bacula/src/version.h

index 230f307c09b9a8efc63c4f1ccd0cb3beb2e06e78..37eaa28d5cf20a301dc95bc39cf58b8cfce0a53f 100644 (file)
@@ -21,19 +21,19 @@ class BaculaEvents:
      """
      events = JobEvents()         # create instance of Job class
      events.job = job             # save Bacula's job pointer
-     job.set_events(events)       # register events desired
+     job.set_events = events      # register events desired
      sys.stderr = events          # send error output to Bacula
      sys.stdout = events          # send stdout to Bacula
-     jobid = job.get("JobId"); client = job.get("Client"); 
-     numvols = job.get("NumVols") 
-     job.set(JobReport="Python StartJob: JobId=%d Client=%s NumVols=%d\n" % (jobid,client,numvols))
+     jobid = job.JobId; client = job.Client
+     numvols = job.NumVols 
+     job.JobReport="Python Dir JobStart: JobId=%d Client=%s NumVols=%d\n" % (jobid,client,numvols) 
      return 1
 
   # Bacula Job is going to terminate
   def JobEnd(self, job):    
-     jobid = job.get("JobId")
-     client = job.get("Client") 
-     job.set(JobReport="Python EndJob output: JobId=%d Client=%s.\n" % (jobid, client))
+     jobid = job.JobId
+     client = job.Client 
+     job.JobReport="Python Dir JobEnd output: JobId=%d Client=%s.\n" % (jobid, client) 
      if (jobid < 2) :
         startid = job.run("run kernsave")
         print "Python started new Job: jobid=", startid
@@ -55,13 +55,13 @@ class JobEvents:
      noop = 1
 
   def NewVolume(self, job):
-     jobid = job.get("JobId")
-     client = job.get("Client") 
-     numvol = job.get("NumVols");
+     jobid = job.JobId
+     client = job.Client 
+     numvol = job.NumVols;
      print "JobId=%d Client=%s NumVols=%d" % (jobid, client, numvol)
-     job.set(JobReport="Python before New Volume set for Job.\n") 
-     job.set(VolumeName="TestA-001")
-     job.set(JobReport="Python after New Volume set for Job.\n") 
+     job.JobReport="Python before New Volume set for Job.\n"
+     job.VolumeName="TestA-001"
+     job.JobReport="Python after New Volume set for Job.\n"  
      return 1
 
 
@@ -73,7 +73,7 @@ class JobEvents:
   def open(self, file):
      print "Open %s called" % file
      self.fd = open('m.py', 'rb')
-     jobid = self.job.get("JobId")
+     jobid = self.job.JobId
      print "Open: JobId=%d" % jobid
      print "name=%s" % bacula.name
 
index 7b06ead86352a62f46b42c8f089c9943a4027b57..d553f2cd9e511575bda1ce2498e0c0cb7d29156c 100644 (file)
@@ -20,23 +20,23 @@ class BaculaEvents:
      """
      events = JobEvents()         # create instance of Job class
      events.job = job             # save Bacula's job pointer
-     job.set_events(events)       # register events desired
+     job.set_events = events      # register events desired
      sys.stderr = events          # send error output to Bacula
      sys.stdout = events          # send stdout to Bacula
-     jobid = job.get("JobId")
-     client = job.get("Client")
-     job.set(JobReport="Python FD StartJob: JobId=%d Client=%s \n" % (jobid,client))
+     jobid = job.JobId
+     client = job.Client
+     job.JobReport="Python FD JobStart: JobId=%d Client=%s \n" % (jobid,client)
      return 1
 
   # Bacula Job is going to terminate
   def JobEnd(self, job):    
-     jobid = job.get("JobId")
-     client = job.get("Client") 
-     job.set(JobReport="Python FD EndJob output: JobId=%d Client=%s.\n" % (jobid, client))
+     jobid = job.JobId
+     client = job.Client 
+     job.JobReport="Python FD JobEnd output: JobId=%d Client=%s.\n" % (jobid, client)
      return 1
 
   # Called here when the Bacula daemon is going to exit
-  def Exit(self, job):
+  def Exit(self):
       noop = 1
      
 bacula.set_events(BaculaEvents()) # register daemon events desired
@@ -58,7 +58,7 @@ class JobEvents:
   def Python_open(self, file):
      print "Open %s called" % file
      self.fd = open(file, 'rb')
-     jobid = self.job.get("JobId")
+     jobid = self.job.JobId
      print "Open: %s" % file
  
   # Read file data into Bacula memory buffer (mem)
index 480f7fb2875d02142fc2fd81ec20f19f2bfe4217..ff6a97b2e54623f5dc3b23680440a1d3abf72f4e 100644 (file)
@@ -20,24 +20,24 @@ class BaculaEvents:
      """
      events = JobEvents()         # create instance of Job class
      events.job = job             # save Bacula's job pointer
-     job.set_events(events)       # register events desired
+     job.set_events = events      # register events desired
      sys.stderr = events          # send error output to Bacula
      sys.stdout = events          # send stdout to Bacula
-     jobid = job.get("JobId")
-     client = job.get("Client")
-     job.set(JobReport="Python SD StartJob: JobId=%d Client=%s \n" % (jobid,client))
+     jobid = job.JobId
+     client = job.Client
+     job.JobReport="Python SD JobStart: JobId=%d Client=%s \n" % (jobid,client)
      return 1
 
   # Bacula Job is going to terminate
   def JobEnd(self, job):    
-     jobid = job.get("JobId")
-     client = job.get("Client") 
-     job.set(JobReport="Python SD EndJob output: JobId=%d Client=%s.\n" % (jobid, client))
+     jobid = job.JobId
+     client = job.Client 
+     job.JobReport="Python SD JobEnd output: JobId=%d Client=%s.\n" % (jobid, client)
      print "Python SD JobEnd\n"  
      return 1
 
   # Called here when the Bacula daemon is going to exit
-  def Exit(self, job):
+  def Exit(self):
       noop = 1
      
 bacula.set_events(BaculaEvents()) # register daemon events desired
@@ -54,4 +54,3 @@ class JobEvents:
   # Pass output back to Bacula
   def write(self, text):
      self.job.write(text)
-
index d74b673f5e6244bedca08c5ef76ec6fd98f58f41..f1347cc3125639ec86adb3ea95f061695ec83c8a 100644 (file)
 /* #define bindtextdomain(p, d) */
 #endif
 
+#ifndef HAVE_TLS
+#define init_tls(x) 0
+#define cleanup_tls()
+#endif
+
 
 /* This should go away! ****FIXME***** */
 #define MAXSTRING 500
index f6a6d98510653a8e035901d9bf6ab28de2b390dc..bdc0cc3431528498924d901fb448adf4b704d01d 100644 (file)
@@ -394,11 +394,9 @@ int main(int argc, char *argv[])
 
    parse_config(configfile);
 
-#ifdef HAVE_TLS
    if (init_tls() != 0) {
       Emsg0(M_ERROR_TERM, 0, _("TLS library initialization failed.\n"));
    }
-#endif
 
    if (!check_resources()) {
       Emsg1(M_ERROR_TERM, 0, _("Please correct configuration file: %s\n"), configfile);
@@ -551,9 +549,7 @@ static void terminate_console(int sig)
       exit(1);
    }
    already_here = true;
-#ifdef HAVE_TLS
    cleanup_tls();
-#endif
    free_pool_memory(args);
    con_term();
    (void)WSACleanup();               /* Cleanup Windows sockets */
index 504f4d4f05154974e15eb8b6c52255fdac341a49..3304e86327bb014249095aaee2403688deac19bd 100644 (file)
@@ -34,7 +34,7 @@ SVRSRCS = dird.c admin.c authenticate.c \
          fd_cmds.c getmsg.c inc_conf.c job.c \
          jobq.c mac.c \
          mountreq.c msgchan.c next_vol.c newvol.c \
-         python.c \
+         pythondir.c \
          recycle.c restore.c run_conf.c \
          scheduler.c sql_cmds.c \
          ua_acl.c ua_cmds.c ua_dotcmds.c \
@@ -49,7 +49,7 @@ SVROBJS = dird.o admin.o authenticate.o \
          fd_cmds.o getmsg.o inc_conf.o job.o \
          jobq.o mac.o \
          mountreq.o msgchan.o next_vol.o newvol.o \
-         python.o \
+         pythondir.o \
          recycle.o restore.o run_conf.o \
          scheduler.o sql_cmds.o \
          ua_acl.o ua_cmds.o ua_dotcmds.o \
index 286987fd5aecb01b8b09af54a14ca391d7b9b5c4..c1909f8c4e1a9f131d8eb5a06fa19fa9656d4b21 100644 (file)
@@ -194,11 +194,9 @@ int main (int argc, char *argv[])
 
    parse_config(configfile);
 
-#ifdef HAVE_TLS
    if (init_tls() != 0) {
       Jmsg((JCR *)NULL, M_ERROR_TERM, 0, _("TLS library initialization failed.\n"));
    }
-#endif
 
    if (!check_resources()) {
       Jmsg((JCR *)NULL, M_ERROR_TERM, 0, _("Please correct configuration file: %s\n"), configfile);
diff --git a/bacula/src/dird/python.c b/bacula/src/dird/python.c
deleted file mode 100644 (file)
index 09dfaeb..0000000
+++ /dev/null
@@ -1,278 +0,0 @@
-/*
- *
- * Bacula interface to Python for the Director
- *
- * Kern Sibbald, November MMIV
- *
- *   Version $Id$
- *
- */
-
-/*
-   Copyright (C) 2004-2005 Kern Sibbald
-
-   This program is free software; you can redistribute it and/or
-   modify it under the terms of the GNU General Public License as
-   published by the Free Software Foundation; either version 2 of
-   the License, or (at your option) any later version.
-
-   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 GNU
-   General Public License for more details.
-
-   You should have received a copy of the GNU General Public
-   License along with this program; if not, write to the Free
-   Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
-   MA 02111-1307, USA.
-
- */
-
-#include "bacula.h"
-#include "dird.h"
-
-#ifdef HAVE_PYTHON
-#undef _POSIX_C_SOURCE
-#include <Python.h>
-
-extern JCR *get_jcr_from_PyObject(PyObject *self);
-extern PyObject *find_method(PyObject *eventsObject, PyObject *method, 
-         const char *name);
-
-static PyObject *job_get(PyObject *self, PyObject *args);
-static PyObject *job_write(PyObject *self, PyObject *args);
-static PyObject *job_set(PyObject *self, PyObject *args, PyObject *keyw);
-static PyObject *set_job_events(PyObject *self, PyObject *args);
-static PyObject *jcr_run(PyObject *self, PyObject *args);
-
-/* Define Job entry points */
-PyMethodDef JobMethods[] = {
-    {"get", job_get, METH_VARARGS, "Get Job variables."},
-    {"set", (PyCFunction)job_set, METH_VARARGS|METH_KEYWORDS,
-        "Set Job variables."},
-    {"set_events", set_job_events, METH_VARARGS, "Define Job events."},
-    {"write", job_write, METH_VARARGS, "Write output."},
-    {"run", (PyCFunction)jcr_run, METH_VARARGS, "Run a Bacula command."},
-    {NULL, NULL, 0, NULL}             /* last item */
-};
-
-
-struct s_vars {
-   const char *name;
-   char *fmt;
-};
-
-/* Read-only variables */
-static struct s_vars vars[] = {
-   { N_("Job"),        "s"},
-   { N_("DirName"),    "s"},
-   { N_("Level"),      "s"},
-   { N_("Type"),       "s"},
-   { N_("JobId"),      "i"},
-   { N_("Client"),     "s"},
-   { N_("NumVols"),    "i"},
-   { N_("Pool"),       "s"},
-   { N_("Storage"),    "s"},
-   { N_("Catalog"),    "s"},
-   { N_("MediaType"),  "s"},
-   { N_("JobName"),    "s"},
-   { N_("JobStatus"),  "s"},
-
-   { NULL,             NULL}
-};
-
-/* Return Job variables */
-static PyObject *job_get(PyObject *self, PyObject *args)
-{
-   JCR *jcr;
-   char *item;
-   bool found = false;
-   int i;
-   char buf[10];
-
-   Dmsg0(100, "In job_get.\n");
-   if (!PyArg_ParseTuple(args, "s:get", &item)) {
-      return NULL;
-   }
-   jcr = get_jcr_from_PyObject(self);
-   for (i=0; vars[i].name; i++) {
-      if (strcmp(vars[i].name, item) == 0) {
-         found = true;
-         break;
-      }
-   }
-   if (!found) {
-      return NULL;
-   }
-   switch (i) {
-   case 0:                            /* Job */
-      return Py_BuildValue(vars[i].fmt, jcr->job->hdr.name);
-   case 1:                            /* Director's name */
-      return Py_BuildValue(vars[i].fmt, my_name);
-   case 2:                            /* level */
-      return Py_BuildValue(vars[i].fmt, job_level_to_str(jcr->JobLevel));
-   case 3:                            /* type */
-      return Py_BuildValue(vars[i].fmt, job_type_to_str(jcr->JobType));
-   case 4:                            /* JobId */
-      return Py_BuildValue(vars[i].fmt, jcr->JobId);
-   case 5:                            /* Client */
-      return Py_BuildValue(vars[i].fmt, jcr->client->hdr.name);
-   case 6:                            /* NumVols */
-      return Py_BuildValue(vars[i].fmt, jcr->NumVols);
-   case 7:                            /* Pool */
-      return Py_BuildValue(vars[i].fmt, jcr->pool->hdr.name);
-   case 8:                            /* Storage */
-      return Py_BuildValue(vars[i].fmt, jcr->store->hdr.name);
-   case 9:
-      return Py_BuildValue(vars[i].fmt, jcr->catalog->hdr.name);
-   case 10:                           /* MediaType */
-      return Py_BuildValue(vars[i].fmt, jcr->store->media_type);
-   case 11:                           /* JobName */
-      return Py_BuildValue(vars[i].fmt, jcr->Job);
-   case 12:                           /* JobStatus */
-      buf[1] = 0;
-      buf[0] = jcr->JobStatus;
-      return Py_BuildValue(vars[i].fmt, buf);
-   }
-   return NULL;
-}
-
-/* Set Job variables */
-static PyObject *job_set(PyObject *self, PyObject *args, PyObject *keyw)
-{
-   JCR *jcr;
-   char *msg = NULL;
-   char *VolumeName = NULL;
-   static char *kwlist[] = {"JobReport", "VolumeName", NULL};
-
-   Dmsg0(100, "In job_set.\n");
-   if (!PyArg_ParseTupleAndKeywords(args, keyw, "|ss:set", kwlist,
-        &msg, &VolumeName)) {
-      return NULL;
-   }
-   jcr = get_jcr_from_PyObject(self);
-
-   if (msg) {
-      Jmsg(jcr, M_INFO, 0, "%s", msg);
-   }
-
-   if (!VolumeName) {
-      Dmsg1(100, "No VolumeName. Event=%s\n", jcr->event);
-   } else {
-      Dmsg2(100, "Vol=%s Event=%s\n", VolumeName, jcr->event);
-   }
-   /* Make sure VolumeName is valid and we are in VolumeName event */
-   if (VolumeName && strcmp("NewVolume", jcr->event) == 0 &&
-       is_volume_name_legal(NULL, VolumeName)) {
-      pm_strcpy(jcr->VolumeName, VolumeName);
-      Dmsg1(100, "Set Vol=%s\n", VolumeName);
-   } else if (VolumeName) {
-      jcr->VolumeName[0] = 0;
-      Dmsg0(100, "Zap VolumeName.\n");
-      return Py_BuildValue("i", 0);  /* invalid volume name */
-   }
-   return Py_BuildValue("i", 1);
-}
-
-static PyObject *set_job_events(PyObject *self, PyObject *args)
-{
-   PyObject *eObject;
-   JCR *jcr;
-
-   Dmsg0(100, "In set_job_events.\n");
-   if (!PyArg_ParseTuple(args, "O:set_events", &eObject)) {
-      return NULL;
-   }
-   jcr = get_jcr_from_PyObject(self);
-   Py_XDECREF((PyObject *)jcr->Python_events);
-   Py_INCREF(eObject);
-   jcr->Python_events = (void *)eObject;
-
-   Py_INCREF(Py_None);
-   return Py_None;
-}
-
-/* Write text to job output */
-static PyObject *job_write(PyObject *self, PyObject *args)
-{
-   char *text;
-
-   if (!PyArg_ParseTuple(args, "s:write", &text)) {
-      return NULL;
-   }
-   if (text) {
-      JCR *jcr = get_jcr_from_PyObject(self);
-      Jmsg(jcr, M_INFO, 0, "%s", text);
-   }
-        
-   Py_INCREF(Py_None);
-   return Py_None;
-}
-
-/* Run a Bacula command */
-static PyObject *jcr_run(PyObject *self, PyObject *args)
-{
-   JCR *jcr;
-   char *item;
-   int stat;
-
-   if (!PyArg_ParseTuple(args, "s:get", &item)) {
-      return NULL;
-   }
-   jcr = get_jcr_from_PyObject(self);
-   UAContext *ua = new_ua_context(jcr);
-   ua->batch = true;
-   pm_strcpy(ua->cmd, item);          /* copy command */
-   parse_ua_args(ua);                 /* parse command */
-   stat = run_cmd(ua, ua->cmd);
-   free_ua_context(ua);
-   return Py_BuildValue("i", stat);
-}
-
-
-int generate_job_event(JCR *jcr, const char *event)
-{
-   PyObject *method = NULL;
-   PyObject *Job = (PyObject *)jcr->Python_job;
-   PyObject *result = NULL;
-   int stat = 0;
-
-   if (!Job) {
-      return 0;
-   }
-
-   PyEval_AcquireLock();
-
-   PyObject *events = (PyObject *)jcr->Python_events;
-   method = find_method(events, method, event);
-   if (!method) {
-      goto bail_out;
-   }
-
-   bstrncpy(jcr->event, event, sizeof(jcr->event));
-   result = PyObject_CallFunction(method, "O", Job);
-   jcr->event[0] = 0;             /* no event in progress */
-   if (result == NULL) {
-      if (PyErr_Occurred()) {
-         PyErr_Print();
-         Dmsg1(000, "Error in Python method %s\n", event);
-      }
-   } else {
-      stat = 1;
-   }
-   Py_XDECREF(result);
-
-bail_out:
-   PyEval_ReleaseLock();
-   return stat;
-}
-
-bool python_set_prog(JCR*, char const*) { return false; }
-
-#else
-
-/* Dummy if Python not configured */
-int generate_job_event(JCR *jcr, const char *event) { return 1; }
-   
-
-#endif /* HAVE_PYTHON */
diff --git a/bacula/src/dird/pythondir.c b/bacula/src/dird/pythondir.c
new file mode 100644 (file)
index 0000000..9869753
--- /dev/null
@@ -0,0 +1,292 @@
+/*
+ *
+ * Bacula interface to Python for the Director
+ *
+ * Kern Sibbald, November MMIV
+ *
+ *   Version $Id$
+ *
+ */
+
+/*
+   Copyright (C) 2004-2005 Kern Sibbald
+
+   This program is free software; you can redistribute it and/or
+   modify it under the terms of the GNU General Public License as
+   published by the Free Software Foundation; either version 2 of
+   the License, or (at your option) any later version.
+
+   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 GNU
+   General Public License for more details.
+
+   You should have received a copy of the GNU General Public
+   License along with this program; if not, write to the Free
+   Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
+   MA 02111-1307, USA.
+
+ */
+
+#include "bacula.h"
+#include "dird.h"
+
+#ifdef HAVE_PYTHON
+#undef _POSIX_C_SOURCE
+#include <Python.h>
+
+extern JCR *get_jcr_from_PyObject(PyObject *self);
+extern PyObject *find_method(PyObject *eventsObject, PyObject *method, 
+         const char *name);
+
+static int set_job_events(PyObject *self, PyObject *arg);
+static int job_run(PyObject *self, PyObject *arg);
+
+struct s_vars {
+   const char *name;
+   char *fmt;
+};
+
+/* Read-only variables */
+static struct s_vars getvars[] = {
+   { N_("Job"),        "s"},
+   { N_("DirName"),    "s"},
+   { N_("Level"),      "s"},
+   { N_("Type"),       "s"},
+   { N_("JobId"),      "i"},
+   { N_("Client"),     "s"},
+   { N_("NumVols"),    "i"},
+   { N_("Pool"),       "s"},
+   { N_("Storage"),    "s"},
+   { N_("Catalog"),    "s"},
+   { N_("MediaType"),  "s"},
+   { N_("JobName"),    "s"},
+   { N_("JobStatus"),  "s"},
+
+   { NULL,             NULL}
+};
+
+/* Writable variables */
+static struct s_vars setvars[] = {
+   { N_("set_events"), NULL},
+   { N_("run"),        NULL},
+   { N_("JobReport"),   "s"},
+   { N_("write"),       "s"},
+   { N_("VolumeName") , "s"},
+
+   { NULL,             NULL}
+};
+
+
+/* Return Job variables */
+/* Returns:  NULL if error
+ *           PyObject * return value if OK
+ */
+PyObject *job_getattr(PyObject *self, char *attrname)
+{
+   JCR *jcr;
+   bool found = false;
+   int i;
+   char buf[10];
+   char errmsg[200];
+
+   Dmsg0(100, "In job_getattr.\n");
+   jcr = get_jcr_from_PyObject(self);
+   if (!jcr) {
+      bstrncpy(errmsg, "Job pointer not found.", sizeof(errmsg));
+      goto bail_out;
+   }
+   for (i=0; getvars[i].name; i++) {
+      if (strcmp(getvars[i].name, attrname) == 0) {
+         found = true;
+         break;
+      }
+   }
+   if (!found) {
+      goto not_found;
+   }
+   switch (i) {
+   case 0:                            /* Job */
+      return Py_BuildValue(getvars[i].fmt, jcr->job->hdr.name);
+   case 1:                            /* Director's name */
+      return Py_BuildValue(getvars[i].fmt, my_name);
+   case 2:                            /* level */
+      return Py_BuildValue(getvars[i].fmt, job_level_to_str(jcr->JobLevel));
+   case 3:                            /* type */
+      return Py_BuildValue(getvars[i].fmt, job_type_to_str(jcr->JobType));
+   case 4:                            /* JobId */
+      return Py_BuildValue(getvars[i].fmt, jcr->JobId);
+   case 5:                            /* Client */
+      return Py_BuildValue(getvars[i].fmt, jcr->client->hdr.name);
+   case 6:                            /* NumVols */
+      return Py_BuildValue(getvars[i].fmt, jcr->NumVols);
+   case 7:                            /* Pool */
+      return Py_BuildValue(getvars[i].fmt, jcr->pool->hdr.name);
+   case 8:                            /* Storage */
+      return Py_BuildValue(getvars[i].fmt, jcr->store->hdr.name);
+   case 9:
+      return Py_BuildValue(getvars[i].fmt, jcr->catalog->hdr.name);
+   case 10:                           /* MediaType */
+      return Py_BuildValue(getvars[i].fmt, jcr->store->media_type);
+   case 11:                           /* JobName */
+      return Py_BuildValue(getvars[i].fmt, jcr->Job);
+   case 12:                           /* JobStatus */
+      buf[1] = 0;
+      buf[0] = jcr->JobStatus;
+      return Py_BuildValue(getvars[i].fmt, buf);
+   }
+not_found:
+   bsnprintf(errmsg, sizeof(errmsg), "Attribute %s not found.", attrname);
+bail_out:
+   PyErr_SetString(PyExc_AttributeError, errmsg);
+   return NULL;
+}
+
+
+/* Set Job variables */
+/*  Returns:   0 for OK
+ *            -1 for error
+ */
+int job_setattr(PyObject *self, char *attrname, PyObject *value)
+{
+   JCR *jcr;
+   bool found = false;
+   char *strval = NULL;
+   int i;
+
+   Dmsg2(100, "In job_setattr=%s val=%p.\n", attrname, value);
+   if (value == NULL) {                /* Cannot delete variables */
+       goto bail_out;
+   }
+   jcr = get_jcr_from_PyObject(self);
+   if (!jcr) {
+      goto bail_out;
+   }
+
+   /* Find attribute name in list */
+   for (i=0; setvars[i].name; i++) {
+      if (strcmp(setvars[i].name, attrname) == 0) {
+         found = true;
+         break;
+      }
+   }
+   if (!found) {
+      goto bail_out;
+   }
+   /* Get argument value ***FIXME*** handle other formats */
+   if (setvars[i].fmt != NULL) {
+      if (!PyArg_Parse(value, setvars[i].fmt, &strval)) {
+         PyErr_SetString(PyExc_TypeError, "Read-only attribute");
+         return -1;
+      }
+   }   
+   switch (i) {
+   case 0:                            /* set_events */
+      return set_job_events(self, value);
+   case 1:                            /* run */
+      return job_run(self, value);
+   case 2:                            /* JobReport */
+   case 3:                            /* write */
+      Jmsg(jcr, M_INFO, 0, "%s", strval);
+      return 0;
+   case 4:                            /* VolumeName */
+      /* Make sure VolumeName is valid and we are in VolumeName event */
+      if (strcmp("NewVolume", jcr->event) == 0 &&
+          is_volume_name_legal(NULL, strval)) {
+         pm_strcpy(jcr->VolumeName, strval);
+         Dmsg1(100, "Set Vol=%s\n", strval);
+         return 0;
+      } else {
+         jcr->VolumeName[0] = 0;
+      }
+   }
+bail_out:
+   PyErr_SetString(PyExc_AttributeError, attrname);
+   return -1;
+}
+
+
+static int set_job_events(PyObject *self, PyObject *arg)
+{
+   PyObject *eObject;
+   JCR *jcr;
+
+   Dmsg0(100, "In set_job_events.\n");
+   if (!PyArg_Parse(arg, "O", &eObject)) {
+      return -1;
+   }
+   jcr = get_jcr_from_PyObject(self);
+   Py_XDECREF((PyObject *)jcr->Python_events);
+   Py_INCREF(eObject);
+   jcr->Python_events = (void *)eObject;
+   return 0;                    /* good return */
+}
+
+/* Run a Bacula command */
+static int job_run(PyObject *self, PyObject *arg)
+{
+   JCR *jcr;
+   char *item;
+   int stat;
+
+   if (!PyArg_Parse(arg, "s", &item)) {
+      return -1;
+   }
+   jcr = get_jcr_from_PyObject(self);
+   UAContext *ua = new_ua_context(jcr);
+   ua->batch = true;
+   pm_strcpy(ua->cmd, item);          /* copy command */
+   parse_ua_args(ua);                 /* parse command */
+   stat = run_cmd(ua, ua->cmd);
+   free_ua_context(ua);
+   /* ***FIXME*** check stat */
+   return 0;
+}
+
+
+int generate_job_event(JCR *jcr, const char *event)
+{
+   PyObject *method = NULL;
+   PyObject *Job = (PyObject *)jcr->Python_job;
+   PyObject *result = NULL;
+   int stat = 0;
+
+   if (!Job) {
+      return 0;
+   }
+
+   PyEval_AcquireLock();
+
+   PyObject *events = (PyObject *)jcr->Python_events;
+   method = find_method(events, method, event);
+   if (!method) {
+      goto bail_out;
+   }
+
+   bstrncpy(jcr->event, event, sizeof(jcr->event));
+   result = PyObject_CallFunction(method, "O", Job);
+   jcr->event[0] = 0;             /* no event in progress */
+   if (result == NULL) {
+      if (PyErr_Occurred()) {
+         PyErr_Print();
+         Dmsg1(000, "Error in Python method %s\n", event);
+      }
+   } else {
+      stat = 1;
+   }
+   Py_XDECREF(result);
+
+bail_out:
+   PyEval_ReleaseLock();
+   return stat;
+}
+
+bool python_set_prog(JCR*, char const*) { return false; }
+
+#else
+
+/* Dummy if Python not configured */
+int generate_job_event(JCR *jcr, const char *event) { return 1; }
+   
+
+#endif /* HAVE_PYTHON */
index 859b7e39ab235117f32b49c65a16330d4b790d31..9cfbaf286c0a566bccff54a02aaf55d941397c04 100755 (executable)
@@ -30,10 +30,10 @@ dummy:
 
 #
 SVRSRCS = filed.c authenticate.c acl.c backup.c chksum.c estimate.c \
-         filed_conf.c heartbeat.c job.c python.c \
+         filed_conf.c heartbeat.c job.c pythonfd.c \
          restore.c status.c verify.c verify_vol.c
 SVROBJS = filed.o authenticate.o acl.o backup.o chksum.o estimate.o \
-         filed_conf.o heartbeat.o job.o python.o \
+         filed_conf.o heartbeat.o job.o pythonfd.o \
          restore.o status.o verify.o verify_vol.o
 
 # these are the objects that are changed by the .configure process
index 4ef2a0b6577b827e2b643a7564351c78c09b1b5f..688a3e4ce568d1ad8b5b33c9a05f995f3cace6db 100644 (file)
@@ -181,12 +181,10 @@ int main (int argc, char *argv[])
 
    parse_config(configfile);
 
-#ifdef HAVE_TLS
    if (init_tls() != 0) {
       Emsg0(M_ERROR, 0, _("TLS library initialization failed.\n"));
       terminate_filed(1);
    }
-#endif
 
    if (!check_resources()) {
       Emsg1(M_ERROR, 0, _("Please correct configuration file: %s\n"), configfile);
diff --git a/bacula/src/filed/python.c b/bacula/src/filed/python.c
deleted file mode 100644 (file)
index 7ccbd16..0000000
+++ /dev/null
@@ -1,278 +0,0 @@
-/*
- *
- * Bacula interface to Python for the File Daemon
- *
- * Kern Sibbald, March MMV
- *
- *   Version $Id$
- *
- */
-
-/*
-   Copyright (C) 2005 Kern Sibbald
-
-   This program is free software; you can redistribute it and/or
-   modify it under the terms of the GNU General Public License as
-   published by the Free Software Foundation; either version 2 of
-   the License, or (at your option) any later version.
-
-   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 GNU
-   General Public License for more details.
-
-   You should have received a copy of the GNU General Public
-   License along with this program; if not, write to the Free
-   Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
-   MA 02111-1307, USA.
-
- */
-
-#include "bacula.h"
-#include "filed.h"
-
-#ifdef HAVE_PYTHON
-#undef _POSIX_C_SOURCE
-#include <Python.h>
-
-/* External function pointers to be set */
-extern bool    (*python_set_prog)(JCR *jcr, const char *prog);
-extern int     (*python_open)(BFILE *bfd, const char *fname, int flags, mode_t mode);
-extern int     (*python_close)(BFILE *bfd);
-extern ssize_t (*python_read)(BFILE *bfd, void *buf, size_t count);
-
-
-extern JCR *get_jcr_from_PyObject(PyObject *self);
-extern PyObject *find_method(PyObject *eventsObject, PyObject *method, 
-          const char *name);
-
-/* Forward referenced functions */
-static PyObject *job_get(PyObject *self, PyObject *args);
-static PyObject *job_write(PyObject *self, PyObject *args);
-static PyObject *job_set(PyObject *self, PyObject *args, PyObject *keyw);
-static PyObject *set_job_events(PyObject *self, PyObject *args);
-
-bool my_python_set_prog(JCR *jcr, const char *prog);
-int my_python_open(BFILE *bfd, const char *fname, int flags, mode_t mode);
-int my_python_close(BFILE *bfd);
-ssize_t my_python_read(BFILE *bfd, void *buf, size_t count);
-
-
-/* Define Job entry points */
-PyMethodDef JobMethods[] = {
-    {"get", job_get, METH_VARARGS, "Get Job variables."},
-    {"set", (PyCFunction)job_set, METH_VARARGS|METH_KEYWORDS,
-        "Set Job variables."},
-    {"set_events", set_job_events, METH_VARARGS, "Define Job events."},
-    {"write", job_write, METH_VARARGS, "Write output."},
-    {NULL, NULL, 0, NULL}             /* last item */
-};
-
-struct s_vars {
-   const char *name;
-   char *fmt;
-};
-
-/* Read-only variables */
-static struct s_vars vars[] = {
-   { N_("FDName"),     "s"},          /* 0 */
-   { N_("Level"),      "s"},          /* 1 */
-   { N_("Type"),       "s"},          /* 2 */
-   { N_("JobId"),      "i"},          /* 3 */
-   { N_("Client"),     "s"},          /* 4 */
-   { N_("JobName"),    "s"},          /* 5 */
-   { N_("JobStatus"),  "s"},          /* 6 */
-
-   { NULL,             NULL}
-};
-
-/* Return Job variables */
-PyObject *job_get(PyObject *self, PyObject *args)
-{
-   JCR *jcr;
-   char *item;
-   bool found = false;
-   int i;
-   char buf[10];
-
-   if (!PyArg_ParseTuple(args, "s:get", &item)) {
-      return NULL;
-   }
-   jcr = get_jcr_from_PyObject(self);
-   for (i=0; vars[i].name; i++) {
-      if (strcmp(vars[i].name, item) == 0) {
-         found = true;
-         break;
-      }
-   }
-   if (!found) {
-      return NULL;
-   }
-   switch (i) {
-   case 0:                            /* FD's name */
-      return Py_BuildValue(vars[i].fmt, my_name);
-   case 1:                            /* level */
-      return Py_BuildValue(vars[i].fmt, job_level_to_str(jcr->JobLevel));
-   case 2:                            /* type */
-      return Py_BuildValue(vars[i].fmt, job_type_to_str(jcr->JobType));
-   case 3:                            /* JobId */
-      return Py_BuildValue(vars[i].fmt, jcr->JobId);
-   case 4:                            /* Client */
-      return Py_BuildValue(vars[i].fmt, jcr->client_name);
-   case 5:                            /* JobName */
-      return Py_BuildValue(vars[i].fmt, jcr->Job);
-   case 6:                            /* JobStatus */
-      buf[1] = 0;
-      buf[0] = jcr->JobStatus;
-      return Py_BuildValue(vars[i].fmt, buf);
-   }
-   return NULL;
-}
-
-/* Set Job variables */
-PyObject *job_set(PyObject *self, PyObject *args, PyObject *keyw)
-{
-   JCR *jcr;
-   char *msg = NULL;
-   static char *kwlist[] = {"JobReport", NULL};
-   
-   if (!PyArg_ParseTupleAndKeywords(args, keyw, "|s:set", kwlist,
-        &msg)) {
-      return NULL;
-   }
-   jcr = get_jcr_from_PyObject(self);
-   
-   if (msg) {
-      Jmsg(jcr, M_INFO, 0, "%s", msg);
-   }
-   return Py_BuildValue("i", 1);
-}
-
-
-static PyObject *set_job_events(PyObject *self, PyObject *args)
-{
-   PyObject *eObject;
-   JCR *jcr;
-
-   Dmsg0(100, "In set_job_events.\n");
-
-   if (!PyArg_ParseTuple(args, "O:set_events", &eObject)) {
-      return NULL;
-   }
-   jcr = get_jcr_from_PyObject(self);
-   Py_XDECREF((PyObject *)jcr->Python_events);
-   Py_INCREF(eObject);
-   jcr->Python_events = (void *)eObject;
-
-   /* Set function pointers to call here */
-   python_set_prog = my_python_set_prog;
-   python_open     = my_python_open;
-   python_close    = my_python_close;
-   python_read     = my_python_read;
-
-   Py_INCREF(Py_None);
-   return Py_None;
-}
-
-/* Write text to job output */
-static PyObject *job_write(PyObject *self, PyObject *args)
-{
-   char *text = NULL;
-
-   if (!PyArg_ParseTuple(args, "s:write", &text)) {
-      return NULL;
-   }
-   if (text) {
-      JCR *jcr = get_jcr_from_PyObject(self);
-      Jmsg(jcr, M_INFO, 0, "%s", text);
-   }
-        
-   Py_INCREF(Py_None);
-   return Py_None;
-}
-
-int generate_job_event(JCR *jcr, const char *event)
-{
-   PyObject *method = NULL;
-   PyObject *Job = (PyObject *)jcr->Python_job;
-   PyObject *result = NULL;
-   int stat = 0;
-
-   if (!Job) {
-      return 0;
-   }
-
-   PyEval_AcquireLock();
-
-   PyObject *events = (PyObject *)jcr->Python_events;
-   method = find_method(events, method, event);
-   if (!method) {
-      goto bail_out;
-   }
-
-   bstrncpy(jcr->event, event, sizeof(jcr->event));
-   result = PyObject_CallFunction(method, "O", Job);
-   jcr->event[0] = 0;             /* no event in progress */
-   if (result == NULL) {
-      if (PyErr_Occurred()) {
-         PyErr_Print();
-         Dmsg1(000, "Error in Python method %s\n", event);
-      }
-   } else {
-      stat = 1;
-   }
-   Py_XDECREF(result);
-
-bail_out:
-   PyEval_ReleaseLock();
-   return stat;
-}
-
-
-bool my_python_set_prog(JCR *jcr, const char *prog)
-{
-   PyObject *events = (PyObject *)jcr->Python_events;
-   BFILE *bfd = &jcr->ff->bfd;
-   char method[MAX_NAME_LENGTH];
-
-   if (!events) {
-      return false;
-   }
-   bstrncpy(method, prog, sizeof(method));
-   bstrncat(method, "_", sizeof(method));
-   bstrncat(method, "open", sizeof(method));
-   bfd->pio.fo = find_method(events, bfd->pio.fo, method);
-   bstrncpy(method, prog, sizeof(method));
-   bstrncat(method, "_", sizeof(method));
-   bstrncat(method, "read", sizeof(method));
-   bfd->pio.fr = find_method(events, bfd->pio.fr, method);
-   bstrncpy(method, prog, sizeof(method));
-   bstrncat(method, "_", sizeof(method));
-   bstrncat(method, "close", sizeof(method));
-   bfd->pio.fc = find_method(events, bfd->pio.fc, method);
-   return bfd->pio.fo && bfd->pio.fr && bfd->pio.fc;
-}
-
-int my_python_open(BFILE *bfd, const char *fname, int flags, mode_t mode)
-{
-   return -1;
-}
-
-int my_python_close(BFILE *bfd) 
-{
-   return 0;
-}
-
-ssize_t my_python_read(BFILE *bfd, void *buf, size_t count)
-{
-   return -1;
-}
-
-#else
-
-/* Dummy if Python not configured */
-int generate_job_event(JCR *jcr, const char *event)
-{ return 1; }
-
-
-#endif /* HAVE_PYTHON */
diff --git a/bacula/src/filed/pythonfd.c b/bacula/src/filed/pythonfd.c
new file mode 100644 (file)
index 0000000..acb7090
--- /dev/null
@@ -0,0 +1,303 @@
+/*
+ *
+ * Bacula interface to Python for the File Daemon
+ *
+ * Kern Sibbald, March MMV
+ *
+ *   Version $Id$
+ *
+ */
+
+/*
+   Copyright (C) 2005 Kern Sibbald
+
+   This program is free software; you can redistribute it and/or
+   modify it under the terms of the GNU General Public License as
+   published by the Free Software Foundation; either version 2 of
+   the License, or (at your option) any later version.
+
+   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 GNU
+   General Public License for more details.
+
+   You should have received a copy of the GNU General Public
+   License along with this program; if not, write to the Free
+   Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
+   MA 02111-1307, USA.
+
+ */
+
+#include "bacula.h"
+#include "filed.h"
+
+#ifdef HAVE_PYTHON
+#undef _POSIX_C_SOURCE
+#include <Python.h>
+
+/* External function pointers to be set */
+extern bool    (*python_set_prog)(JCR *jcr, const char *prog);
+extern int     (*python_open)(BFILE *bfd, const char *fname, int flags, mode_t mode);
+extern int     (*python_close)(BFILE *bfd);
+extern ssize_t (*python_read)(BFILE *bfd, void *buf, size_t count);
+
+
+extern JCR *get_jcr_from_PyObject(PyObject *self);
+extern PyObject *find_method(PyObject *eventsObject, PyObject *method, 
+          const char *name);
+
+/* Forward referenced functions */
+static int set_job_events(PyObject *self, PyObject *arg);
+
+bool my_python_set_prog(JCR *jcr, const char *prog);
+int my_python_open(BFILE *bfd, const char *fname, int flags, mode_t mode);
+int my_python_close(BFILE *bfd);
+ssize_t my_python_read(BFILE *bfd, void *buf, size_t count);
+
+
+struct s_vars {
+   const char *name;
+   char *fmt;
+};
+
+/* Read-only variables */
+static struct s_vars getvars[] = {
+   { N_("FDName"),     "s"},          /* 0 */
+   { N_("Level"),      "s"},          /* 1 */
+   { N_("Type"),       "s"},          /* 2 */
+   { N_("JobId"),      "i"},          /* 3 */
+   { N_("Client"),     "s"},          /* 4 */
+   { N_("JobName"),    "s"},          /* 5 */
+   { N_("JobStatus"),  "s"},          /* 6 */
+
+   { NULL,             NULL}
+};
+
+/* Writable variables */
+static struct s_vars setvars[] = {
+   { N_("set_events"), NULL},
+   { N_("JobReport"),   "s"},
+   { N_("write"),       "s"},
+
+   { NULL,             NULL}
+};
+
+/* Return Job variables */
+PyObject *job_getattr(PyObject *self, char *attrname)
+{
+   JCR *jcr;
+   bool found = false;
+   int i;
+   char buf[10];
+   char errmsg[200];
+
+   jcr = get_jcr_from_PyObject(self);
+   if (!jcr) {
+      bstrncpy(errmsg, "Job pointer not found.", sizeof(errmsg));
+      goto bail_out;
+   }
+   for (i=0; getvars[i].name; i++) {
+      if (strcmp(getvars[i].name, attrname) == 0) {
+         found = true;
+         break;
+      }
+   }
+   if (!found) {
+      goto not_found;
+   }
+   switch (i) {
+   case 0:                            /* FD's name */
+      return Py_BuildValue(getvars[i].fmt, my_name);
+   case 1:                            /* level */
+      return Py_BuildValue(getvars[i].fmt, job_level_to_str(jcr->JobLevel));
+   case 2:                            /* type */
+      return Py_BuildValue(getvars[i].fmt, job_type_to_str(jcr->JobType));
+   case 3:                            /* JobId */
+      return Py_BuildValue(getvars[i].fmt, jcr->JobId);
+   case 4:                            /* Client */
+      return Py_BuildValue(getvars[i].fmt, jcr->client_name);
+   case 5:                            /* JobName */
+      return Py_BuildValue(getvars[i].fmt, jcr->Job);
+   case 6:                            /* JobStatus */
+      buf[1] = 0;
+      buf[0] = jcr->JobStatus;
+      return Py_BuildValue(getvars[i].fmt, buf);
+   }
+not_found:
+   bsnprintf(errmsg, sizeof(errmsg), "Attribute %s not found.", attrname);
+bail_out:
+   PyErr_SetString(PyExc_AttributeError, errmsg);
+   return NULL;
+}
+
+int job_setattr(PyObject *self, char *attrname, PyObject *value)
+{
+  JCR *jcr;
+   bool found = false;
+   char *strval = NULL;
+   char buf[200];
+   char *errmsg;
+   int i;
+
+   Dmsg2(100, "In job_setattr=%s val=%p.\n", attrname, value);
+   if (value == NULL) {                /* Cannot delete variables */
+      bsnprintf(buf, sizeof(buf), "Cannot delete attribute %s", attrname);
+      errmsg = buf;
+      goto bail_out;
+   }
+   jcr = get_jcr_from_PyObject(self);
+   if (!jcr) {
+      errmsg = "Job pointer not found.";
+      goto bail_out;
+   }
+
+   /* Find attribute name in list */
+   for (i=0; setvars[i].name; i++) {
+      if (strcmp(setvars[i].name, attrname) == 0) {
+         found = true;
+         break;
+      }
+   }
+   if (!found) {
+      bsnprintf(buf, sizeof(buf), "Cannot find attribute %s", attrname);
+      errmsg = buf;
+      goto bail_out;
+   }
+   /* Get argument value ***FIXME*** handle other formats */
+   if (setvars[i].fmt != NULL) {
+      if (!PyArg_Parse(value, setvars[i].fmt, &strval)) {
+         PyErr_SetString(PyExc_TypeError, "Read-only attribute");
+         return -1;
+      }
+   }   
+   switch (i) {
+   case 0:                            /* set_events */
+      return set_job_events(self, value);
+   case 1:                            /* JobReport */
+   case 2:                            /* write */
+      Jmsg(jcr, M_INFO, 0, "%s", strval);
+      return 0;
+   }
+   bsnprintf(buf, sizeof(buf), "Cannot find attribute %s", attrname);
+   errmsg = buf;
+bail_out:
+   PyErr_SetString(PyExc_AttributeError, errmsg);
+   return -1;
+}
+
+
+
+static int set_job_events(PyObject *self, PyObject *arg)
+{
+   PyObject *eObject;
+   JCR *jcr;
+
+   Dmsg0(100, "In set_job_events.\n");
+   if (!PyArg_Parse(arg, "O", &eObject)) {
+      Dmsg0(000, "Parse error looking for Object argument\n");
+      return -1;
+   }
+   jcr = get_jcr_from_PyObject(self);
+   if (!jcr) {
+      PyErr_SetString(PyExc_AttributeError, "Job pointer not found.");
+      return -1;
+   }
+   Py_XDECREF((PyObject *)jcr->Python_events);  /* release any old events Object */
+   Py_INCREF(eObject);
+   jcr->Python_events = (void *)eObject;        /* set new events */
+
+   /* Set function pointers to call here */
+   python_set_prog = my_python_set_prog;
+   python_open     = my_python_open;
+   python_close    = my_python_close;
+   python_read     = my_python_read;
+
+   return 0;
+}
+
+
+int generate_job_event(JCR *jcr, const char *event)
+{
+   PyObject *method = NULL;
+   PyObject *Job = (PyObject *)jcr->Python_job;
+   PyObject *result = NULL;
+   int stat = 0;
+
+   if (!Job) {
+      return 0;
+   }
+
+   PyEval_AcquireLock();
+
+   PyObject *events = (PyObject *)jcr->Python_events;
+   method = find_method(events, method, event);
+   if (!method) {
+      goto bail_out;
+   }
+
+   bstrncpy(jcr->event, event, sizeof(jcr->event));
+   result = PyObject_CallFunction(method, "O", Job);
+   jcr->event[0] = 0;             /* no event in progress */
+   if (result == NULL) {
+      if (PyErr_Occurred()) {
+         PyErr_Print();
+         Dmsg1(000, "Error in Python method %s\n", event);
+      }
+   } else {
+      stat = 1;
+   }
+   Py_XDECREF(result);
+
+bail_out:
+   PyEval_ReleaseLock();
+   return stat;
+}
+
+
+bool my_python_set_prog(JCR *jcr, const char *prog)
+{
+   PyObject *events = (PyObject *)jcr->Python_events;
+   BFILE *bfd = &jcr->ff->bfd;
+   char method[MAX_NAME_LENGTH];
+
+   if (!events) {
+      return false;
+   }
+   bstrncpy(method, prog, sizeof(method));
+   bstrncat(method, "_", sizeof(method));
+   bstrncat(method, "open", sizeof(method));
+   bfd->pio.fo = find_method(events, bfd->pio.fo, method);
+   bstrncpy(method, prog, sizeof(method));
+   bstrncat(method, "_", sizeof(method));
+   bstrncat(method, "read", sizeof(method));
+   bfd->pio.fr = find_method(events, bfd->pio.fr, method);
+   bstrncpy(method, prog, sizeof(method));
+   bstrncat(method, "_", sizeof(method));
+   bstrncat(method, "close", sizeof(method));
+   bfd->pio.fc = find_method(events, bfd->pio.fc, method);
+   return bfd->pio.fo && bfd->pio.fr && bfd->pio.fc;
+}
+
+int my_python_open(BFILE *bfd, const char *fname, int flags, mode_t mode)
+{
+   return -1;
+}
+
+int my_python_close(BFILE *bfd) 
+{
+   return 0;
+}
+
+ssize_t my_python_read(BFILE *bfd, void *buf, size_t count)
+{
+   return -1;
+}
+
+#else
+
+/* Dummy if Python not configured */
+int generate_job_event(JCR *jcr, const char *event)
+{ return 1; }
+
+
+#endif /* HAVE_PYTHON */
index b507960a7e4c05ea7d1b6651f6362465b625aa20..378c85036af27fc42c323f93d0d5fdf9c1704e56 100644 (file)
@@ -37,7 +37,9 @@
 #include <Python.h>
 
 /* Imported subroutines */
-extern PyMethodDef JobMethods[];
+//extern PyMethodDef JobMethods[];
+extern PyObject *job_getattr(PyObject *self, char *attrname);
+extern int job_setattr(PyObject *self, char *attrname, PyObject *value);
 
 static PyObject *bacula_module = NULL;    /* We create this */
 static PyObject *StartUp_module = NULL;   /* We import this */
@@ -72,49 +74,15 @@ typedef struct s_JobObject {
 
 static PyTypeObject JobType = {
     PyObject_HEAD_INIT(NULL)
-    0,                         /*ob_size*/
-    "bacula.jcr",              /*tp_name*/
-    sizeof(JobObject),         /*tp_basicsize*/
-    0,                         /*tp_itemsize*/
-    0,                         /*tp_dealloc*/
-    0,                         /*tp_print*/
-    0,                         /*tp_getattr*/
-    0,                         /*tp_setattr*/
-    0,                         /*tp_compare*/
-    0,                         /*tp_repr*/
-    0,                         /*tp_as_number*/
-    0,                         /*tp_as_sequence*/
-    0,                         /*tp_as_mapping*/
-    0,                         /*tp_hash */
-    0,                         /*tp_call*/
-    0,                         /*tp_str*/
-    0,                         /*tp_getattro*/
-    0,                         /*tp_setattro*/
-    0,                         /*tp_as_buffer*/
-    Py_TPFLAGS_DEFAULT, /*tp_flags*/
-    "Job objects",             /* tp_doc */
-    0,                         /* tp_traverse */
-    0,                         /* tp_clear */
-    0,                         /* tp_richcompare */
-    0,                         /* tp_weaklistoffset */
-    0,                         /* tp_iter */
-    0,                         /* tp_iternext */
-    JobMethods,                /* tp_methods */
-    0,                         /* tp_members */
-    0,                         /* tp_getset */
-    0,                         /* tp_base */
-    0,                         /* tp_dict */
-    0,                         /* tp_descr_get */
-    0,                         /* tp_descr_set */
-    0,                         /* tp_dictoffset */
-    0,                         /* tp_init */
-    0,                         /* tp_alloc */
-    0,                         /* tp_new */
+    /* Other items filled in in code below */
 };
 
 /* Return the JCR pointer from the JobObject */
 JCR *get_jcr_from_PyObject(PyObject *self)
 {
+   if (!self) {
+      return NULL;
+   }
    return ((JobObject *)self)->jcr;
 }
 
@@ -135,6 +103,7 @@ void init_python_interpreter(const char *progname, const char *scripts,
    Py_Initialize();
    PyEval_InitThreads();
    bacula_module = Py_InitModule("bacula", BaculaMethods);
+   PyModule_AddStringConstant(bacula_module, "name", my_name);
    if (!bacula_module) {
       Jmsg0(NULL, M_ERROR_TERM, 0, "Could not initialize Python\n");
    }
@@ -143,7 +112,15 @@ void init_python_interpreter(const char *progname, const char *scripts,
    if (PyRun_SimpleString(buf) != 0) {
       Jmsg1(NULL, M_ERROR_TERM, 0, "Could not Run Python string %s\n", buf);
    }   
-   JobType.tp_methods = JobMethods;
+
+   /* Explicitly set values we want */
+   JobType.tp_name = "Bacula.Job";
+   JobType.tp_basicsize = sizeof(JobObject);
+   JobType.tp_flags = Py_TPFLAGS_DEFAULT;
+   JobType.tp_doc = "Bacula Job object";
+   JobType.tp_getattr = job_getattr;
+   JobType.tp_setattr = job_setattr;
+   
    if (PyType_Ready(&JobType) != 0) {
       Jmsg0(NULL, M_ERROR_TERM, 0, "Could not initialize Python Job type.\n");
       PyErr_Print();
@@ -273,19 +250,20 @@ int generate_daemon_event(JCR *jcr, const char *event)
 
    } else if (strcmp(event, "JobEnd") == 0) {
       if (!JobEnd_method || !jcr->Python_job) {
-         Dmsg0(100, "No JobEnd method\n");
+         Dmsg2(000, "No JobEnd method=%p Job=%p\n", JobEnd_method, jcr->Python_job);
          stat = 0;
          goto bail_out;
       }
       bstrncpy(jcr->event, event, sizeof(jcr->event));
-      Dmsg1(100, "Call event=%s\n", event);
+      Dmsg1(100, "Call daemon event=%s\n", event);
       result = PyObject_CallFunction(JobEnd_method, "O", jcr->Python_job);
       jcr->event[0] = 0;             /* no event in progress */
       if (result == NULL) {
-         JobEnd_method = NULL;
          if (PyErr_Occurred()) {
             PyErr_Print();
-            Dmsg1(000, "Python JobEnd error. JobId=%d\n", jcr->JobId);
+            Dmsg2(000, "Python JobEnd error. job=%p JobId=%d\n", jcr->Python_job,
+              jcr->JobId);
+           JobEnd_method = NULL;
          }
          Jmsg(jcr, M_ERROR, 0, "Python function \"%s\" not found.\n", event);
          goto bail_out;
@@ -296,13 +274,13 @@ int generate_daemon_event(JCR *jcr, const char *event)
          stat = 0;
          goto bail_out;
       }
-      result = PyObject_CallFunction(JobEnd_method, NULL);
+      result = PyObject_CallFunction(Exit_method, NULL);
       if (result == NULL) {
          goto bail_out;
       }
       stat = 1;                    /* OK */
    } else {
-      Emsg1(M_ABORT, 0, "Unknown Python daemon event %s\n", event);
+      Jmsg1(jcr, M_ABORT, 0, "Unknown Python daemon event %s\n", event);
    }
 
 bail_out:
@@ -317,74 +295,6 @@ jobstart_ok:
    return stat; 
 }
 
-#ifdef xxx
-   PyObject *pName, *pModule, *pDict, *pFunc;
-   PyObject *pArgs, *pJCR, *pCall;
-   
-   Dmsg1(100, "Generate event %s\n", event);
-   pName = PyString_FromString(event);
-   if (!pName) {
-      Jmsg(jcr, M_ERROR, 0, "Could not convert \"%s\" to Python string.\n", event);
-      return -1;                      /* Could not convert string */
-   }
-
-   pModule = PyImport_Import(pName);
-   Py_DECREF(pName);                  /* release pName */
-
-   if (pModule != NULL) {
-      pDict = PyModule_GetDict(pModule);
-      /* pDict is a borrowed reference */
-
-      pFunc = PyDict_GetItemString(pDict, (char *)event);
-      /* pFun: Borrowed reference */
-
-      if (pFunc && PyCallable_Check(pFunc)) {
-          /* Create JCR argument to send to function */
-          pArgs = PyTuple_New(1);
-          pJCR = (PyObject *)PyObject_New(JCRObject, &JCRType);
-          ((JCRObject *)pJCR)->jcr = jcr;
-          if (!pJCR) {
-             Py_DECREF(pArgs);
-             Py_DECREF(pModule);
-             Jmsg0(jcr, M_ERROR, 0, "Could not create JCR Python Object.\n");
-             return -1;
-          }
-          Py_INCREF(pJCR);
-          /* pJCR reference stolen here: */
-          PyTuple_SetItem(pArgs, 0, pJCR);
-
-          /* Finally, we call the module here */
-          bstrncpy(jcr->event, event, sizeof(jcr->event));
-          pCall = PyObject_CallObject(pFunc, pArgs);
-          jcr->event[0] = 0;             /* no event in progress */
-          Py_DECREF(pArgs);
-          Py_DECREF(pJCR);
-          if (pCall != NULL) {
-             Py_DECREF(pCall);
-          } else {
-             Py_DECREF(pModule);
-             PyErr_Print();
-             Jmsg1(jcr, M_ERROR, 0, "Error running Python module: %s\n", event);
-             return 0;                /* error running function */
-          }
-          /* pDict and pFunc are borrowed and must not be Py_DECREF-ed */
-      } else {
-         if (PyErr_Occurred()) {
-            PyErr_Print();
-            Dmsg1(000, "Python event %s function not callable.\n", event);
-         }
-         Jmsg1(jcr, M_ERROR, 0, "Python function \"%s\" not found in module.\n", event);
-         return -1;                   /* function not found */
-      }
-      Py_DECREF(pModule);
-   } else {
-      return 0;                       /* Module not present */
-   }
-   Dmsg0(100, "Generate event OK\n");
-   return 1;
-}
-#endif
-
 #else
 
 /*
index 3899ecffd95b0a7d21395f728b54229db0fc503d..777f287c152fc23695904041b87a83df7facc445 100644 (file)
@@ -27,7 +27,7 @@ SVRSRCS = stored.c ansi_label.c \
          block.c butil.c dev.c \
          device.c dircmd.c dvd.c ebcdic.c fd_cmds.c job.c \
          label.c match_bsr.c mount.c parse_bsr.c \
-         python.c \
+         pythonsd.c \
          read.c read_record.c record.c \
          spool.c status.c stored_conf.c wait.c
 SVROBJS = stored.o ansi_label.o \
@@ -36,7 +36,7 @@ SVROBJS = stored.o ansi_label.o \
          block.o butil.o dev.o \
          device.o dircmd.o dvd.o ebcdic.c fd_cmds.o job.o \
          label.o match_bsr.o mount.o parse_bsr.o \
-         python.o \
+         pythonsd.o \
          read.o read_record.o record.o \
          spool.o status.o stored_conf.o wait.o
 
@@ -60,7 +60,7 @@ BLSOBJS = bls.o block.o butil.o device.o dev.o label.o match_bsr.o \
 BEXTOBJS = bextract.o block.o device.o dev.o label.o record.o \
           ansi_label.o dvd.o ebcdic.o \
           autochanger.o acquire.o mount.o match_bsr.o parse_bsr.o butil.o \
-          python.o \
+          pythonsd.o \
           read_record.o stored_conf.o spool.o wait.o
 
 # bscan
index 5884e57559ac94d2b5031c08ce998a703fc98ba2..02c2fc91690c66e4cc9f55c620ee8d8db84caa60 100644 (file)
@@ -219,6 +219,7 @@ void *handle_connection_request(void *arg)
       }
    }
 bail_out:
+   generate_daemon_event(jcr, "JobEnd");
    dequeue_messages(jcr);             /* send any queued messages */
    bnet_sig(bs, BNET_TERMINATE);
    free_jcr(jcr);
index 2e161f3406f7728abf68949dda5585f18630afde..6bde98a8a702337ccf7e4fd65d5c52286ba111f4 100644 (file)
@@ -139,6 +139,7 @@ bool job_cmd(JCR *jcr)
    Dmsg1(100, ">dird: %s", dir->msg);
    jcr->sd_auth_key = bstrdup(auth_key);
    memset(auth_key, 0, sizeof(auth_key));
+   generate_daemon_event(jcr, "JobStart");
    return true;
 }
 
diff --git a/bacula/src/stored/python.c b/bacula/src/stored/python.c
deleted file mode 100644 (file)
index aa9e7e8..0000000
+++ /dev/null
@@ -1,208 +0,0 @@
-/*
- *
- * Bacula interface to Python for the Storage Daemon
- *
- * Kern Sibbald, January MMV
- *
- *   Version $Id$
- *
- */
-
-/*
-   Copyright (C) 2005 Kern Sibbald
-
-   This program is free software; you can redistribute it and/or
-   modify it under the terms of the GNU General Public License as
-   published by the Free Software Foundation; either version 2 of
-   the License, or (at your option) any later version.
-
-   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 GNU
-   General Public License for more details.
-
-   You should have received a copy of the GNU General Public
-   License along with this program; if not, write to the Free
-   Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
-   MA 02111-1307, USA.
-
- */
-
-#include "bacula.h"
-#include "stored.h"
-
-#ifdef HAVE_PYTHON
-#undef _POSIX_C_SOURCE
-#include <Python.h>
-
-extern JCR *get_jcr_from_PyObject(PyObject *self);
-extern PyObject *find_method(PyObject *eventsObject, PyObject *method, 
-         const char *name);
-
-static PyObject *jcr_get(PyObject *self, PyObject *args);
-static PyObject *jcr_write(PyObject *self, PyObject *args);
-static PyObject *jcr_set(PyObject *self, PyObject *args, PyObject *keyw);
-static PyObject *set_jcr_events(PyObject *self, PyObject *args);
-
-
-/* Define Job entry points */
-PyMethodDef JobMethods[] = {
-    {"get", jcr_get, METH_VARARGS, "Get Job variables."},
-    {"set", (PyCFunction)jcr_set, METH_VARARGS|METH_KEYWORDS,
-        "Set Job variables."},
-    {"set_events", set_jcr_events, METH_VARARGS, "Define Job events."},
-    {"write", jcr_write, METH_VARARGS, "Write output."},
-    {NULL, NULL, 0, NULL}             /* last item */
-};
-
-
-struct s_vars {
-   const char *name;
-   char *fmt;
-};
-
-static struct s_vars vars[] = {
-   { N_("Job"),        "s"},          /* 0 */
-   { N_("SDName"),     "s"},          /* 1 */
-   { N_("Level"),      "s"},          /* 2 */
-   { N_("Type"),       "s"},          /* 3 */
-   { N_("JobId"),      "i"},          /* 4 */
-   { N_("Client"),     "s"},          /* 5 */
-   { N_("Pool"),       "s"},          /* 6 */
-   { N_("MediaType"),  "s"},          /* 7 */
-   { N_("JobName"),    "s"},          /* 8 */
-   { N_("JobStatus"),  "s"},          /* 9 */
-   { N_("VolumeName"), "s"},          /* 10 */
-   { N_("Device"),     "s"},          /* 11 */
-
-   { NULL,             NULL}
-};
-
-/* Return Job variables */
-PyObject *jcr_get(PyObject *self, PyObject *args)
-{
-   JCR *jcr;
-   char *item;
-   bool found = false;
-   int i;
-   char buf[10];
-   
-   if (!PyArg_ParseTuple(args, "s:get", &item)) {
-      return NULL;
-   }
-   jcr = get_jcr_from_PyObject(self);
-
-   for (i=0; vars[i].name; i++) {
-      if (strcmp(vars[i].name, item) == 0) {
-         found = true;
-         break;
-      }
-   }
-   if (!found) {
-      return NULL;
-   }
-   switch (i) {
-   case 0:                            /* Job */
-      return Py_BuildValue(vars[i].fmt, jcr->job_name);    /* Non-unique name */
-   case 1:                            /* SD's name */
-      return Py_BuildValue(vars[i].fmt, my_name);
-   case 2:                            /* level */
-      return Py_BuildValue(vars[i].fmt, job_level_to_str(jcr->JobLevel));
-   case 3:                            /* type */
-      return Py_BuildValue(vars[i].fmt, job_type_to_str(jcr->JobType));
-   case 4:                            /* JobId */
-      return Py_BuildValue(vars[i].fmt, jcr->JobId);
-   case 5:                            /* Client */
-      return Py_BuildValue(vars[i].fmt, jcr->client_name);
-   case 6:                            /* Pool */
-      return Py_BuildValue(vars[i].fmt, jcr->dcr->pool_name);
-   case 7:                            /* MediaType */
-      return Py_BuildValue(vars[i].fmt, jcr->dcr->media_type);
-   case 8:                            /* JobName */
-      return Py_BuildValue(vars[i].fmt, jcr->Job);
-   case 9:                            /* JobStatus */
-      buf[1] = 0;
-      buf[0] = jcr->JobStatus;
-      return Py_BuildValue(vars[i].fmt, buf);
-   case 10:
-      return Py_BuildValue(vars[i].fmt, jcr->dcr->VolumeName);
-   case 11:
-      return Py_BuildValue(vars[i].fmt, jcr->dcr->dev_name);
-   }
-   return NULL;
-}
-
-/* Set Job variables */
-PyObject *jcr_set(PyObject *self, PyObject *args, PyObject *keyw)
-{
-   JCR *jcr;
-   char *msg = NULL;
-   static char *kwlist[] = {"JobReport", NULL};
-   
-   if (!PyArg_ParseTupleAndKeywords(args, keyw, "|s:set", kwlist,
-        &msg)) {
-      return NULL;
-   }
-   jcr = get_jcr_from_PyObject(self);
-
-   if (msg) {
-      Jmsg(jcr, M_INFO, 0, "%s", msg);
-   }
-   return Py_BuildValue("i", 1);
-}
-
-static PyObject *set_jcr_events(PyObject *self, PyObject *args)
-{
-   PyObject *eObject;
-   JCR *jcr;
-   if (!PyArg_ParseTuple(args, "O:set_events_hook", &eObject)) {
-      return NULL;
-   }
-   Py_XINCREF(eObject);
-   jcr = get_jcr_from_PyObject(self);
-// jcr->ff->bfd.pio.fc = find_method(eObject, close_method, "close");
-   Py_INCREF(Py_None);
-   return Py_None;
-}
-
-/* Write text to job output */
-static PyObject *jcr_write(PyObject *self, PyObject *args)
-{
-   char *text;
-   if (!PyArg_ParseTuple(args, "s:write", &text)) {
-      return NULL;
-   }
-   if (text) {
-      JCR *jcr = get_jcr_from_PyObject(self);
-      Jmsg(jcr, M_INFO, 0, "%s", text);
-   }
-        
-   Py_INCREF(Py_None);
-   return Py_None;
-}
-
-int generate_job_event(JCR *jcr, const char *event)
-{
-#ifdef implemented
-   PyEval_AcquireLock();
-
-   PyObject *result = PyObject_CallFunction(open_method, "s", "m.py");
-   if (result == NULL) {
-      PyErr_Print();
-      PyErr_Clear();
-   }
-   Py_XDECREF(result);
-
-   PyEval_ReleaseLock();
-#endif
-   return 1;
-}
-
-#else
-
-/* Dummy if Python not configured */
-int generate_job_event(JCR *jcr, const char *event)
-{ return 1; }
-
-
-#endif /* HAVE_PYTHON */
diff --git a/bacula/src/stored/pythonsd.c b/bacula/src/stored/pythonsd.c
new file mode 100644 (file)
index 0000000..85ca46e
--- /dev/null
@@ -0,0 +1,261 @@
+/*
+ *
+ * Bacula interface to Python for the Storage Daemon
+ *
+ * Kern Sibbald, January MMV
+ *
+ *   Version $Id$
+ *
+ */
+
+/*
+   Copyright (C) 2005 Kern Sibbald
+
+   This program is free software; you can redistribute it and/or
+   modify it under the terms of the GNU General Public License as
+   published by the Free Software Foundation; either version 2 of
+   the License, or (at your option) any later version.
+
+   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 GNU
+   General Public License for more details.
+
+   You should have received a copy of the GNU General Public
+   License along with this program; if not, write to the Free
+   Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
+   MA 02111-1307, USA.
+
+ */
+
+#include "bacula.h"
+#include "stored.h"
+
+#ifdef HAVE_PYTHON
+#undef _POSIX_C_SOURCE
+#include <Python.h>
+
+extern JCR *get_jcr_from_PyObject(PyObject *self);
+extern PyObject *find_method(PyObject *eventsObject, PyObject *method, 
+         const char *name);
+
+static int set_job_events(PyObject *self, PyObject *arg);
+
+
+struct s_vars {
+   const char *name;
+   char *fmt;
+};
+
+static struct s_vars getvars[] = {
+   { N_("Job"),        "s"},          /* 0 */
+   { N_("SDName"),     "s"},          /* 1 */
+   { N_("Level"),      "s"},          /* 2 */
+   { N_("Type"),       "s"},          /* 3 */
+   { N_("JobId"),      "i"},          /* 4 */
+   { N_("Client"),     "s"},          /* 5 */
+   { N_("Pool"),       "s"},          /* 6 */
+   { N_("MediaType"),  "s"},          /* 7 */
+   { N_("JobName"),    "s"},          /* 8 */
+   { N_("JobStatus"),  "s"},          /* 9 */
+   { N_("VolumeName"), "s"},          /* 10 */
+   { N_("Device"),     "s"},          /* 11 */
+
+   { NULL,             NULL}
+};
+
+
+/* Writable variables */
+static struct s_vars setvars[] = {
+   { N_("set_events"), NULL},
+   { N_("JobReport"),   "s"},
+   { N_("write"),       "s"},
+
+   { NULL,             NULL}
+};
+
+
+/* Return Job variables */
+PyObject *job_getattr(PyObject *self, char *attrname)
+{
+   JCR *jcr;
+   bool found = false;
+   int i;
+   char buf[10];
+   char errmsg[200];
+   
+   Dmsg1(100, "In job_getattr=%s\n", attrname);
+   jcr = get_jcr_from_PyObject(self);
+   if (!jcr) {
+      bstrncpy(errmsg, "Job pointer not found.", sizeof(errmsg));
+      goto bail_out;
+   }
+
+   for (i=0; getvars[i].name; i++) {
+      if (strcmp(getvars[i].name, attrname) == 0) {
+         found = true;
+         break;
+      }
+   }
+   if (!found) {
+      goto not_found;
+   }  
+   switch (i) {
+   case 0:                            /* Job */
+      return Py_BuildValue(getvars[i].fmt, jcr->job_name);    /* Non-unique name */
+   case 1:                            /* SD's name */
+      return Py_BuildValue(getvars[i].fmt, my_name);
+   case 2:                            /* level */
+      return Py_BuildValue(getvars[i].fmt, job_level_to_str(jcr->JobLevel));
+   case 3:                            /* type */
+      return Py_BuildValue(getvars[i].fmt, job_type_to_str(jcr->JobType));
+   case 4:                            /* JobId */
+      return Py_BuildValue(getvars[i].fmt, jcr->JobId);
+   case 5:                            /* Client */
+      return Py_BuildValue(getvars[i].fmt, jcr->client_name);
+   case 6:                            /* Pool */
+      return Py_BuildValue(getvars[i].fmt, jcr->dcr->pool_name);
+   case 7:                            /* MediaType */
+      return Py_BuildValue(getvars[i].fmt, jcr->dcr->media_type);
+   case 8:                            /* JobName */
+      return Py_BuildValue(getvars[i].fmt, jcr->Job);
+   case 9:                            /* JobStatus */
+      buf[1] = 0;
+      buf[0] = jcr->JobStatus;
+      return Py_BuildValue(getvars[i].fmt, buf);
+   case 10:
+      return Py_BuildValue(getvars[i].fmt, jcr->dcr->VolumeName);
+   case 11:
+      return Py_BuildValue(getvars[i].fmt, jcr->dcr->dev_name);
+   }
+not_found:
+   bsnprintf(errmsg, sizeof(errmsg), "Attribute %s not found.", attrname);
+bail_out:
+   PyErr_SetString(PyExc_AttributeError, errmsg);
+   return NULL;
+}
+
+int job_setattr(PyObject *self, char *attrname, PyObject *value)
+{
+  JCR *jcr;
+   bool found = false;
+   char *strval = NULL;
+   char buf[200];
+   char *errmsg;
+   int i;
+
+   Dmsg2(100, "In job_setattr=%s val=%p.\n", attrname, value);
+   if (value == NULL) {                /* Cannot delete variables */
+      bsnprintf(buf, sizeof(buf), "Cannot delete attribute %s", attrname);
+      errmsg = buf;
+      goto bail_out;
+   }
+   jcr = get_jcr_from_PyObject(self);
+   if (!jcr) {
+      errmsg = "Job pointer not found.";
+      goto bail_out;
+   }
+
+   /* Find attribute name in list */
+   for (i=0; setvars[i].name; i++) {
+      if (strcmp(setvars[i].name, attrname) == 0) {
+         found = true;
+         break;
+      }
+   }
+   if (!found) {
+      goto not_found;
+   }
+   /* Get argument value ***FIXME*** handle other formats */
+   if (setvars[i].fmt != NULL) {
+      if (!PyArg_Parse(value, setvars[i].fmt, &strval)) {
+         PyErr_SetString(PyExc_TypeError, "Read-only attribute");
+         return -1;
+      }
+   }   
+   switch (i) {
+   case 0:                            /* set_events */
+      return set_job_events(self, value);
+   case 1:                            /* JobReport */
+   case 2:                            /* write */
+      Jmsg(jcr, M_INFO, 0, "%s", strval);
+      return 0;
+   }
+not_found:
+   bsnprintf(buf, sizeof(buf), "Cannot find attribute %s", attrname);
+   errmsg = buf;
+bail_out:
+   PyErr_SetString(PyExc_AttributeError, errmsg);
+   return -1;
+}
+
+
+static int set_job_events(PyObject *self, PyObject *arg)
+{
+   PyObject *eObject;
+   JCR *jcr;
+
+   Dmsg0(100, "In set_job_events.\n");
+   if (!PyArg_Parse(arg, "O", &eObject)) {
+      Dmsg0(000, "Parse error looking for Object argument\n");
+      return -1;
+   }
+   jcr = get_jcr_from_PyObject(self);
+   if (!jcr) {
+      PyErr_SetString(PyExc_AttributeError, "Job pointer not found.");
+      return -1;
+   }
+   Py_XDECREF((PyObject *)jcr->Python_events);  /* release any old events Object */
+   Py_INCREF(eObject);
+   jcr->Python_events = (void *)eObject;        /* set new events */
+
+   return 0;
+}
+
+
+int generate_job_event(JCR *jcr, const char *event)
+{
+   PyObject *method = NULL;
+   PyObject *Job = (PyObject *)jcr->Python_job;
+   PyObject *result = NULL;
+   int stat = 0;
+
+   if (!Job) {
+      return 0;
+   }
+
+   PyEval_AcquireLock();
+
+   PyObject *events = (PyObject *)jcr->Python_events;
+   method = find_method(events, method, event);
+   if (!method) {
+      goto bail_out;
+   }
+
+   bstrncpy(jcr->event, event, sizeof(jcr->event));
+   result = PyObject_CallFunction(method, "O", Job);
+   jcr->event[0] = 0;             /* no event in progress */
+   if (result == NULL) {
+      if (PyErr_Occurred()) {
+         PyErr_Print();
+         Dmsg1(000, "Error in Python method %s\n", event);
+      }
+   } else {
+      stat = 1;
+   }
+   Py_XDECREF(result);
+
+bail_out:
+   PyEval_ReleaseLock();
+   return stat;
+}
+
+
+#else
+
+/* Dummy if Python not configured */
+int generate_job_event(JCR *jcr, const char *event)
+{ return 1; }
+
+
+#endif /* HAVE_PYTHON */
index fd7c09dba1184f34cf679bedf714632945bb1614..a20be7cf5092587be2ccc369af566b4822d34523 100644 (file)
@@ -185,11 +185,9 @@ int main (int argc, char *argv[])
 
    parse_config(configfile);
 
-#ifdef HAVE_TLS
    if (init_tls() != 0) {
       Jmsg((JCR *)NULL, M_ERROR_TERM, 0, _("TLS library initialization failed.\n"));
    }
-#endif
 
    if (!check_resources()) {
       Jmsg((JCR *)NULL, M_ERROR_TERM, 0, _("Please correct configuration file: %s\n"), configfile);
index f3881e505e090f5f24260fcb45c4d763867f723a..2e73fb83aae65abd2831d2c66112151a328dd9e1 100644 (file)
@@ -1,8 +1,8 @@
 /* */
 #undef  VERSION
-#define VERSION "1.37.14"
-#define BDATE   "26 April 2005"
-#define LSMDATE "26Apr05"
+#define VERSION "1.37.15"
+#define BDATE   "30 April 2005"
+#define LSMDATE "30Apr05"
 
 /* Debug flags */
 #undef  DEBUG