]> git.sur5r.net Git - bacula/bacula/blob - bacula/src/dird/pythondir.c
9869753cef5272d42a9a50478685adced5aef148
[bacula/bacula] / bacula / src / dird / pythondir.c
1 /*
2  *
3  * Bacula interface to Python for the Director
4  *
5  * Kern Sibbald, November MMIV
6  *
7  *   Version $Id$
8  *
9  */
10
11 /*
12    Copyright (C) 2004-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 "dird.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 static int job_run(PyObject *self, PyObject *arg);
44
45 struct s_vars {
46    const char *name;
47    char *fmt;
48 };
49
50 /* Read-only variables */
51 static struct s_vars getvars[] = {
52    { N_("Job"),        "s"},
53    { N_("DirName"),    "s"},
54    { N_("Level"),      "s"},
55    { N_("Type"),       "s"},
56    { N_("JobId"),      "i"},
57    { N_("Client"),     "s"},
58    { N_("NumVols"),    "i"},
59    { N_("Pool"),       "s"},
60    { N_("Storage"),    "s"},
61    { N_("Catalog"),    "s"},
62    { N_("MediaType"),  "s"},
63    { N_("JobName"),    "s"},
64    { N_("JobStatus"),  "s"},
65
66    { NULL,             NULL}
67 };
68
69 /* Writable variables */
70 static struct s_vars setvars[] = {
71    { N_("set_events"), NULL},
72    { N_("run"),        NULL},
73    { N_("JobReport"),   "s"},
74    { N_("write"),       "s"},
75    { N_("VolumeName") , "s"},
76
77    { NULL,             NULL}
78 };
79
80
81 /* Return Job variables */
82 /* Returns:  NULL if error
83  *           PyObject * return value if OK
84  */
85 PyObject *job_getattr(PyObject *self, char *attrname)
86 {
87    JCR *jcr;
88    bool found = false;
89    int i;
90    char buf[10];
91    char errmsg[200];
92
93    Dmsg0(100, "In job_getattr.\n");
94    jcr = get_jcr_from_PyObject(self);
95    if (!jcr) {
96       bstrncpy(errmsg, "Job pointer not found.", sizeof(errmsg));
97       goto bail_out;
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       goto not_found;
107    }
108    switch (i) {
109    case 0:                            /* Job */
110       return Py_BuildValue(getvars[i].fmt, jcr->job->hdr.name);
111    case 1:                            /* Director's name */
112       return Py_BuildValue(getvars[i].fmt, my_name);
113    case 2:                            /* level */
114       return Py_BuildValue(getvars[i].fmt, job_level_to_str(jcr->JobLevel));
115    case 3:                            /* type */
116       return Py_BuildValue(getvars[i].fmt, job_type_to_str(jcr->JobType));
117    case 4:                            /* JobId */
118       return Py_BuildValue(getvars[i].fmt, jcr->JobId);
119    case 5:                            /* Client */
120       return Py_BuildValue(getvars[i].fmt, jcr->client->hdr.name);
121    case 6:                            /* NumVols */
122       return Py_BuildValue(getvars[i].fmt, jcr->NumVols);
123    case 7:                            /* Pool */
124       return Py_BuildValue(getvars[i].fmt, jcr->pool->hdr.name);
125    case 8:                            /* Storage */
126       return Py_BuildValue(getvars[i].fmt, jcr->store->hdr.name);
127    case 9:
128       return Py_BuildValue(getvars[i].fmt, jcr->catalog->hdr.name);
129    case 10:                           /* MediaType */
130       return Py_BuildValue(getvars[i].fmt, jcr->store->media_type);
131    case 11:                           /* JobName */
132       return Py_BuildValue(getvars[i].fmt, jcr->Job);
133    case 12:                           /* JobStatus */
134       buf[1] = 0;
135       buf[0] = jcr->JobStatus;
136       return Py_BuildValue(getvars[i].fmt, buf);
137    }
138 not_found:
139    bsnprintf(errmsg, sizeof(errmsg), "Attribute %s not found.", attrname);
140 bail_out:
141    PyErr_SetString(PyExc_AttributeError, errmsg);
142    return NULL;
143 }
144
145
146 /* Set Job variables */
147 /*  Returns:   0 for OK
148  *            -1 for error
149  */
150 int job_setattr(PyObject *self, char *attrname, PyObject *value)
151 {
152    JCR *jcr;
153    bool found = false;
154    char *strval = NULL;
155    int i;
156
157    Dmsg2(100, "In job_setattr=%s val=%p.\n", attrname, value);
158    if (value == NULL) {                /* Cannot delete variables */
159        goto bail_out;
160    }
161    jcr = get_jcr_from_PyObject(self);
162    if (!jcr) {
163       goto bail_out;
164    }
165
166    /* Find attribute name in list */
167    for (i=0; setvars[i].name; i++) {
168       if (strcmp(setvars[i].name, attrname) == 0) {
169          found = true;
170          break;
171       }
172    }
173    if (!found) {
174       goto bail_out;
175    }
176    /* Get argument value ***FIXME*** handle other formats */
177    if (setvars[i].fmt != NULL) {
178       if (!PyArg_Parse(value, setvars[i].fmt, &strval)) {
179          PyErr_SetString(PyExc_TypeError, "Read-only attribute");
180          return -1;
181       }
182    }   
183    switch (i) {
184    case 0:                            /* set_events */
185       return set_job_events(self, value);
186    case 1:                            /* run */
187       return job_run(self, value);
188    case 2:                            /* JobReport */
189    case 3:                            /* write */
190       Jmsg(jcr, M_INFO, 0, "%s", strval);
191       return 0;
192    case 4:                            /* VolumeName */
193       /* Make sure VolumeName is valid and we are in VolumeName event */
194       if (strcmp("NewVolume", jcr->event) == 0 &&
195           is_volume_name_legal(NULL, strval)) {
196          pm_strcpy(jcr->VolumeName, strval);
197          Dmsg1(100, "Set Vol=%s\n", strval);
198          return 0;
199       } else {
200          jcr->VolumeName[0] = 0;
201       }
202    }
203 bail_out:
204    PyErr_SetString(PyExc_AttributeError, attrname);
205    return -1;
206 }
207
208
209 static int set_job_events(PyObject *self, PyObject *arg)
210 {
211    PyObject *eObject;
212    JCR *jcr;
213
214    Dmsg0(100, "In set_job_events.\n");
215    if (!PyArg_Parse(arg, "O", &eObject)) {
216       return -1;
217    }
218    jcr = get_jcr_from_PyObject(self);
219    Py_XDECREF((PyObject *)jcr->Python_events);
220    Py_INCREF(eObject);
221    jcr->Python_events = (void *)eObject;
222    return 0;                    /* good return */
223 }
224
225 /* Run a Bacula command */
226 static int job_run(PyObject *self, PyObject *arg)
227 {
228    JCR *jcr;
229    char *item;
230    int stat;
231
232    if (!PyArg_Parse(arg, "s", &item)) {
233       return -1;
234    }
235    jcr = get_jcr_from_PyObject(self);
236    UAContext *ua = new_ua_context(jcr);
237    ua->batch = true;
238    pm_strcpy(ua->cmd, item);          /* copy command */
239    parse_ua_args(ua);                 /* parse command */
240    stat = run_cmd(ua, ua->cmd);
241    free_ua_context(ua);
242    /* ***FIXME*** check stat */
243    return 0;
244 }
245
246
247 int generate_job_event(JCR *jcr, const char *event)
248 {
249    PyObject *method = NULL;
250    PyObject *Job = (PyObject *)jcr->Python_job;
251    PyObject *result = NULL;
252    int stat = 0;
253
254    if (!Job) {
255       return 0;
256    }
257
258    PyEval_AcquireLock();
259
260    PyObject *events = (PyObject *)jcr->Python_events;
261    method = find_method(events, method, event);
262    if (!method) {
263       goto bail_out;
264    }
265
266    bstrncpy(jcr->event, event, sizeof(jcr->event));
267    result = PyObject_CallFunction(method, "O", Job);
268    jcr->event[0] = 0;             /* no event in progress */
269    if (result == NULL) {
270       if (PyErr_Occurred()) {
271          PyErr_Print();
272          Dmsg1(000, "Error in Python method %s\n", event);
273       }
274    } else {
275       stat = 1;
276    }
277    Py_XDECREF(result);
278
279 bail_out:
280    PyEval_ReleaseLock();
281    return stat;
282 }
283
284 bool python_set_prog(JCR*, char const*) { return false; }
285
286 #else
287
288 /* Dummy if Python not configured */
289 int generate_job_event(JCR *jcr, const char *event) { return 1; }
290    
291
292 #endif /* HAVE_PYTHON */