]> git.sur5r.net Git - bacula/bacula/blob - bacula/src/filed/python.c
Update projects
[bacula/bacula] / bacula / src / filed / python.c
1 /*
2  *
3  * Bacula interface to Python for the File Daemon
4  *
5  * Kern Sibbald, March 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 "filed.h"
33
34 #ifdef HAVE_PYTHON
35 #undef _POSIX_C_SOURCE
36 #include <Python.h>
37
38 /* External function pointers to be set */
39 extern bool    (*python_set_prog)(JCR *jcr, const char *prog);
40 extern int     (*python_open)(BFILE *bfd, const char *fname, int flags, mode_t mode);
41 extern int     (*python_close)(BFILE *bfd);
42 extern ssize_t (*python_read)(BFILE *bfd, void *buf, size_t count);
43
44
45 extern JCR *get_jcr_from_PyObject(PyObject *self);
46 extern PyObject *find_method(PyObject *eventsObject, PyObject *method, 
47           const char *name);
48
49 /* Forward referenced functions */
50 static PyObject *job_get(PyObject *self, PyObject *args);
51 static PyObject *job_write(PyObject *self, PyObject *args);
52 static PyObject *job_set(PyObject *self, PyObject *args, PyObject *keyw);
53 static PyObject *set_job_events(PyObject *self, PyObject *args);
54
55 bool my_python_set_prog(JCR *jcr, const char *prog);
56 int my_python_open(BFILE *bfd, const char *fname, int flags, mode_t mode);
57 int my_python_close(BFILE *bfd);
58 ssize_t my_python_read(BFILE *bfd, void *buf, size_t count);
59
60
61 /* Define Job entry points */
62 PyMethodDef JobMethods[] = {
63     {"get", job_get, METH_VARARGS, "Get Job variables."},
64     {"set", (PyCFunction)job_set, METH_VARARGS|METH_KEYWORDS,
65         "Set Job variables."},
66     {"set_events", set_job_events, METH_VARARGS, "Define Job events."},
67     {"write", job_write, METH_VARARGS, "Write output."},
68     {NULL, NULL, 0, NULL}             /* last item */
69 };
70
71 struct s_vars {
72    const char *name;
73    char *fmt;
74 };
75
76 /* Read-only variables */
77 static struct s_vars vars[] = {
78    { N_("FDName"),     "s"},          /* 0 */
79    { N_("Level"),      "s"},          /* 1 */
80    { N_("Type"),       "s"},          /* 2 */
81    { N_("JobId"),      "i"},          /* 3 */
82    { N_("Client"),     "s"},          /* 4 */
83    { N_("JobName"),    "s"},          /* 5 */
84    { N_("JobStatus"),  "s"},          /* 6 */
85
86    { NULL,             NULL}
87 };
88
89 /* Return Job variables */
90 PyObject *job_get(PyObject *self, PyObject *args)
91 {
92    JCR *jcr;
93    char *item;
94    bool found = false;
95    int i;
96    char buf[10];
97
98    if (!PyArg_ParseTuple(args, "s:get", &item)) {
99       return NULL;
100    }
101    jcr = get_jcr_from_PyObject(self);
102    for (i=0; vars[i].name; i++) {
103       if (strcmp(vars[i].name, item) == 0) {
104          found = true;
105          break;
106       }
107    }
108    if (!found) {
109       return NULL;
110    }
111    switch (i) {
112    case 0:                            /* FD's name */
113       return Py_BuildValue(vars[i].fmt, my_name);
114    case 1:                            /* level */
115       return Py_BuildValue(vars[i].fmt, job_level_to_str(jcr->JobLevel));
116    case 2:                            /* type */
117       return Py_BuildValue(vars[i].fmt, job_type_to_str(jcr->JobType));
118    case 3:                            /* JobId */
119       return Py_BuildValue(vars[i].fmt, jcr->JobId);
120    case 4:                            /* Client */
121       return Py_BuildValue(vars[i].fmt, jcr->client_name);
122    case 5:                            /* JobName */
123       return Py_BuildValue(vars[i].fmt, jcr->Job);
124    case 6:                            /* JobStatus */
125       buf[1] = 0;
126       buf[0] = jcr->JobStatus;
127       return Py_BuildValue(vars[i].fmt, buf);
128    }
129    return NULL;
130 }
131
132 /* Set Job variables */
133 PyObject *job_set(PyObject *self, PyObject *args, PyObject *keyw)
134 {
135    JCR *jcr;
136    char *msg = NULL;
137    static char *kwlist[] = {"JobReport", NULL};
138    
139    if (!PyArg_ParseTupleAndKeywords(args, keyw, "|s:set", kwlist,
140         &msg)) {
141       return NULL;
142    }
143    jcr = get_jcr_from_PyObject(self);
144    
145    if (msg) {
146       Jmsg(jcr, M_INFO, 0, "%s", msg);
147    }
148    return Py_BuildValue("i", 1);
149 }
150
151
152 static PyObject *set_job_events(PyObject *self, PyObject *args)
153 {
154    PyObject *eObject;
155    JCR *jcr;
156
157    Dmsg0(100, "In set_job_events.\n");
158
159    if (!PyArg_ParseTuple(args, "O:set_events", &eObject)) {
160       return NULL;
161    }
162    jcr = get_jcr_from_PyObject(self);
163    Py_XDECREF((PyObject *)jcr->Python_events);
164    Py_INCREF(eObject);
165    jcr->Python_events = (void *)eObject;
166
167    /* Set function pointers to call here */
168    python_set_prog = my_python_set_prog;
169    python_open     = my_python_open;
170    python_close    = my_python_close;
171    python_read     = my_python_read;
172
173    Py_INCREF(Py_None);
174    return Py_None;
175 }
176
177 /* Write text to job output */
178 static PyObject *job_write(PyObject *self, PyObject *args)
179 {
180    char *text = NULL;
181
182    if (!PyArg_ParseTuple(args, "s:write", &text)) {
183       return NULL;
184    }
185    if (text) {
186       JCR *jcr = get_jcr_from_PyObject(self);
187       Jmsg(jcr, M_INFO, 0, "%s", text);
188    }
189         
190    Py_INCREF(Py_None);
191    return Py_None;
192 }
193
194 int generate_job_event(JCR *jcr, const char *event)
195 {
196    PyObject *method = NULL;
197    PyObject *Job = (PyObject *)jcr->Python_job;
198    PyObject *result = NULL;
199    int stat = 0;
200
201    if (!Job) {
202       return 0;
203    }
204
205    PyEval_AcquireLock();
206
207    PyObject *events = (PyObject *)jcr->Python_events;
208    method = find_method(events, method, event);
209    if (!method) {
210       goto bail_out;
211    }
212
213    bstrncpy(jcr->event, event, sizeof(jcr->event));
214    result = PyObject_CallFunction(method, "O", Job);
215    jcr->event[0] = 0;             /* no event in progress */
216    if (result == NULL) {
217       if (PyErr_Occurred()) {
218          PyErr_Print();
219          Dmsg1(000, "Error in Python method %s\n", event);
220       }
221    } else {
222       stat = 1;
223    }
224    Py_XDECREF(result);
225
226 bail_out:
227    PyEval_ReleaseLock();
228    return stat;
229 }
230
231
232 bool my_python_set_prog(JCR *jcr, const char *prog)
233 {
234    PyObject *events = (PyObject *)jcr->Python_events;
235    BFILE *bfd = &jcr->ff->bfd;
236    char method[MAX_NAME_LENGTH];
237
238    if (!events) {
239       return false;
240    }
241    bstrncpy(method, prog, sizeof(method));
242    bstrncat(method, "_", sizeof(method));
243    bstrncat(method, "open", sizeof(method));
244    bfd->pio.fo = find_method(events, bfd->pio.fo, method);
245    bstrncpy(method, prog, sizeof(method));
246    bstrncat(method, "_", sizeof(method));
247    bstrncat(method, "read", sizeof(method));
248    bfd->pio.fr = find_method(events, bfd->pio.fr, method);
249    bstrncpy(method, prog, sizeof(method));
250    bstrncat(method, "_", sizeof(method));
251    bstrncat(method, "close", sizeof(method));
252    bfd->pio.fc = find_method(events, bfd->pio.fc, method);
253    return bfd->pio.fo && bfd->pio.fr && bfd->pio.fc;
254 }
255
256 int my_python_open(BFILE *bfd, const char *fname, int flags, mode_t mode)
257 {
258    return -1;
259 }
260
261 int my_python_close(BFILE *bfd) 
262 {
263    return 0;
264 }
265
266 ssize_t my_python_read(BFILE *bfd, void *buf, size_t count)
267 {
268    return -1;
269 }
270
271 #else
272
273 /* Dummy if Python not configured */
274 int generate_job_event(JCR *jcr, const char *event)
275 { return 1; }
276
277
278 #endif /* HAVE_PYTHON */