]> git.sur5r.net Git - bacula/bacula/blob - bacula/src/filed/python.c
- Fix new Python code to work for Director.
[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 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 *jcr_get(PyObject *self, PyObject *args);
43 static PyObject *jcr_write(PyObject *self, PyObject *args);
44 static PyObject *jcr_set(PyObject *self, PyObject *args, PyObject *keyw);
45 static PyObject *set_jcr_events(PyObject *self, PyObject *args);
46
47
48 /* Define Job entry points */
49 PyMethodDef JobMethods[] = {
50     {"get", jcr_get, METH_VARARGS, "Get Job variables."},
51     {"set", (PyCFunction)jcr_set, METH_VARARGS|METH_KEYWORDS,
52         "Set Job variables."},
53     {"set_events", set_jcr_events, METH_VARARGS, "Define Job events."},
54     {"write", jcr_write, METH_VARARGS, "Write output."},
55     {NULL, NULL, 0, NULL}             /* last item */
56 };
57
58
59 static PyObject *open_method = NULL;
60 static PyObject *read_method = NULL;
61 static PyObject *close_method = NULL;
62
63
64 struct s_vars {
65    const char *name;
66    char *fmt;
67 };
68
69 /* Read-only variables */
70 static struct s_vars vars[] = {
71    { N_("FDName"),     "s"},          /* 0 */
72    { N_("Level"),      "s"},          /* 1 */
73    { N_("Type"),       "s"},          /* 2 */
74    { N_("JobId"),      "i"},          /* 3 */
75    { N_("Client"),     "s"},          /* 4 */
76    { N_("JobName"),    "s"},          /* 5 */
77    { N_("JobStatus"),  "s"},          /* 6 */
78
79    { NULL,             NULL}
80 };
81
82 /* Return Job variables */
83 PyObject *jcr_get(PyObject *self, PyObject *args)
84 {
85    JCR *jcr;
86    char *item;
87    bool found = false;
88    int i;
89    char buf[10];
90
91    if (!PyArg_ParseTuple(args, "s:get", &item)) {
92       return NULL;
93    }
94    jcr = get_jcr_from_PyObject(self);
95    for (i=0; vars[i].name; i++) {
96       if (strcmp(vars[i].name, item) == 0) {
97          found = true;
98          break;
99       }
100    }
101    if (!found) {
102       return NULL;
103    }
104    switch (i) {
105    case 0:                            /* FD's name */
106       return Py_BuildValue(vars[i].fmt, my_name);
107    case 1:                            /* level */
108       return Py_BuildValue(vars[i].fmt, job_level_to_str(jcr->JobLevel));
109    case 2:                            /* type */
110       return Py_BuildValue(vars[i].fmt, job_type_to_str(jcr->JobType));
111    case 3:                            /* JobId */
112       return Py_BuildValue(vars[i].fmt, jcr->JobId);
113    case 4:                            /* Client */
114       return Py_BuildValue(vars[i].fmt, jcr->client_name);
115    case 5:                            /* JobName */
116       return Py_BuildValue(vars[i].fmt, jcr->Job);
117    case 6:                            /* JobStatus */
118       buf[1] = 0;
119       buf[0] = jcr->JobStatus;
120       return Py_BuildValue(vars[i].fmt, buf);
121    }
122    return NULL;
123 }
124
125 /* Set Job variables */
126 PyObject *jcr_set(PyObject *self, PyObject *args, PyObject *keyw)
127 {
128    JCR *jcr;
129    char *msg = NULL;
130    PyObject *fo = NULL, *fr = NULL, *fc = NULL;
131    static char *kwlist[] = {"JobReport", 
132                  "FileOpen", "FileRead", "FileClose",
133                  NULL};
134    
135    if (!PyArg_ParseTupleAndKeywords(args, keyw, "|sOOO:set", kwlist,
136         &msg, &fo, &fr, &fc)) {
137       return NULL;
138    }
139    jcr = get_jcr_from_PyObject(self);
140    
141    if (msg) {
142       Jmsg(jcr, M_INFO, 0, "%s", msg);
143    }
144    if (strcmp("Reader", jcr->event) == 0) {
145       if (fo) {
146          if (PyCallable_Check(fo)) {
147             jcr->ff->bfd.pio.fo = fo;
148          } else {
149             Jmsg(jcr, M_ERROR, 0, _("Python FileOpen object not callable.\n"));
150          }
151       }
152       if (fr) {
153          if (PyCallable_Check(fo)) {
154             jcr->ff->bfd.pio.fr = fr;
155          } else {
156             Jmsg(jcr, M_ERROR, 0, _("Python FileRead object not callable.\n"));
157          }
158       }
159       if (fc) {
160          if (PyCallable_Check(fc)) {
161             jcr->ff->bfd.pio.fc = fc;
162          } else {
163             Jmsg(jcr, M_ERROR, 0, _("Python FileClose object not callable.\n"));
164          }
165       }
166    } 
167    return Py_BuildValue("i", 1);
168 }
169
170
171 static PyObject *set_jcr_events(PyObject *self, PyObject *args)
172 {
173    PyObject *eObject;
174    JCR *jcr;
175    if (!PyArg_ParseTuple(args, "O:set_events_hook", &eObject)) {
176       return NULL;
177    }
178    Py_XINCREF(eObject);
179    jcr = get_jcr_from_PyObject(self);
180    jcr->ff->bfd.pio.fo = find_method(eObject, open_method, "open");
181    jcr->ff->bfd.pio.fr = find_method(eObject, read_method, "read");
182    jcr->ff->bfd.pio.fc = find_method(eObject, close_method, "close");
183    Py_INCREF(Py_None);
184    return Py_None;
185 }
186
187 /* Write text to job output */
188 static PyObject *jcr_write(PyObject *self, PyObject *args)
189 {
190    char *text;
191    if (!PyArg_ParseTuple(args, "s:write", &text)) {
192       return NULL;
193    }
194    if (text) {
195       JCR *jcr = get_jcr_from_PyObject(self);
196       Jmsg(jcr, M_INFO, 0, "%s", text);
197    }
198         
199    Py_INCREF(Py_None);
200    return Py_None;
201 }
202
203 int generate_job_event(JCR *jcr, const char *event)
204 {
205    PyEval_AcquireLock();
206
207    PyObject *result = PyObject_CallFunction(open_method, "s", "m.py");
208    if (result == NULL) {
209       PyErr_Print();
210       PyErr_Clear();
211    }
212    Py_XDECREF(result);
213
214    PyEval_ReleaseLock();
215    return 1;
216 }
217
218 #else
219
220 /* Dummy if Python not configured */
221 int generate_job_event(JCR *jcr, const char *event)
222 { return 1; }
223
224
225 #endif /* HAVE_PYTHON */