]> git.sur5r.net Git - bacula/bacula/blob - bacula/src/stored/pythonsd.c
Enhance FD status to have level
[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 #include <lib/pythonlib.h>
47
48 static PyObject *set_job_events(PyObject *self, PyObject *arg);
49 static PyObject *job_write(PyObject *self, PyObject *arg);
50
51 PyMethodDef JobMethods[] = {
52     {"set_events", set_job_events, METH_VARARGS, "Set Job events"},
53     {"write", job_write, METH_VARARGS, "Write to output"},
54     {NULL, NULL, 0, NULL}             /* last item */
55 };
56
57
58 struct s_vars {
59    const char *name;
60    const char *fmt;
61 };
62
63 static struct s_vars getvars[] = {
64    { NT_("Job"),        "s"},          /* 0 */
65    { NT_("SDName"),     "s"},          /* 1 */
66    { NT_("Level"),      "s"},          /* 2 */
67    { NT_("Type"),       "s"},          /* 3 */
68    { NT_("JobId"),      "i"},          /* 4 */
69    { NT_("Client"),     "s"},          /* 5 */
70    { NT_("Pool"),       "s"},          /* 6 */
71    { NT_("MediaType"),  "s"},          /* 7 */
72    { NT_("JobName"),    "s"},          /* 8 */
73    { NT_("JobStatus"),  "s"},          /* 9 */
74    { NT_("VolumeName"), "s"},          /* 10 */
75    { NT_("Device"),     "s"},          /* 11 */
76
77    { NULL,             NULL}
78 };
79
80
81 /* Writable variables */
82 static struct s_vars setvars[] = {
83    { NT_("JobReport"),   "s"},
84
85    { NULL,             NULL}
86 };
87
88
89 /* Return Job variables */
90 PyObject *job_getattr(PyObject *self, char *attrname)
91 {
92    JCR *jcr;
93    bool found = false;
94    int i;
95    char buf[10];
96    char errmsg[200];
97    
98    Dmsg1(100, "In job_getattr=%s\n", attrname);
99    jcr = get_jcr_from_PyObject(self);
100    if (!jcr) {
101       bstrncpy(errmsg, _("Job pointer not found."), sizeof(errmsg));
102       goto bail_out;
103    }
104
105    for (i=0; getvars[i].name; i++) {
106       if (strcmp(getvars[i].name, attrname) == 0) {
107          found = true;
108          break;
109       }
110    }
111    if (!found) {
112       /* Try our methods */
113       return Py_FindMethod(JobMethods, self, attrname);
114    }  
115    switch (i) {
116    case 0:                            /* Job */
117       return Py_BuildValue((char *)getvars[i].fmt, jcr->job_name);    /* Non-unique name */
118    case 1:                            /* SD's name */
119       return Py_BuildValue((char *)getvars[i].fmt, my_name);
120    case 2:                            /* level */
121       return Py_BuildValue((char *)getvars[i].fmt, job_level_to_str(jcr->getJobLevel()));
122    case 3:                            /* type */
123       return Py_BuildValue((char *)getvars[i].fmt, job_type_to_str(jcr->getJobType()));
124    case 4:                            /* JobId */
125       return Py_BuildValue((char *)getvars[i].fmt, jcr->JobId);
126    case 5:                            /* Client */
127       return Py_BuildValue((char *)getvars[i].fmt, jcr->client_name);
128    case 6:                            /* Pool */
129       return Py_BuildValue((char *)getvars[i].fmt, jcr->dcr->pool_name);
130    case 7:                            /* MediaType */
131       return Py_BuildValue((char *)getvars[i].fmt, jcr->dcr->media_type);
132    case 8:                            /* JobName */
133       return Py_BuildValue((char *)getvars[i].fmt, jcr->Job);
134    case 9:                            /* JobStatus */
135       buf[1] = 0;
136       buf[0] = jcr->JobStatus;
137       return Py_BuildValue((char *)getvars[i].fmt, buf);
138    case 10:
139       return Py_BuildValue((char *)getvars[i].fmt, jcr->dcr->VolumeName);
140    case 11:
141       return Py_BuildValue((char *)getvars[i].fmt, jcr->dcr->dev_name);
142    }
143    bsnprintf(errmsg, sizeof(errmsg), _("Attribute %s not found."), attrname);
144 bail_out:
145    PyErr_SetString(PyExc_AttributeError, errmsg);
146    return NULL;
147 }
148
149 int job_setattr(PyObject *self, char *attrname, PyObject *value)
150 {
151   JCR *jcr;
152    bool found = false;
153    char *strval = NULL;
154    char buf[200];
155    char *errmsg;
156    int i;
157
158    Dmsg2(100, "In job_setattr=%s val=%p.\n", attrname, value);
159    if (value == NULL) {                /* Cannot delete variables */
160       bsnprintf(buf, sizeof(buf), _("Cannot delete attribute %s"), attrname);
161       errmsg = buf;
162       goto bail_out;
163    }
164    jcr = get_jcr_from_PyObject(self);
165    if (!jcr) {
166       errmsg = _("Job pointer not found.");
167       goto bail_out;
168    }
169
170    /* Find attribute name in list */
171    for (i=0; setvars[i].name; i++) {
172       if (strcmp(setvars[i].name, attrname) == 0) {
173          found = true;
174          break;
175       }
176    }
177    if (!found) {
178       goto not_found;
179    }
180    /* Get argument value ***FIXME*** handle other formats */
181    if (setvars[i].fmt != NULL) {
182       if (!PyArg_Parse(value, (char *)setvars[i].fmt, &strval)) {
183          PyErr_SetString(PyExc_TypeError, _("Read-only attribute"));
184          return -1;
185       }
186    }   
187    switch (i) {
188    case 0:                            /* JobReport */
189       Jmsg(jcr, M_INFO, 0, "%s", strval);
190       return 0;
191    }
192 not_found:
193    bsnprintf(buf, sizeof(buf), _("Cannot find attribute %s"), attrname);
194    errmsg = buf;
195 bail_out:
196    PyErr_SetString(PyExc_AttributeError, errmsg);
197    return -1;
198 }
199
200
201 static PyObject *set_job_events(PyObject *self, PyObject *arg)
202 {
203    PyObject *eObject;
204    JCR *jcr;
205
206    Dmsg0(100, "In set_job_events.\n");
207    if (!PyArg_ParseTuple(arg, "O:set_events", &eObject)) {
208       Pmsg0(000, _("Error in ParseTuple\n"));
209       return NULL;
210    }
211    jcr = get_jcr_from_PyObject(self);
212    Py_XDECREF((PyObject *)jcr->Python_events);
213    Py_INCREF(eObject);
214    jcr->Python_events = (void *)eObject;
215    Py_INCREF(Py_None);
216    return Py_None;
217 }
218
219 static PyObject *job_write(PyObject *self, PyObject *args)
220 {
221    char *text = NULL;
222
223    if (!PyArg_ParseTuple(args, "s:write", &text)) {
224       Pmsg0(000, _("Parse tuple error in job_write\n"));
225       return NULL;
226    }
227    if (text) {
228       Jmsg(NULL, M_INFO, 0, "%s", text);
229    }
230    Py_INCREF(Py_None);
231    return Py_None;
232 }
233
234
235 int generate_job_event(JCR *jcr, const char *event)
236 {
237    PyObject *method = NULL;
238    PyObject *Job = (PyObject *)jcr->Python_job;
239    PyObject *events = (PyObject *)jcr->Python_events;
240    PyObject *result = NULL;
241    int stat = 0;
242
243    if (!Job || !events) {
244       return 0;
245    }
246
247    lock_python();
248 // PyEval_AcquireLock();
249
250    method = find_method(events, method, event);
251    if (!method) {
252       goto bail_out;
253    }
254
255    bstrncpy(jcr->event, event, sizeof(jcr->event));
256    result = PyObject_CallFunction(method, (char *)"O", Job);
257    jcr->event[0] = 0;             /* no event in progress */
258    if (result == NULL) {
259       if (PyErr_Occurred()) {
260          PyErr_Print();
261          Dmsg1(000, _("Error in Python method %s\n"), event);
262       }
263    } else {
264       stat = 1;
265    }
266    Py_XDECREF(result);
267
268 bail_out:
269    unlock_python();
270 // PyEval_ReleaseLock();
271    return stat;
272 }
273
274
275 #else
276
277 /* Dummy if Python not configured */
278 int generate_job_event(JCR *jcr, const char *event)
279 { return 1; }
280
281
282 #endif /* HAVE_PYTHON */