3 * Bacula interface to Python for the File Daemon
5 * Kern Sibbald, March MMV
11 Bacula® - The Network Backup Solution
13 Copyright (C) 2005-2006 Free Software Foundation Europe e.V.
15 The main author of Bacula is Kern Sibbald, with contributions from
16 many others, a complete list can be found in the file AUTHORS.
17 This program is Free Software; you can redistribute it and/or
18 modify it under the terms of version two of the GNU General Public
19 License as published by the Free Software Foundation plus additions
20 that are listed in the file LICENSE.
22 This program is distributed in the hope that it will be useful, but
23 WITHOUT ANY WARRANTY; without even the implied warranty of
24 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
25 General Public License for more details.
27 You should have received a copy of the GNU General Public License
28 along with this program; if not, write to the Free Software
29 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
32 Bacula® is a registered trademark of John Walker.
33 The licensor of Bacula is the Free Software Foundation Europe
34 (FSFE), Fiduciary Program, Sumatrastrasse 25, 8006 Zürich,
35 Switzerland, email:ftf@fsfeurope.org.
42 #undef _POSIX_C_SOURCE
45 /* External function pointers to be set */
46 extern bool (*python_set_prog)(JCR *jcr, const char *prog);
47 extern int (*python_open)(BFILE *bfd, const char *fname, int flags, mode_t mode);
48 extern int (*python_close)(BFILE *bfd);
49 extern ssize_t (*python_read)(BFILE *bfd, void *buf, size_t count);
52 extern JCR *get_jcr_from_PyObject(PyObject *self);
53 extern PyObject *find_method(PyObject *eventsObject, PyObject *method,
56 /* Forward referenced functions */
57 static PyObject *set_job_events(PyObject *self, PyObject *arg);
58 static PyObject *job_write(PyObject *self, PyObject *arg);
60 PyMethodDef JobMethods[] = {
61 {"set_events", set_job_events, METH_VARARGS, "Set Job events"},
62 {"write", job_write, METH_VARARGS, "Write to output"},
63 {NULL, NULL, 0, NULL} /* last item */
67 bool my_python_set_prog(JCR *jcr, const char *prog);
68 int my_python_open(BFILE *bfd, const char *fname, int flags, mode_t mode);
69 int my_python_close(BFILE *bfd);
70 ssize_t my_python_read(BFILE *bfd, void *buf, size_t count);
78 /* Read-only variables */
79 static struct s_vars getvars[] = {
80 { NT_("FDName"), "s"}, /* 0 */
81 { NT_("Level"), "s"}, /* 1 */
82 { NT_("Type"), "s"}, /* 2 */
83 { NT_("JobId"), "i"}, /* 3 */
84 { NT_("Client"), "s"}, /* 4 */
85 { NT_("JobName"), "s"}, /* 5 */
86 { NT_("JobStatus"), "s"}, /* 6 */
91 /* Writable variables */
92 static struct s_vars setvars[] = {
93 { NT_("JobReport"), "s"},
98 /* Return Job variables */
99 PyObject *job_getattr(PyObject *self, char *attrname)
107 jcr = get_jcr_from_PyObject(self);
109 bstrncpy(errmsg, _("Job pointer not found."), sizeof(errmsg));
112 for (i=0; getvars[i].name; i++) {
113 if (strcmp(getvars[i].name, attrname) == 0) {
119 /* Try our methods */
120 return Py_FindMethod(JobMethods, self, attrname);
123 case 0: /* FD's name */
124 return Py_BuildValue(getvars[i].fmt, my_name);
126 return Py_BuildValue(getvars[i].fmt, job_level_to_str(jcr->JobLevel));
128 return Py_BuildValue(getvars[i].fmt, job_type_to_str(jcr->JobType));
130 return Py_BuildValue(getvars[i].fmt, jcr->JobId);
132 return Py_BuildValue(getvars[i].fmt, jcr->client_name);
133 case 5: /* JobName */
134 return Py_BuildValue(getvars[i].fmt, jcr->Job);
135 case 6: /* JobStatus */
137 buf[0] = jcr->JobStatus;
138 return Py_BuildValue(getvars[i].fmt, buf);
140 bsnprintf(errmsg, sizeof(errmsg), _("Attribute %s not found."), attrname);
142 PyErr_SetString(PyExc_AttributeError, errmsg);
146 int job_setattr(PyObject *self, char *attrname, PyObject *value)
155 Dmsg2(100, "In job_setattr=%s val=%p.\n", attrname, value);
156 if (value == NULL) { /* Cannot delete variables */
157 bsnprintf(buf, sizeof(buf), _("Cannot delete attribute %s"), attrname);
161 jcr = get_jcr_from_PyObject(self);
163 errmsg = _("Job pointer not found.");
167 /* Find attribute name in list */
168 for (i=0; setvars[i].name; i++) {
169 if (strcmp(setvars[i].name, attrname) == 0) {
175 bsnprintf(buf, sizeof(buf), _("Cannot find attribute %s"), attrname);
179 /* Get argument value ***FIXME*** handle other formats */
180 if (setvars[i].fmt != NULL) {
181 if (!PyArg_Parse(value, setvars[i].fmt, &strval)) {
182 PyErr_SetString(PyExc_TypeError, _("Read-only attribute"));
187 case 0: /* JobReport */
188 Jmsg(jcr, M_INFO, 0, "%s", strval);
191 bsnprintf(buf, sizeof(buf), _("Cannot find attribute %s"), attrname);
194 PyErr_SetString(PyExc_AttributeError, errmsg);
199 static PyObject *job_write(PyObject *self, PyObject *args)
203 if (!PyArg_ParseTuple(args, "s:write", &text)) {
204 Dmsg0(000, "Parse tuple error in job_write\n");
208 Jmsg(NULL, M_INFO, 0, "%s", text);
215 static PyObject *set_job_events(PyObject *self, PyObject *arg)
220 Dmsg0(100, "In set_job_events.\n");
221 if (!PyArg_ParseTuple(arg, "O", &eObject)) {
222 Dmsg0(000, "Parse error looking for Object argument\n");
225 jcr = get_jcr_from_PyObject(self);
227 PyErr_SetString(PyExc_AttributeError, _("Job pointer not found."));
230 Py_XDECREF((PyObject *)jcr->Python_events); /* release any old events Object */
232 jcr->Python_events = (void *)eObject; /* set new events */
234 /* Set function pointers to call here */
235 python_set_prog = my_python_set_prog;
236 python_open = my_python_open;
237 python_close = my_python_close;
238 python_read = my_python_read;
245 int generate_job_event(JCR *jcr, const char *event)
247 PyObject *method = NULL;
248 PyObject *Job = (PyObject *)jcr->Python_job;
249 PyObject *events = (PyObject *)jcr->Python_events;
250 PyObject *result = NULL;
253 if (!Job || !events) {
258 // PyEval_AcquireLock();
260 method = find_method(events, method, event);
265 bstrncpy(jcr->event, event, sizeof(jcr->event));
266 result = PyObject_CallFunction(method, "O", Job);
267 jcr->event[0] = 0; /* no event in progress */
268 if (result == NULL) {
269 if (PyErr_Occurred()) {
271 Dmsg1(000, "Error in Python method %s\n", event);
280 // PyEval_ReleaseLock();
285 bool my_python_set_prog(JCR *jcr, const char *prog)
287 PyObject *events = (PyObject *)jcr->Python_events;
288 BFILE *bfd = &jcr->ff->bfd;
289 char method[MAX_NAME_LENGTH];
294 bstrncpy(method, prog, sizeof(method));
295 bstrncat(method, "_", sizeof(method));
296 bstrncat(method, "open", sizeof(method));
297 bfd->pio.fo = find_method(events, bfd->pio.fo, method);
298 bstrncpy(method, prog, sizeof(method));
299 bstrncat(method, "_", sizeof(method));
300 bstrncat(method, "read", sizeof(method));
301 bfd->pio.fr = find_method(events, bfd->pio.fr, method);
302 bstrncpy(method, prog, sizeof(method));
303 bstrncat(method, "_", sizeof(method));
304 bstrncat(method, "close", sizeof(method));
305 bfd->pio.fc = find_method(events, bfd->pio.fc, method);
306 return bfd->pio.fo && bfd->pio.fr && bfd->pio.fc;
309 int my_python_open(BFILE *bfd, const char *fname, int flags, mode_t mode)
314 int my_python_close(BFILE *bfd)
319 ssize_t my_python_read(BFILE *bfd, void *buf, size_t count)
326 /* Dummy if Python not configured */
327 int generate_job_event(JCR *jcr, const char *event)
331 #endif /* HAVE_PYTHON */