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