]> git.sur5r.net Git - bacula/bacula/blob - bacula/src/stored/pythonsd.c
85ca46ed2e741a8e180b20a149847e4d6f98c18c
[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 int set_job_events(PyObject *self, PyObject *arg);
43
44
45 struct s_vars {
46    const char *name;
47    char *fmt;
48 };
49
50 static struct s_vars getvars[] = {
51    { N_("Job"),        "s"},          /* 0 */
52    { N_("SDName"),     "s"},          /* 1 */
53    { N_("Level"),      "s"},          /* 2 */
54    { N_("Type"),       "s"},          /* 3 */
55    { N_("JobId"),      "i"},          /* 4 */
56    { N_("Client"),     "s"},          /* 5 */
57    { N_("Pool"),       "s"},          /* 6 */
58    { N_("MediaType"),  "s"},          /* 7 */
59    { N_("JobName"),    "s"},          /* 8 */
60    { N_("JobStatus"),  "s"},          /* 9 */
61    { N_("VolumeName"), "s"},          /* 10 */
62    { N_("Device"),     "s"},          /* 11 */
63
64    { NULL,             NULL}
65 };
66
67
68 /* Writable variables */
69 static struct s_vars setvars[] = {
70    { N_("set_events"), NULL},
71    { N_("JobReport"),   "s"},
72    { N_("write"),       "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       goto not_found;
102    }  
103    switch (i) {
104    case 0:                            /* Job */
105       return Py_BuildValue(getvars[i].fmt, jcr->job_name);    /* Non-unique name */
106    case 1:                            /* SD's name */
107       return Py_BuildValue(getvars[i].fmt, my_name);
108    case 2:                            /* level */
109       return Py_BuildValue(getvars[i].fmt, job_level_to_str(jcr->JobLevel));
110    case 3:                            /* type */
111       return Py_BuildValue(getvars[i].fmt, job_type_to_str(jcr->JobType));
112    case 4:                            /* JobId */
113       return Py_BuildValue(getvars[i].fmt, jcr->JobId);
114    case 5:                            /* Client */
115       return Py_BuildValue(getvars[i].fmt, jcr->client_name);
116    case 6:                            /* Pool */
117       return Py_BuildValue(getvars[i].fmt, jcr->dcr->pool_name);
118    case 7:                            /* MediaType */
119       return Py_BuildValue(getvars[i].fmt, jcr->dcr->media_type);
120    case 8:                            /* JobName */
121       return Py_BuildValue(getvars[i].fmt, jcr->Job);
122    case 9:                            /* JobStatus */
123       buf[1] = 0;
124       buf[0] = jcr->JobStatus;
125       return Py_BuildValue(getvars[i].fmt, buf);
126    case 10:
127       return Py_BuildValue(getvars[i].fmt, jcr->dcr->VolumeName);
128    case 11:
129       return Py_BuildValue(getvars[i].fmt, jcr->dcr->dev_name);
130    }
131 not_found:
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:                            /* set_events */
178       return set_job_events(self, value);
179    case 1:                            /* JobReport */
180    case 2:                            /* write */
181       Jmsg(jcr, M_INFO, 0, "%s", strval);
182       return 0;
183    }
184 not_found:
185    bsnprintf(buf, sizeof(buf), "Cannot find attribute %s", attrname);
186    errmsg = buf;
187 bail_out:
188    PyErr_SetString(PyExc_AttributeError, errmsg);
189    return -1;
190 }
191
192
193 static int set_job_events(PyObject *self, PyObject *arg)
194 {
195    PyObject *eObject;
196    JCR *jcr;
197
198    Dmsg0(100, "In set_job_events.\n");
199    if (!PyArg_Parse(arg, "O", &eObject)) {
200       Dmsg0(000, "Parse error looking for Object argument\n");
201       return -1;
202    }
203    jcr = get_jcr_from_PyObject(self);
204    if (!jcr) {
205       PyErr_SetString(PyExc_AttributeError, "Job pointer not found.");
206       return -1;
207    }
208    Py_XDECREF((PyObject *)jcr->Python_events);  /* release any old events Object */
209    Py_INCREF(eObject);
210    jcr->Python_events = (void *)eObject;        /* set new events */
211
212    return 0;
213 }
214
215
216 int generate_job_event(JCR *jcr, const char *event)
217 {
218    PyObject *method = NULL;
219    PyObject *Job = (PyObject *)jcr->Python_job;
220    PyObject *result = NULL;
221    int stat = 0;
222
223    if (!Job) {
224       return 0;
225    }
226
227    PyEval_AcquireLock();
228
229    PyObject *events = (PyObject *)jcr->Python_events;
230    method = find_method(events, method, event);
231    if (!method) {
232       goto bail_out;
233    }
234
235    bstrncpy(jcr->event, event, sizeof(jcr->event));
236    result = PyObject_CallFunction(method, "O", Job);
237    jcr->event[0] = 0;             /* no event in progress */
238    if (result == NULL) {
239       if (PyErr_Occurred()) {
240          PyErr_Print();
241          Dmsg1(000, "Error in Python method %s\n", event);
242       }
243    } else {
244       stat = 1;
245    }
246    Py_XDECREF(result);
247
248 bail_out:
249    PyEval_ReleaseLock();
250    return stat;
251 }
252
253
254 #else
255
256 /* Dummy if Python not configured */
257 int generate_job_event(JCR *jcr, const char *event)
258 { return 1; }
259
260
261 #endif /* HAVE_PYTHON */