]> git.sur5r.net Git - bacula/bacula/blob - bacula/src/stored/pythonsd.c
kes Add back code to open tape device nonblocking, but if rewind fails
[bacula/bacula] / bacula / src / stored / pythonsd.c
1 /*
2  *
3  * Bacula interface to Python for the Storage Daemon
4  *
5  * Kern Sibbald, January MMV
6  *
7  *   Version $Id$
8  *
9  */
10 /*
11    Copyright (C) 2005-2006 Kern Sibbald
12
13    This program is free software; you can redistribute it and/or
14    modify it under the terms of the GNU General Public License
15    version 2 as amended with additional clauses defined in the
16    file LICENSE in the main source directory.
17
18    This program is distributed in the hope that it will be useful,
19    but WITHOUT ANY WARRANTY; without even the implied warranty of
20    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 
21    the file LICENSE for additional details.
22
23  */
24
25
26 #include "bacula.h"
27 #include "stored.h"
28
29 #ifdef HAVE_PYTHON
30 #undef _POSIX_C_SOURCE
31 #include <Python.h>
32
33 extern JCR *get_jcr_from_PyObject(PyObject *self);
34 extern PyObject *find_method(PyObject *eventsObject, PyObject *method, 
35          const char *name);
36
37 static PyObject *set_job_events(PyObject *self, PyObject *arg);
38 static PyObject *job_write(PyObject *self, PyObject *arg);
39
40 PyMethodDef JobMethods[] = {
41     {"set_events", set_job_events, METH_VARARGS, "Set Job events"},
42     {"write", job_write, METH_VARARGS, "Write to output"},
43     {NULL, NULL, 0, NULL}             /* last item */
44 };
45
46
47 struct s_vars {
48    const char *name;
49    char *fmt;
50 };
51
52 static struct s_vars getvars[] = {
53    { NT_("Job"),        "s"},          /* 0 */
54    { NT_("SDName"),     "s"},          /* 1 */
55    { NT_("Level"),      "s"},          /* 2 */
56    { NT_("Type"),       "s"},          /* 3 */
57    { NT_("JobId"),      "i"},          /* 4 */
58    { NT_("Client"),     "s"},          /* 5 */
59    { NT_("Pool"),       "s"},          /* 6 */
60    { NT_("MediaType"),  "s"},          /* 7 */
61    { NT_("JobName"),    "s"},          /* 8 */
62    { NT_("JobStatus"),  "s"},          /* 9 */
63    { NT_("VolumeName"), "s"},          /* 10 */
64    { NT_("Device"),     "s"},          /* 11 */
65
66    { NULL,             NULL}
67 };
68
69
70 /* Writable variables */
71 static struct s_vars setvars[] = {
72    { NT_("JobReport"),   "s"},
73
74    { NULL,             NULL}
75 };
76
77
78 /* Return Job variables */
79 PyObject *job_getattr(PyObject *self, char *attrname)
80 {
81    JCR *jcr;
82    bool found = false;
83    int i;
84    char buf[10];
85    char errmsg[200];
86    
87    Dmsg1(100, "In job_getattr=%s\n", attrname);
88    jcr = get_jcr_from_PyObject(self);
89    if (!jcr) {
90       bstrncpy(errmsg, _("Job pointer not found."), sizeof(errmsg));
91       goto bail_out;
92    }
93
94    for (i=0; getvars[i].name; i++) {
95       if (strcmp(getvars[i].name, attrname) == 0) {
96          found = true;
97          break;
98       }
99    }
100    if (!found) {
101       /* Try our methods */
102       return Py_FindMethod(JobMethods, self, attrname);
103    }  
104    switch (i) {
105    case 0:                            /* Job */
106       return Py_BuildValue(getvars[i].fmt, jcr->job_name);    /* Non-unique name */
107    case 1:                            /* SD's name */
108       return Py_BuildValue(getvars[i].fmt, my_name);
109    case 2:                            /* level */
110       return Py_BuildValue(getvars[i].fmt, job_level_to_str(jcr->JobLevel));
111    case 3:                            /* type */
112       return Py_BuildValue(getvars[i].fmt, job_type_to_str(jcr->JobType));
113    case 4:                            /* JobId */
114       return Py_BuildValue(getvars[i].fmt, jcr->JobId);
115    case 5:                            /* Client */
116       return Py_BuildValue(getvars[i].fmt, jcr->client_name);
117    case 6:                            /* Pool */
118       return Py_BuildValue(getvars[i].fmt, jcr->dcr->pool_name);
119    case 7:                            /* MediaType */
120       return Py_BuildValue(getvars[i].fmt, jcr->dcr->media_type);
121    case 8:                            /* JobName */
122       return Py_BuildValue(getvars[i].fmt, jcr->Job);
123    case 9:                            /* JobStatus */
124       buf[1] = 0;
125       buf[0] = jcr->JobStatus;
126       return Py_BuildValue(getvars[i].fmt, buf);
127    case 10:
128       return Py_BuildValue(getvars[i].fmt, jcr->dcr->VolumeName);
129    case 11:
130       return Py_BuildValue(getvars[i].fmt, jcr->dcr->dev_name);
131    }
132    bsnprintf(errmsg, sizeof(errmsg), _("Attribute %s not found."), attrname);
133 bail_out:
134    PyErr_SetString(PyExc_AttributeError, errmsg);
135    return NULL;
136 }
137
138 int job_setattr(PyObject *self, char *attrname, PyObject *value)
139 {
140   JCR *jcr;
141    bool found = false;
142    char *strval = NULL;
143    char buf[200];
144    char *errmsg;
145    int i;
146
147    Dmsg2(100, "In job_setattr=%s val=%p.\n", attrname, value);
148    if (value == NULL) {                /* Cannot delete variables */
149       bsnprintf(buf, sizeof(buf), _("Cannot delete attribute %s"), attrname);
150       errmsg = buf;
151       goto bail_out;
152    }
153    jcr = get_jcr_from_PyObject(self);
154    if (!jcr) {
155       errmsg = _("Job pointer not found.");
156       goto bail_out;
157    }
158
159    /* Find attribute name in list */
160    for (i=0; setvars[i].name; i++) {
161       if (strcmp(setvars[i].name, attrname) == 0) {
162          found = true;
163          break;
164       }
165    }
166    if (!found) {
167       goto not_found;
168    }
169    /* Get argument value ***FIXME*** handle other formats */
170    if (setvars[i].fmt != NULL) {
171       if (!PyArg_Parse(value, setvars[i].fmt, &strval)) {
172          PyErr_SetString(PyExc_TypeError, _("Read-only attribute"));
173          return -1;
174       }
175    }   
176    switch (i) {
177    case 0:                            /* JobReport */
178       Jmsg(jcr, M_INFO, 0, "%s", strval);
179       return 0;
180    }
181 not_found:
182    bsnprintf(buf, sizeof(buf), _("Cannot find attribute %s"), attrname);
183    errmsg = buf;
184 bail_out:
185    PyErr_SetString(PyExc_AttributeError, errmsg);
186    return -1;
187 }
188
189
190 static PyObject *set_job_events(PyObject *self, PyObject *arg)
191 {
192    PyObject *eObject;
193    JCR *jcr;
194
195    Dmsg0(100, "In set_job_events.\n");
196    if (!PyArg_ParseTuple(arg, "O:set_events", &eObject)) {
197       Dmsg0(000, _("Error in ParseTuple\n"));
198       return NULL;
199    }
200    jcr = get_jcr_from_PyObject(self);
201    Py_XDECREF((PyObject *)jcr->Python_events);
202    Py_INCREF(eObject);
203    jcr->Python_events = (void *)eObject;
204    Py_INCREF(Py_None);
205    return Py_None;
206 }
207
208 static PyObject *job_write(PyObject *self, PyObject *args)
209 {
210    char *text = NULL;
211
212    if (!PyArg_ParseTuple(args, "s:write", &text)) {
213       Dmsg0(000, _("Parse tuple error in job_write\n"));
214       return NULL;
215    }
216    if (text) {
217       Jmsg(NULL, M_INFO, 0, "%s", text);
218    }
219    Py_INCREF(Py_None);
220    return Py_None;
221 }
222
223
224 int generate_job_event(JCR *jcr, const char *event)
225 {
226    PyObject *method = NULL;
227    PyObject *Job = (PyObject *)jcr->Python_job;
228    PyObject *events = (PyObject *)jcr->Python_events;
229    PyObject *result = NULL;
230    int stat = 0;
231
232    if (!Job || !events) {
233       return 0;
234    }
235
236    lock_python();
237 // PyEval_AcquireLock();
238
239    method = find_method(events, method, event);
240    if (!method) {
241       goto bail_out;
242    }
243
244    bstrncpy(jcr->event, event, sizeof(jcr->event));
245    result = PyObject_CallFunction(method, "O", Job);
246    jcr->event[0] = 0;             /* no event in progress */
247    if (result == NULL) {
248       if (PyErr_Occurred()) {
249          PyErr_Print();
250          Dmsg1(000, _("Error in Python method %s\n"), event);
251       }
252    } else {
253       stat = 1;
254    }
255    Py_XDECREF(result);
256
257 bail_out:
258    unlock_python();
259 // PyEval_ReleaseLock();
260    return stat;
261 }
262
263
264 #else
265
266 /* Dummy if Python not configured */
267 int generate_job_event(JCR *jcr, const char *event)
268 { return 1; }
269
270
271 #endif /* HAVE_PYTHON */