]> git.sur5r.net Git - bacula/bacula/blob - bacula/src/lib/python.c
aea7ff571a9a8ff20f11d20f1d19cf09b8a85670
[bacula/bacula] / bacula / src / lib / python.c
1 /*
2
3    Bacula interface to Python
4
5    Kern Sibbald, November MMIV
6    
7    Copyright (C) 2004 Kern Sibbald
8
9    This program is free software; you can redistribute it and/or
10    modify it under the terms of the GNU General Public License as
11    published by the Free Software Foundation; either version 2 of
12    the License, or (at your option) any later version.
13
14    This program is distributed in the hope that it will be useful,
15    but WITHOUT ANY WARRANTY; without even the implied warranty of
16    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17    General Public License for more details.
18
19    You should have received a copy of the GNU General Public
20    License along with this program; if not, write to the Free
21    Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
22    MA 02111-1307, USA.
23
24  */
25
26 #include "bacula.h"
27 #include "../dird/dird_conf.h"
28 #define DIRECTOR_DAEMON 1
29 #include "../cats/cats.h"
30 #include "jcr.h"
31
32
33 #ifdef HAVE_PYTHON
34 #include <Python.h>
35
36 bool run_module(const char *module);
37
38 static PyObject *bacula_get(PyObject *self, PyObject *args);
39 static PyObject *bacula_set(PyObject *self, PyObject *args, PyObject *keyw);
40
41 /* Define Bacula entry points */
42 static PyMethodDef BaculaMethods[] = {
43     {"get", bacula_get, METH_VARARGS, "Get Bacula variables."},
44     {"set", (PyCFunction)bacula_set, METH_VARARGS|METH_KEYWORDS,
45         "Set Bacula variables."}, 
46     {NULL, NULL, 0, NULL}             /* last item */
47 };
48
49
50 /* Return Bacula variables */
51 static PyObject*
52 bacula_get(PyObject *self, PyObject *args)
53 {
54    PyObject *CObject;
55    JCR *jcr;
56    char *item;
57    if (!PyArg_ParseTuple(args, "Os:get", &CObject, &item)) {
58       return NULL;
59    }
60    jcr = (JCR *)PyCObject_AsVoidPtr(CObject);
61    /* ***FIXME*** put this in a table */
62    if (strcmp(item, "JobId") == 0) {
63       return Py_BuildValue("i", jcr->JobId);
64    } else if (strcmp(item, "Client") == 0) {
65       return Py_BuildValue("s", jcr->client->hdr.name);
66    } else if (strcmp(item, "Pool") == 0) {
67       return Py_BuildValue("s", jcr->pool->hdr.name);
68    } else if (strcmp(item, "Storage") == 0) {
69       return Py_BuildValue("s", jcr->store->hdr.name);
70    } else if (strcmp(item, "Catalog") == 0) {
71       return Py_BuildValue("s", jcr->catalog->hdr.name);
72    } else if (strcmp(item, "MediaType") == 0) {
73       return Py_BuildValue("s", jcr->store->media_type);
74    } else if (strcmp(item, "NumVols") == 0) {
75       return Py_BuildValue("i", jcr->NumVols);
76    } else if (strcmp(item, "DirName") == 0) {
77       return Py_BuildValue("s", my_name);
78    } else if (strcmp(item, "Level") == 0) {
79       return Py_BuildValue("s", job_level_to_str(jcr->JobLevel));
80    } else if (strcmp(item, "Type") == 0) {
81       return Py_BuildValue("s", job_type_to_str(jcr->JobType));
82    } else if (strcmp(item, "Job") == 0) {
83       return Py_BuildValue("s", jcr->job->hdr.name);
84    } else if (strcmp(item, "JobName") == 0) {
85       return Py_BuildValue("s", jcr->Job);
86    }
87    return NULL;
88 }
89
90 /* Set Bacula variables */
91 static PyObject*                                         
92 bacula_set(PyObject *self, PyObject *args, PyObject *keyw)
93 {
94    PyObject *CObject;
95    JCR *jcr;
96    char *msg = NULL;
97    char *VolumeName = NULL;
98    static char *kwlist[] = {"jcr", "JobReport", "VolumeName", NULL};
99    if (!PyArg_ParseTupleAndKeywords(args, keyw, "O|ss:set", kwlist, 
100         &CObject, &msg, &VolumeName)) {
101       return NULL;
102    }
103    jcr = (JCR *)PyCObject_AsVoidPtr(CObject);
104    if (msg) {
105       Jmsg(jcr, M_INFO, 0, "%s", msg);
106    }
107    if (VolumeName) {
108       pm_strcpy(jcr->VolumeName, VolumeName);
109    }
110    return Py_BuildValue("i", 1);
111 }
112
113
114 void init_python_interpreter(char *progname)
115 {
116    Py_SetProgramName(progname);
117    Py_Initialize();
118    PyEval_InitThreads();
119    Py_InitModule("bacula", BaculaMethods);
120    PyRun_SimpleString("import sys\n"
121                       "sys.path.append('.')\n");
122    PyEval_ReleaseLock();
123 }
124
125 void term_python_interpreter()
126 {
127    Py_Finalize();
128 }
129
130
131 /* 
132  * Generate and process a Bacula event by importing a Python
133  *  module and running it.
134  *
135  *  Returns: 0 if Python not configured or module not found
136  *          -1 on Python error
137  *           1 OK
138  */
139 int generate_event(JCR *jcr, const char *event)
140 {
141    PyObject *pName, *pModule, *pDict, *pFunc;
142    PyObject *pArgs, *pValue;
143
144    pName = PyString_FromString(event);
145    if (!pName) {
146       Jmsg(jcr, M_ERROR, 0, "Could not convert \"%s\" to Python string.\n", event);
147       return -1;                      /* Could not convert string */
148    }
149
150    pModule = PyImport_Import(pName);
151    Py_DECREF(pName);                  /* release pName */
152
153    if (pModule != NULL) {
154       pDict = PyModule_GetDict(pModule);
155       /* pDict is a borrowed reference */
156
157       pFunc = PyDict_GetItemString(pDict, (char *)event);
158       /* pFun: Borrowed reference */
159
160       if (pFunc && PyCallable_Check(pFunc)) {
161           /* Create JCR argument to send to function */
162           pArgs = PyTuple_New(1);
163           pValue = PyCObject_FromVoidPtr((void *)jcr, NULL);
164           if (!pValue) {
165              Py_DECREF(pArgs);
166              Py_DECREF(pModule);
167              Jmsg(jcr, M_ERROR, 0, "Could not convert JCR to Python CObject.\n");
168              return -1;               /* Could not convert JCR to CObject */
169           }
170           /* pValue reference stolen here: */
171           PyTuple_SetItem(pArgs, 0, pValue);
172
173           /* Finally, we call the module here */
174           pValue = PyObject_CallObject(pFunc, pArgs);
175           Py_DECREF(pArgs);
176           if (pValue != NULL) {
177              Py_DECREF(pValue);
178           } else {
179              Py_DECREF(pModule);
180              PyErr_Print();
181              Jmsg(jcr, M_ERROR, 0, "Error running Python module: %s\n", event);
182              return 0;                /* error running function */
183           }
184           /* pDict and pFunc are borrowed and must not be Py_DECREF-ed */
185       } else {
186          Jmsg(jcr, M_ERROR, 0, "Python function \"%s\" not found in module.\n", event);
187          return -1;                   /* function not found */ 
188       }
189       Py_DECREF(pModule);
190    } else {
191       return 0;                       /* Module not present */
192    }
193    return 1;
194 }
195
196 #else
197
198 /*
199  *  No Python configured
200  */
201
202 int generate_event(JCR *jcr, const char *event) { return 0; }
203 void init_python_interpreter(char *progname) { }
204 void term_python_interpreter() { }
205
206
207 #endif /* HAVE_PYTHON */