]> git.sur5r.net Git - bacula/bacula/blob - bacula/src/stored/pythonsd.c
4a9b83048a2a3b086903b078466ca3f7c9401f39
[bacula/bacula] / bacula / src / stored / pythonsd.c
1 /*
2    Bacula® - The Network Backup Solution
3
4    Copyright (C) 2005-2008 Free Software Foundation Europe e.V.
5
6    The main author of Bacula is Kern Sibbald, with contributions from
7    many others, a complete list can be found in the file AUTHORS.
8    This program is Free Software; you can redistribute it and/or
9    modify it under the terms of version two of the GNU General Public
10    License as published by the Free Software Foundation and included
11    in the file LICENSE.
12
13    This program is distributed in the hope that it will be useful, but
14    WITHOUT ANY WARRANTY; without even the implied warranty of
15    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16    General Public License for more details.
17
18    You should have received a copy of the GNU General Public License
19    along with this program; if not, write to the Free Software
20    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
21    02110-1301, USA.
22
23    Bacula® is a registered trademark of Kern Sibbald.
24    The licensor of Bacula is the Free Software Foundation Europe
25    (FSFE), Fiduciary Program, Sumatrastrasse 25, 8006 Zürich,
26    Switzerland, email:ftf@fsfeurope.org.
27 */
28 /*
29  *
30  * Bacula interface to Python for the Storage Daemon
31  *
32  * Kern Sibbald, January MMV
33  *
34  *   Version $Id$
35  *
36  */
37
38
39 #include "bacula.h"
40 #include "stored.h"
41
42 #ifdef HAVE_PYTHON
43 #undef _POSIX_C_SOURCE
44 #include <Python.h>
45
46 extern JCR *get_jcr_from_PyObject(PyObject *self);
47 extern PyObject *find_method(PyObject *eventsObject, PyObject *method, 
48          const char *name);
49
50 static PyObject *set_job_events(PyObject *self, PyObject *arg);
51 static PyObject *job_write(PyObject *self, PyObject *arg);
52
53 PyMethodDef JobMethods[] = {
54     {"set_events", set_job_events, METH_VARARGS, "Set Job events"},
55     {"write", job_write, METH_VARARGS, "Write to output"},
56     {NULL, NULL, 0, NULL}             /* last item */
57 };
58
59
60 struct s_vars {
61    const char *name;
62    const char *fmt;
63 };
64
65 static struct s_vars getvars[] = {
66    { NT_("Job"),        "s"},          /* 0 */
67    { NT_("SDName"),     "s"},          /* 1 */
68    { NT_("Level"),      "s"},          /* 2 */
69    { NT_("Type"),       "s"},          /* 3 */
70    { NT_("JobId"),      "i"},          /* 4 */
71    { NT_("Client"),     "s"},          /* 5 */
72    { NT_("Pool"),       "s"},          /* 6 */
73    { NT_("MediaType"),  "s"},          /* 7 */
74    { NT_("JobName"),    "s"},          /* 8 */
75    { NT_("JobStatus"),  "s"},          /* 9 */
76    { NT_("VolumeName"), "s"},          /* 10 */
77    { NT_("Device"),     "s"},          /* 11 */
78
79    { NULL,             NULL}
80 };
81
82
83 /* Writable variables */
84 static struct s_vars setvars[] = {
85    { NT_("JobReport"),   "s"},
86
87    { NULL,             NULL}
88 };
89
90
91 /* Return Job variables */
92 PyObject *job_getattr(PyObject *self, char *attrname)
93 {
94    JCR *jcr;
95    bool found = false;
96    int i;
97    char buf[10];
98    char errmsg[200];
99    
100    Dmsg1(100, "In job_getattr=%s\n", attrname);
101    jcr = get_jcr_from_PyObject(self);
102    if (!jcr) {
103       bstrncpy(errmsg, _("Job pointer not found."), sizeof(errmsg));
104       goto bail_out;
105    }
106
107    for (i=0; getvars[i].name; i++) {
108       if (strcmp(getvars[i].name, attrname) == 0) {
109          found = true;
110          break;
111       }
112    }
113    if (!found) {
114       /* Try our methods */
115       return Py_FindMethod(JobMethods, self, attrname);
116    }  
117    switch (i) {
118    case 0:                            /* Job */
119       return Py_BuildValue((char *)getvars[i].fmt, jcr->job_name);    /* Non-unique name */
120    case 1:                            /* SD's name */
121       return Py_BuildValue((char *)getvars[i].fmt, my_name);
122    case 2:                            /* level */
123       return Py_BuildValue((char *)getvars[i].fmt, job_level_to_str(jcr->get_JobLevel()));
124    case 3:                            /* type */
125       return Py_BuildValue((char *)getvars[i].fmt, job_type_to_str(jcr->get_JobType()));
126    case 4:                            /* JobId */
127       return Py_BuildValue((char *)getvars[i].fmt, jcr->JobId);
128    case 5:                            /* Client */
129       return Py_BuildValue((char *)getvars[i].fmt, jcr->client_name);
130    case 6:                            /* Pool */
131       return Py_BuildValue((char *)getvars[i].fmt, jcr->dcr->pool_name);
132    case 7:                            /* MediaType */
133       return Py_BuildValue((char *)getvars[i].fmt, jcr->dcr->media_type);
134    case 8:                            /* JobName */
135       return Py_BuildValue((char *)getvars[i].fmt, jcr->Job);
136    case 9:                            /* JobStatus */
137       buf[1] = 0;
138       buf[0] = jcr->JobStatus;
139       return Py_BuildValue((char *)getvars[i].fmt, buf);
140    case 10:
141       return Py_BuildValue((char *)getvars[i].fmt, jcr->dcr->VolumeName);
142    case 11:
143       return Py_BuildValue((char *)getvars[i].fmt, jcr->dcr->dev_name);
144    }
145    bsnprintf(errmsg, sizeof(errmsg), _("Attribute %s not found."), attrname);
146 bail_out:
147    PyErr_SetString(PyExc_AttributeError, errmsg);
148    return NULL;
149 }
150
151 int job_setattr(PyObject *self, char *attrname, PyObject *value)
152 {
153   JCR *jcr;
154    bool found = false;
155    char *strval = NULL;
156    char buf[200];
157    char *errmsg;
158    int i;
159
160    Dmsg2(100, "In job_setattr=%s val=%p.\n", attrname, value);
161    if (value == NULL) {                /* Cannot delete variables */
162       bsnprintf(buf, sizeof(buf), _("Cannot delete attribute %s"), attrname);
163       errmsg = buf;
164       goto bail_out;
165    }
166    jcr = get_jcr_from_PyObject(self);
167    if (!jcr) {
168       errmsg = _("Job pointer not found.");
169       goto bail_out;
170    }
171
172    /* Find attribute name in list */
173    for (i=0; setvars[i].name; i++) {
174       if (strcmp(setvars[i].name, attrname) == 0) {
175          found = true;
176          break;
177       }
178    }
179    if (!found) {
180       goto not_found;
181    }
182    /* Get argument value ***FIXME*** handle other formats */
183    if (setvars[i].fmt != NULL) {
184       if (!PyArg_Parse(value, (char *)setvars[i].fmt, &strval)) {
185          PyErr_SetString(PyExc_TypeError, _("Read-only attribute"));
186          return -1;
187       }
188    }   
189    switch (i) {
190    case 0:                            /* JobReport */
191       Jmsg(jcr, M_INFO, 0, "%s", strval);
192       return 0;
193    }
194 not_found:
195    bsnprintf(buf, sizeof(buf), _("Cannot find attribute %s"), attrname);
196    errmsg = buf;
197 bail_out:
198    PyErr_SetString(PyExc_AttributeError, errmsg);
199    return -1;
200 }
201
202
203 static PyObject *set_job_events(PyObject *self, PyObject *arg)
204 {
205    PyObject *eObject;
206    JCR *jcr;
207
208    Dmsg0(100, "In set_job_events.\n");
209    if (!PyArg_ParseTuple(arg, "O:set_events", &eObject)) {
210       Pmsg0(000, _("Error in ParseTuple\n"));
211       return NULL;
212    }
213    jcr = get_jcr_from_PyObject(self);
214    Py_XDECREF((PyObject *)jcr->Python_events);
215    Py_INCREF(eObject);
216    jcr->Python_events = (void *)eObject;
217    Py_INCREF(Py_None);
218    return Py_None;
219 }
220
221 static PyObject *job_write(PyObject *self, PyObject *args)
222 {
223    char *text = NULL;
224
225    if (!PyArg_ParseTuple(args, "s:write", &text)) {
226       Pmsg0(000, _("Parse tuple error in job_write\n"));
227       return NULL;
228    }
229    if (text) {
230       Jmsg(NULL, M_INFO, 0, "%s", text);
231    }
232    Py_INCREF(Py_None);
233    return Py_None;
234 }
235
236
237 int generate_job_event(JCR *jcr, const char *event)
238 {
239    PyObject *method = NULL;
240    PyObject *Job = (PyObject *)jcr->Python_job;
241    PyObject *events = (PyObject *)jcr->Python_events;
242    PyObject *result = NULL;
243    int stat = 0;
244
245    if (!Job || !events) {
246       return 0;
247    }
248
249    lock_python();
250 // PyEval_AcquireLock();
251
252    method = find_method(events, method, event);
253    if (!method) {
254       goto bail_out;
255    }
256
257    bstrncpy(jcr->event, event, sizeof(jcr->event));
258    result = PyObject_CallFunction(method, (char *)"O", Job);
259    jcr->event[0] = 0;             /* no event in progress */
260    if (result == NULL) {
261       if (PyErr_Occurred()) {
262          PyErr_Print();
263          Dmsg1(000, _("Error in Python method %s\n"), event);
264       }
265    } else {
266       stat = 1;
267    }
268    Py_XDECREF(result);
269
270 bail_out:
271    unlock_python();
272 // PyEval_ReleaseLock();
273    return stat;
274 }
275
276
277 #else
278
279 /* Dummy if Python not configured */
280 int generate_job_event(JCR *jcr, const char *event)
281 { return 1; }
282
283
284 #endif /* HAVE_PYTHON */