3 * Bacula interface to Python for the File Daemon
5 * Kern Sibbald, March MMV
12 Copyright (C) 2005-2006 Kern Sibbald
14 This program is free software; you can redistribute it and/or
15 modify it under the terms of the GNU General Public License as
16 published by the Free Software Foundation; either version 2 of
17 the License, or (at your option) any later version.
19 This program is distributed in the hope that it will be useful,
20 but WITHOUT ANY WARRANTY; without even the implied warranty of
21 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
22 General Public License for more details.
24 You should have received a copy of the GNU General Public
25 License along with this program; if not, write to the Free
26 Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
35 #undef _POSIX_C_SOURCE
38 /* External function pointers to be set */
39 extern bool (*python_set_prog)(JCR *jcr, const char *prog);
40 extern int (*python_open)(BFILE *bfd, const char *fname, int flags, mode_t mode);
41 extern int (*python_close)(BFILE *bfd);
42 extern ssize_t (*python_read)(BFILE *bfd, void *buf, size_t count);
45 extern JCR *get_jcr_from_PyObject(PyObject *self);
46 extern PyObject *find_method(PyObject *eventsObject, PyObject *method,
49 /* Forward referenced functions */
50 static PyObject *set_job_events(PyObject *self, PyObject *arg);
51 static PyObject *job_write(PyObject *self, PyObject *arg);
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 */
60 bool my_python_set_prog(JCR *jcr, const char *prog);
61 int my_python_open(BFILE *bfd, const char *fname, int flags, mode_t mode);
62 int my_python_close(BFILE *bfd);
63 ssize_t my_python_read(BFILE *bfd, void *buf, size_t count);
71 /* Read-only variables */
72 static struct s_vars getvars[] = {
73 { NT_("FDName"), "s"}, /* 0 */
74 { NT_("Level"), "s"}, /* 1 */
75 { NT_("Type"), "s"}, /* 2 */
76 { NT_("JobId"), "i"}, /* 3 */
77 { NT_("Client"), "s"}, /* 4 */
78 { NT_("JobName"), "s"}, /* 5 */
79 { NT_("JobStatus"), "s"}, /* 6 */
84 /* Writable variables */
85 static struct s_vars setvars[] = {
86 { NT_("JobReport"), "s"},
91 /* Return Job variables */
92 PyObject *job_getattr(PyObject *self, char *attrname)
100 jcr = get_jcr_from_PyObject(self);
102 bstrncpy(errmsg, _("Job pointer not found."), sizeof(errmsg));
105 for (i=0; getvars[i].name; i++) {
106 if (strcmp(getvars[i].name, attrname) == 0) {
112 /* Try our methods */
113 return Py_FindMethod(JobMethods, self, attrname);
116 case 0: /* FD's name */
117 return Py_BuildValue(getvars[i].fmt, my_name);
119 return Py_BuildValue(getvars[i].fmt, job_level_to_str(jcr->JobLevel));
121 return Py_BuildValue(getvars[i].fmt, job_type_to_str(jcr->JobType));
123 return Py_BuildValue(getvars[i].fmt, jcr->JobId);
125 return Py_BuildValue(getvars[i].fmt, jcr->client_name);
126 case 5: /* JobName */
127 return Py_BuildValue(getvars[i].fmt, jcr->Job);
128 case 6: /* JobStatus */
130 buf[0] = jcr->JobStatus;
131 return Py_BuildValue(getvars[i].fmt, buf);
133 bsnprintf(errmsg, sizeof(errmsg), _("Attribute %s not found."), attrname);
135 PyErr_SetString(PyExc_AttributeError, errmsg);
139 int job_setattr(PyObject *self, char *attrname, PyObject *value)
148 Dmsg2(100, "In job_setattr=%s val=%p.\n", attrname, value);
149 if (value == NULL) { /* Cannot delete variables */
150 bsnprintf(buf, sizeof(buf), _("Cannot delete attribute %s"), attrname);
154 jcr = get_jcr_from_PyObject(self);
156 errmsg = _("Job pointer not found.");
160 /* Find attribute name in list */
161 for (i=0; setvars[i].name; i++) {
162 if (strcmp(setvars[i].name, attrname) == 0) {
168 bsnprintf(buf, sizeof(buf), _("Cannot find attribute %s"), attrname);
172 /* Get argument value ***FIXME*** handle other formats */
173 if (setvars[i].fmt != NULL) {
174 if (!PyArg_Parse(value, setvars[i].fmt, &strval)) {
175 PyErr_SetString(PyExc_TypeError, _("Read-only attribute"));
180 case 0: /* JobReport */
181 Jmsg(jcr, M_INFO, 0, "%s", strval);
184 bsnprintf(buf, sizeof(buf), _("Cannot find attribute %s"), attrname);
187 PyErr_SetString(PyExc_AttributeError, errmsg);
192 static PyObject *job_write(PyObject *self, PyObject *args)
196 if (!PyArg_ParseTuple(args, "s:write", &text)) {
197 Dmsg0(000, "Parse tuple error in job_write\n");
201 Jmsg(NULL, M_INFO, 0, "%s", text);
208 static PyObject *set_job_events(PyObject *self, PyObject *arg)
213 Dmsg0(100, "In set_job_events.\n");
214 if (!PyArg_ParseTuple(arg, "O", &eObject)) {
215 Dmsg0(000, "Parse error looking for Object argument\n");
218 jcr = get_jcr_from_PyObject(self);
220 PyErr_SetString(PyExc_AttributeError, _("Job pointer not found."));
223 Py_XDECREF((PyObject *)jcr->Python_events); /* release any old events Object */
225 jcr->Python_events = (void *)eObject; /* set new events */
227 /* Set function pointers to call here */
228 python_set_prog = my_python_set_prog;
229 python_open = my_python_open;
230 python_close = my_python_close;
231 python_read = my_python_read;
238 int generate_job_event(JCR *jcr, const char *event)
240 PyObject *method = NULL;
241 PyObject *Job = (PyObject *)jcr->Python_job;
242 PyObject *events = (PyObject *)jcr->Python_events;
243 PyObject *result = NULL;
246 if (!Job || !events) {
250 PyEval_AcquireLock();
252 method = find_method(events, method, event);
257 bstrncpy(jcr->event, event, sizeof(jcr->event));
258 result = PyObject_CallFunction(method, "O", Job);
259 jcr->event[0] = 0; /* no event in progress */
260 if (result == NULL) {
261 if (PyErr_Occurred()) {
263 Dmsg1(000, "Error in Python method %s\n", event);
271 PyEval_ReleaseLock();
276 bool my_python_set_prog(JCR *jcr, const char *prog)
278 PyObject *events = (PyObject *)jcr->Python_events;
279 BFILE *bfd = &jcr->ff->bfd;
280 char method[MAX_NAME_LENGTH];
285 bstrncpy(method, prog, sizeof(method));
286 bstrncat(method, "_", sizeof(method));
287 bstrncat(method, "open", sizeof(method));
288 bfd->pio.fo = find_method(events, bfd->pio.fo, method);
289 bstrncpy(method, prog, sizeof(method));
290 bstrncat(method, "_", sizeof(method));
291 bstrncat(method, "read", sizeof(method));
292 bfd->pio.fr = find_method(events, bfd->pio.fr, method);
293 bstrncpy(method, prog, sizeof(method));
294 bstrncat(method, "_", sizeof(method));
295 bstrncat(method, "close", sizeof(method));
296 bfd->pio.fc = find_method(events, bfd->pio.fc, method);
297 return bfd->pio.fo && bfd->pio.fr && bfd->pio.fc;
300 int my_python_open(BFILE *bfd, const char *fname, int flags, mode_t mode)
305 int my_python_close(BFILE *bfd)
310 ssize_t my_python_read(BFILE *bfd, void *buf, size_t count)
317 /* Dummy if Python not configured */
318 int generate_job_event(JCR *jcr, const char *event)
322 #endif /* HAVE_PYTHON */