3 * Bacula interface to Python for the Storage Daemon
5 * Kern Sibbald, January 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 and included
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.
43 #undef _POSIX_C_SOURCE
46 extern JCR *get_jcr_from_PyObject(PyObject *self);
47 extern PyObject *find_method(PyObject *eventsObject, PyObject *method,
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 */
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 */
83 /* Writable variables */
84 static struct s_vars setvars[] = {
85 { NT_("JobReport"), "s"},
91 /* Return Job variables */
92 PyObject *job_getattr(PyObject *self, char *attrname)
100 Dmsg1(100, "In job_getattr=%s\n", attrname);
101 jcr = get_jcr_from_PyObject(self);
103 bstrncpy(errmsg, _("Job pointer not found."), sizeof(errmsg));
107 for (i=0; getvars[i].name; i++) {
108 if (strcmp(getvars[i].name, attrname) == 0) {
114 /* Try our methods */
115 return Py_FindMethod(JobMethods, self, attrname);
119 return Py_BuildValue(getvars[i].fmt, jcr->job_name); /* Non-unique name */
120 case 1: /* SD's name */
121 return Py_BuildValue(getvars[i].fmt, my_name);
123 return Py_BuildValue(getvars[i].fmt, job_level_to_str(jcr->JobLevel));
125 return Py_BuildValue(getvars[i].fmt, job_type_to_str(jcr->JobType));
127 return Py_BuildValue(getvars[i].fmt, jcr->JobId);
129 return Py_BuildValue(getvars[i].fmt, jcr->client_name);
131 return Py_BuildValue(getvars[i].fmt, jcr->dcr->pool_name);
132 case 7: /* MediaType */
133 return Py_BuildValue(getvars[i].fmt, jcr->dcr->media_type);
134 case 8: /* JobName */
135 return Py_BuildValue(getvars[i].fmt, jcr->Job);
136 case 9: /* JobStatus */
138 buf[0] = jcr->JobStatus;
139 return Py_BuildValue(getvars[i].fmt, buf);
141 return Py_BuildValue(getvars[i].fmt, jcr->dcr->VolumeName);
143 return Py_BuildValue(getvars[i].fmt, jcr->dcr->dev_name);
145 bsnprintf(errmsg, sizeof(errmsg), _("Attribute %s not found."), attrname);
147 PyErr_SetString(PyExc_AttributeError, errmsg);
151 int job_setattr(PyObject *self, char *attrname, PyObject *value)
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);
166 jcr = get_jcr_from_PyObject(self);
168 errmsg = _("Job pointer not found.");
172 /* Find attribute name in list */
173 for (i=0; setvars[i].name; i++) {
174 if (strcmp(setvars[i].name, attrname) == 0) {
182 /* Get argument value ***FIXME*** handle other formats */
183 if (setvars[i].fmt != NULL) {
184 if (!PyArg_Parse(value, setvars[i].fmt, &strval)) {
185 PyErr_SetString(PyExc_TypeError, _("Read-only attribute"));
190 case 0: /* JobReport */
191 Jmsg(jcr, M_INFO, 0, "%s", strval);
195 bsnprintf(buf, sizeof(buf), _("Cannot find attribute %s"), attrname);
198 PyErr_SetString(PyExc_AttributeError, errmsg);
203 static PyObject *set_job_events(PyObject *self, PyObject *arg)
208 Dmsg0(100, "In set_job_events.\n");
209 if (!PyArg_ParseTuple(arg, "O:set_events", &eObject)) {
210 Pmsg0(000, _("Error in ParseTuple\n"));
213 jcr = get_jcr_from_PyObject(self);
214 Py_XDECREF((PyObject *)jcr->Python_events);
216 jcr->Python_events = (void *)eObject;
221 static PyObject *job_write(PyObject *self, PyObject *args)
225 if (!PyArg_ParseTuple(args, "s:write", &text)) {
226 Pmsg0(000, _("Parse tuple error in job_write\n"));
230 Jmsg(NULL, M_INFO, 0, "%s", text);
237 int generate_job_event(JCR *jcr, const char *event)
239 PyObject *method = NULL;
240 PyObject *Job = (PyObject *)jcr->Python_job;
241 PyObject *events = (PyObject *)jcr->Python_events;
242 PyObject *result = NULL;
245 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);
272 // PyEval_ReleaseLock();
279 /* Dummy if Python not configured */
280 int generate_job_event(JCR *jcr, const char *event)
284 #endif /* HAVE_PYTHON */