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