python plugin: Check return value of malloc().
[collectd.git] / src / python.c
1 /**
2  * collectd - src/python.c
3  * Copyright (C) 2009  Sven Trenkel
4  *
5  * Permission is hereby granted, free of charge, to any person obtaining a
6  * copy of this software and associated documentation files (the "Software"),
7  * to deal in the Software without restriction, including without limitation
8  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
9  * and/or sell copies of the Software, and to permit persons to whom the
10  * Software is furnished to do so, subject to the following conditions:
11  *
12  * The above copyright notice and this permission notice shall be included in
13  * all copies or substantial portions of the Software.
14  *
15  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
21  * DEALINGS IN THE SOFTWARE.
22  *
23  * Authors:
24  *   Sven Trenkel <collectd at semidefinite.de>  
25  **/
26
27 #include <Python.h>
28 #include <structmember.h>
29
30 #include <signal.h>
31 #if HAVE_PTHREAD_H
32 # include <pthread.h>
33 #endif
34
35 #include "collectd.h"
36 #include "common.h"
37
38 #include "cpython.h"
39
40 typedef struct cpy_callback_s {
41         char *name;
42         PyObject *callback;
43         PyObject *data;
44         struct cpy_callback_s *next;
45 } cpy_callback_t;
46
47 static char log_doc[] = "This function sends a string to all logging plugins.";
48
49 static char flush_doc[] = "flush([plugin][, timeout][, identifier]) -> None\n"
50                 "\n"
51                 "Flushes the cache of another plugin.";
52
53 static char unregister_doc[] = "Unregisters a callback. This function needs exactly one parameter either\n"
54                 "the function to unregister or the callback identifier to unregister.";
55
56 static char reg_log_doc[] = "register_log(callback[, data][, name]) -> identifier\n"
57                 "\n"
58                 "Register a callback function for log messages.\n"
59                 "\n"
60                 "'callback' is a callable object that will be called every time something\n"
61                 "    is logged.\n"
62                 "'data' is an optional object that will be passed back to the callback\n"
63                 "    function every time it is called.\n"
64                 "'name' is an optional identifier for this callback. The default name\n"
65                 "    is 'python.<module>'.\n"
66                 "    Every callback needs a unique identifier, so if you want to\n"
67                 "    register this callback multiple time from the same module you need\n"
68                 "    to specify a name here.\n"
69                 "'identifier' is the full identifier assigned to this callback.\n"
70                 "\n"
71                 "The callback function will be called with two or three parameters:\n"
72                 "severity: An integer that should be compared to the LOG_ constants.\n"
73                 "message: The text to be logged.\n"
74                 "data: The optional data parameter passed to the register function.\n"
75                 "    If the parameter was omitted it will be omitted here, too.";
76
77 static char reg_init_doc[] = "register_init(callback[, data][, name]) -> identifier\n"
78                 "\n"
79                 "Register a callback function that will be executed once after the config.\n"
80                 "file has been read, all plugins heve been loaded and the collectd has\n"
81                 "forked into the background.\n"
82                 "\n"
83                 "'callback' is a callable object that will be executed.\n"
84                 "'data' is an optional object that will be passed back to the callback\n"
85                 "    function when it is called.\n"
86                 "'name' is an optional identifier for this callback. The default name\n"
87                 "    is 'python.<module>'.\n"
88                 "    Every callback needs a unique identifier, so if you want to\n"
89                 "    register this callback multiple time from the same module you need\n"
90                 "    to specify a name here.\n"
91                 "'identifier' is the full identifier assigned to this callback.\n"
92                 "\n"
93                 "The callback function will be called without parameters, except for\n"
94                 "data if it was supplied.";
95
96 static char reg_config_doc[] = "register_config(callback[, data][, name]) -> identifier\n"
97                 "\n"
98                 "Register a callback function for config file entries.\n"
99                 "'callback' is a callable object that will be called for every config block.\n"
100                 "'data' is an optional object that will be passed back to the callback\n"
101                 "    function every time it is called.\n"
102                 "'name' is an optional identifier for this callback. The default name\n"
103                 "    is 'python.<module>'.\n"
104                 "    Every callback needs a unique identifier, so if you want to\n"
105                 "    register this callback multiple time from the same module you need\n"
106                 "    to specify a name here.\n"
107                 "'identifier' is the full identifier assigned to this callback.\n"
108                 "\n"
109                 "The callback function will be called with one or two parameters:\n"
110                 "config: A Config object.\n"
111                 "data: The optional data parameter passed to the register function.\n"
112                 "    If the parameter was omitted it will be omitted here, too.";
113
114 static char reg_read_doc[] = "register_read(callback[, interval][, data][, name]) -> identifier\n"
115                 "\n"
116                 "Register a callback function for reading data. It will just be called\n"
117                 "in a fixed interval to signal that it's time to dispatch new values.\n"
118                 "'callback' is a callable object that will be called every time something\n"
119                 "    is logged.\n"
120                 "'interval' is the number of seconds between between calls to the callback\n"
121                 "    function. Full float precision is supported here.\n"
122                 "'data' is an optional object that will be passed back to the callback\n"
123                 "    function every time it is called.\n"
124                 "'name' is an optional identifier for this callback. The default name\n"
125                 "    is 'python.<module>'.\n"
126                 "    Every callback needs a unique identifier, so if you want to\n"
127                 "    register this callback multiple time from the same module you need\n"
128                 "    to specify a name here.\n"
129                 "'identifier' is the full identifier assigned to this callback.\n"
130                 "\n"
131                 "The callback function will be called without parameters, except for\n"
132                 "data if it was supplied.";
133
134 static char reg_write_doc[] = "register_write(callback[, data][, name]) -> identifier\n"
135                 "\n"
136                 "Register a callback function to receive values dispatched by other plugins.\n"
137                 "'callback' is a callable object that will be called every time a value\n"
138                 "    is dispatched.\n"
139                 "'data' is an optional object that will be passed back to the callback\n"
140                 "    function every time it is called.\n"
141                 "'name' is an optional identifier for this callback. The default name\n"
142                 "    is 'python.<module>'.\n"
143                 "    Every callback needs a unique identifier, so if you want to\n"
144                 "    register this callback multiple time from the same module you need\n"
145                 "    to specify a name here.\n"
146                 "'identifier' is the full identifier assigned to this callback.\n"
147                 "\n"
148                 "The callback function will be called with one or two parameters:\n"
149                 "values: A Values object which is a copy of the dispatched values.\n"
150                 "data: The optional data parameter passed to the register function.\n"
151                 "    If the parameter was omitted it will be omitted here, too.";
152
153 static char reg_notification_doc[] = "register_notification(callback[, data][, name]) -> identifier\n"
154                 "\n"
155                 "Register a callback function for notifications.\n"
156                 "'callback' is a callable object that will be called every time a notification\n"
157                 "    is dispatched.\n"
158                 "'data' is an optional object that will be passed back to the callback\n"
159                 "    function every time it is called.\n"
160                 "'name' is an optional identifier for this callback. The default name\n"
161                 "    is 'python.<module>'.\n"
162                 "    Every callback needs a unique identifier, so if you want to\n"
163                 "    register this callback multiple time from the same module you need\n"
164                 "    to specify a name here.\n"
165                 "'identifier' is the full identifier assigned to this callback.\n"
166                 "\n"
167                 "The callback function will be called with one or two parameters:\n"
168                 "notification: A copy of the notification that was dispatched.\n"
169                 "data: The optional data parameter passed to the register function.\n"
170                 "    If the parameter was omitted it will be omitted here, too.";
171
172 static char reg_flush_doc[] = "register_flush(callback[, data][, name]) -> identifier\n"
173                 "\n"
174                 "Register a callback function for flush messages.\n"
175                 "'callback' is a callable object that will be called every time a plugin\n"
176                 "    requests a flush for either this or all plugins.\n"
177                 "'data' is an optional object that will be passed back to the callback\n"
178                 "    function every time it is called.\n"
179                 "'name' is an optional identifier for this callback. The default name\n"
180                 "    is 'python.<module>'.\n"
181                 "    Every callback needs a unique identifier, so if you want to\n"
182                 "    register this callback multiple time from the same module you need\n"
183                 "    to specify a name here.\n"
184                 "'identifier' is the full identifier assigned to this callback.\n"
185                 "\n"
186                 "The callback function will be called with two or three parameters:\n"
187                 "timeout: Indicates that only data older than 'timeout' seconds is to\n"
188                 "    be flushed.\n"
189                 "id: Specifies which values are to be flushed.\n"
190                 "data: The optional data parameter passed to the register function.\n"
191                 "    If the parameter was omitted it will be omitted here, too.";
192
193 static char reg_shutdown_doc[] = "register_shutdown(callback[, data][, name]) -> identifier\n"
194                 "\n"
195                 "Register a callback function for collectd shutdown.\n"
196                 "'callback' is a callable object that will be called once collectd is\n"
197                 "    shutting down.\n"
198                 "'data' is an optional object that will be passed back to the callback\n"
199                 "    function if it is called.\n"
200                 "'name' is an optional identifier for this callback. The default name\n"
201                 "    is 'python.<module>'.\n"
202                 "    Every callback needs a unique identifier, so if you want to\n"
203                 "    register this callback multiple time from the same module you need\n"
204                 "    to specify a name here.\n"
205                 "'identifier' is the full identifier assigned to this callback.\n"
206                 "\n"
207                 "The callback function will be called with no parameters except for\n"
208                 "    data if it was supplied.";
209
210
211 static int do_interactive = 0;
212
213 /* This is our global thread state. Python saves some stuff in thread-local
214  * storage. So if we allow the interpreter to run in the background
215  * (the scriptwriters might have created some threads from python), we have
216  * to save the state so we can resume it later after shutdown. */
217
218 static PyThreadState *state;
219
220 static PyObject *sys_path, *cpy_format_exception;
221
222 static cpy_callback_t *cpy_config_callbacks;
223 static cpy_callback_t *cpy_init_callbacks;
224 static cpy_callback_t *cpy_shutdown_callbacks;
225
226 static void cpy_destroy_user_data(void *data) {
227         cpy_callback_t *c = data;
228         free(c->name);
229         Py_DECREF(c->callback);
230         Py_XDECREF(c->data);
231         free(c);
232 }
233
234 /* You must hold the GIL to call this function!
235  * But if you managed to extract the callback parameter then you probably already do. */
236
237 static void cpy_build_name(char *buf, size_t size, PyObject *callback, const char *name) {
238         const char *module = NULL;
239         PyObject *mod = NULL;
240         
241         if (name != NULL) {
242                 snprintf(buf, size, "python.%s", name);
243                 return;
244         }
245         
246         mod = PyObject_GetAttrString(callback, "__module__"); /* New reference. */
247         if (mod != NULL)
248                 module = cpy_unicode_or_bytes_to_string(&mod);
249         
250         if (module != NULL) {
251                 snprintf(buf, size, "python.%s", module);
252                 Py_XDECREF(mod);
253                 PyErr_Clear();
254                 return;
255         }
256         Py_XDECREF(mod);
257         
258         snprintf(buf, size, "python.%p", callback);
259         PyErr_Clear();
260 }
261
262 void cpy_log_exception(const char *context) {
263         int l = 0, i;
264         const char *typename = NULL, *message = NULL;
265         PyObject *type, *value, *traceback, *tn, *m, *list;
266         
267         PyErr_Fetch(&type, &value, &traceback);
268         PyErr_NormalizeException(&type, &value, &traceback);
269         if (type == NULL) return;
270         tn = PyObject_GetAttrString(type, "__name__"); /* New reference. */
271         m = PyObject_Str(value); /* New reference. */
272         if (tn != NULL)
273                 typename = cpy_unicode_or_bytes_to_string(&tn);
274         if (m != NULL)
275                 message = cpy_unicode_or_bytes_to_string(&m);
276         if (typename == NULL)
277                 typename = "NamelessException";
278         if (message == NULL)
279                 message = "N/A";
280         Py_BEGIN_ALLOW_THREADS
281         ERROR("Unhandled python exception in %s: %s: %s", context, typename, message);
282         Py_END_ALLOW_THREADS
283         Py_XDECREF(tn);
284         Py_XDECREF(m);
285         if (!cpy_format_exception || !traceback) {
286                 PyErr_Clear();
287                 Py_DECREF(type);
288                 Py_XDECREF(value);
289                 Py_XDECREF(traceback);
290                 return;
291         }
292         list = PyObject_CallFunction(cpy_format_exception, "NNN", type, value, traceback); /* New reference. Steals references from "type", "value" and "traceback". */
293         if (list)
294                 l = PyObject_Length(list);
295         for (i = 0; i < l; ++i) {
296                 char *s;
297                 PyObject *line;
298                 
299                 line = PyList_GET_ITEM(list, i); /* Borrowed reference. */
300                 Py_INCREF(line);
301                 s = strdup(cpy_unicode_or_bytes_to_string(&line));
302                 Py_DECREF(line);
303                 if (s[strlen(s) - 1] == '\n')
304                         s[strlen(s) - 1] = 0;
305                 Py_BEGIN_ALLOW_THREADS
306                 ERROR("%s", s);
307                 Py_END_ALLOW_THREADS
308                 free(s);
309         }
310         Py_XDECREF(list);
311         PyErr_Clear();
312 }
313
314 static int cpy_read_callback(user_data_t *data) {
315         cpy_callback_t *c = data->data;
316         PyObject *ret;
317
318         CPY_LOCK_THREADS
319                 ret = PyObject_CallFunctionObjArgs(c->callback, c->data, (void *) 0); /* New reference. */
320                 if (ret == NULL) {
321                         cpy_log_exception("read callback");
322                 } else {
323                         Py_DECREF(ret);
324                 }
325         CPY_RELEASE_THREADS
326         if (ret == NULL)
327                 return 1;
328         return 0;
329 }
330
331 static int cpy_write_callback(const data_set_t *ds, const value_list_t *value_list, user_data_t *data) {
332         int i;
333         cpy_callback_t *c = data->data;
334         PyObject *ret, *list, *temp, *dict = NULL;
335         Values *v;
336
337         CPY_LOCK_THREADS
338                 list = PyList_New(value_list->values_len); /* New reference. */
339                 if (list == NULL) {
340                         cpy_log_exception("write callback");
341                         CPY_RETURN_FROM_THREADS 0;
342                 }
343                 for (i = 0; i < value_list->values_len; ++i) {
344                         if (ds->ds[i].type == DS_TYPE_COUNTER) {
345                                 if ((long) value_list->values[i].counter == value_list->values[i].counter)
346                                         PyList_SetItem(list, i, PyInt_FromLong(value_list->values[i].counter));
347                                 else
348                                         PyList_SetItem(list, i, PyLong_FromUnsignedLongLong(value_list->values[i].counter));
349                         } else if (ds->ds[i].type == DS_TYPE_GAUGE) {
350                                 PyList_SetItem(list, i, PyFloat_FromDouble(value_list->values[i].gauge));
351                         } else if (ds->ds[i].type == DS_TYPE_DERIVE) {
352                                 if ((long) value_list->values[i].derive == value_list->values[i].derive)
353                                         PyList_SetItem(list, i, PyInt_FromLong(value_list->values[i].derive));
354                                 else
355                                         PyList_SetItem(list, i, PyLong_FromLongLong(value_list->values[i].derive));
356                         } else if (ds->ds[i].type == DS_TYPE_ABSOLUTE) {
357                                 if ((long) value_list->values[i].absolute == value_list->values[i].absolute)
358                                         PyList_SetItem(list, i, PyInt_FromLong(value_list->values[i].absolute));
359                                 else
360                                         PyList_SetItem(list, i, PyLong_FromUnsignedLongLong(value_list->values[i].absolute));
361                         } else {
362                                 Py_BEGIN_ALLOW_THREADS
363                                 ERROR("cpy_write_callback: Unknown value type %d.", ds->ds[i].type);
364                                 Py_END_ALLOW_THREADS
365                                 Py_DECREF(list);
366                                 CPY_RETURN_FROM_THREADS 0;
367                         }
368                         if (PyErr_Occurred() != NULL) {
369                                 cpy_log_exception("value building for write callback");
370                                 Py_DECREF(list);
371                                 CPY_RETURN_FROM_THREADS 0;
372                         }
373                 }
374                 dict = PyDict_New();  /* New reference. */
375                 if (value_list->meta) {
376                         int i, num;
377                         char **table;
378                         meta_data_t *meta = value_list->meta;
379
380                         num = meta_data_toc(meta, &table);
381                         for (i = 0; i < num; ++i) {
382                                 int type;
383                                 char *string;
384                                 int64_t si;
385                                 uint64_t ui;
386                                 double d;
387                                 _Bool b;
388                                 
389                                 type = meta_data_type(meta, table[i]);
390                                 if (type == MD_TYPE_STRING) {
391                                         if (meta_data_get_string(meta, table[i], &string))
392                                                 continue;
393                                         temp = cpy_string_to_unicode_or_bytes(string);  /* New reference. */
394                                         free(string);
395                                         PyDict_SetItemString(dict, table[i], temp);
396                                         Py_XDECREF(temp);
397                                 } else if (type == MD_TYPE_SIGNED_INT) {
398                                         if (meta_data_get_signed_int(meta, table[i], &si))
399                                                 continue;
400                                         temp = PyObject_CallFunctionObjArgs((void *) &SignedType, PyLong_FromLongLong(si), (void *) 0);  /* New reference. */
401                                         PyDict_SetItemString(dict, table[i], temp);
402                                         Py_XDECREF(temp);
403                                 } else if (type == MD_TYPE_UNSIGNED_INT) {
404                                         if (meta_data_get_unsigned_int(meta, table[i], &ui))
405                                                 continue;
406                                         temp = PyObject_CallFunctionObjArgs((void *) &UnsignedType, PyLong_FromUnsignedLongLong(ui), (void *) 0);  /* New reference. */
407                                         PyDict_SetItemString(dict, table[i], temp);
408                                         Py_XDECREF(temp);
409                                 } else if (type == MD_TYPE_DOUBLE) {
410                                         if (meta_data_get_double(meta, table[i], &d))
411                                                 continue;
412                                         temp = PyFloat_FromDouble(d);  /* New reference. */
413                                         PyDict_SetItemString(dict, table[i], temp);
414                                         Py_XDECREF(temp);
415                                 } else if (type == MD_TYPE_BOOLEAN) {
416                                         if (meta_data_get_boolean(meta, table[i], &b))
417                                                 continue;
418                                         if (b)
419                                                 PyDict_SetItemString(dict, table[i], Py_True);
420                                         else
421                                                 PyDict_SetItemString(dict, table[i], Py_False);
422                                 }
423                                 free(table[i]);
424                         }
425                         free(table);
426                 }
427                 v = (Values *) Values_New(); /* New reference. */
428                 sstrncpy(v->data.host, value_list->host, sizeof(v->data.host));
429                 sstrncpy(v->data.type, value_list->type, sizeof(v->data.type));
430                 sstrncpy(v->data.type_instance, value_list->type_instance, sizeof(v->data.type_instance));
431                 sstrncpy(v->data.plugin, value_list->plugin, sizeof(v->data.plugin));
432                 sstrncpy(v->data.plugin_instance, value_list->plugin_instance, sizeof(v->data.plugin_instance));
433                 v->data.time = CDTIME_T_TO_DOUBLE(value_list->time);
434                 v->interval = CDTIME_T_TO_DOUBLE(value_list->interval);
435                 Py_CLEAR(v->values);
436                 v->values = list;
437                 Py_CLEAR(v->meta);
438                 v->meta = dict;  /* Steals a reference. */
439                 ret = PyObject_CallFunctionObjArgs(c->callback, v, c->data, (void *) 0); /* New reference. */
440                 Py_XDECREF(v);
441                 if (ret == NULL) {
442                         cpy_log_exception("write callback");
443                 } else {
444                         Py_DECREF(ret);
445                 }
446         CPY_RELEASE_THREADS
447         return 0;
448 }
449
450 static int cpy_notification_callback(const notification_t *notification, user_data_t *data) {
451         cpy_callback_t *c = data->data;
452         PyObject *ret, *notify;
453         Notification *n;
454
455         CPY_LOCK_THREADS
456                 notify = Notification_New(); /* New reference. */
457                 n = (Notification *) notify;
458                 sstrncpy(n->data.host, notification->host, sizeof(n->data.host));
459                 sstrncpy(n->data.type, notification->type, sizeof(n->data.type));
460                 sstrncpy(n->data.type_instance, notification->type_instance, sizeof(n->data.type_instance));
461                 sstrncpy(n->data.plugin, notification->plugin, sizeof(n->data.plugin));
462                 sstrncpy(n->data.plugin_instance, notification->plugin_instance, sizeof(n->data.plugin_instance));
463                 n->data.time = CDTIME_T_TO_DOUBLE(notification->time);
464                 sstrncpy(n->message, notification->message, sizeof(n->message));
465                 n->severity = notification->severity;
466                 ret = PyObject_CallFunctionObjArgs(c->callback, n, c->data, (void *) 0); /* New reference. */
467                 Py_XDECREF(notify);
468                 if (ret == NULL) {
469                         cpy_log_exception("notification callback");
470                 } else {
471                         Py_DECREF(ret);
472                 }
473         CPY_RELEASE_THREADS
474         return 0;
475 }
476
477 static void cpy_log_callback(int severity, const char *message, user_data_t *data) {
478         cpy_callback_t * c = data->data;
479         PyObject *ret, *text;
480
481         CPY_LOCK_THREADS
482         text = cpy_string_to_unicode_or_bytes(message);  /* New reference. */
483         if (c->data == NULL)
484                 ret = PyObject_CallFunction(c->callback, "iN", severity, text); /* New reference. Steals a reference from "text". */
485         else
486                 ret = PyObject_CallFunction(c->callback, "iNO", severity, text, c->data); /* New reference. Steals a reference from "text". */
487
488         if (ret == NULL) {
489                 /* FIXME */
490                 /* Do we really want to trigger a log callback because a log callback failed?
491                  * Probably not. */
492                 PyErr_Print();
493                 /* In case someone wanted to be clever, replaced stderr and failed at that. */
494                 PyErr_Clear();
495         } else {
496                 Py_DECREF(ret);
497         }
498         CPY_RELEASE_THREADS
499 }
500
501 static void cpy_flush_callback(int timeout, const char *id, user_data_t *data) {
502         cpy_callback_t * c = data->data;
503         PyObject *ret, *text;
504
505         CPY_LOCK_THREADS
506         text = cpy_string_to_unicode_or_bytes(id);
507         if (c->data == NULL)
508                 ret = PyObject_CallFunction(c->callback, "iN", timeout, text); /* New reference. */
509         else
510                 ret = PyObject_CallFunction(c->callback, "iNO", timeout, text, c->data); /* New reference. */
511
512         if (ret == NULL) {
513                 cpy_log_exception("flush callback");
514         } else {
515                 Py_DECREF(ret);
516         }
517         CPY_RELEASE_THREADS
518 }
519
520 static PyObject *cpy_register_generic(cpy_callback_t **list_head, PyObject *args, PyObject *kwds) {
521         char buf[512];
522         cpy_callback_t *c;
523         char *name = NULL;
524         PyObject *callback = NULL, *data = NULL, *mod = NULL;
525         static char *kwlist[] = {"callback", "data", "name", NULL};
526         
527         if (PyArg_ParseTupleAndKeywords(args, kwds, "O|Oet", kwlist, &callback, &data, NULL, &name) == 0) return NULL;
528         if (PyCallable_Check(callback) == 0) {
529                 PyMem_Free(name);
530                 PyErr_SetString(PyExc_TypeError, "callback needs a be a callable object.");
531                 return NULL;
532         }
533         cpy_build_name(buf, sizeof(buf), callback, name);
534
535         Py_INCREF(callback);
536         Py_XINCREF(data);
537
538         c = malloc(sizeof(*c));
539         if (c == NULL)
540                 return NULL;
541         memset (c, 0, sizeof (*c));
542
543         c->name = strdup(buf);
544         c->callback = callback;
545         c->data = data;
546         c->next = *list_head;
547         *list_head = c;
548         Py_XDECREF(mod);
549         PyMem_Free(name);
550         return cpy_string_to_unicode_or_bytes(buf);
551 }
552
553 static PyObject *cpy_flush(cpy_callback_t **list_head, PyObject *args, PyObject *kwds) {
554         int timeout = -1;
555         char *plugin = NULL, *identifier = NULL;
556         static char *kwlist[] = {"plugin", "timeout", "identifier", NULL};
557         
558         if (PyArg_ParseTupleAndKeywords(args, kwds, "|etiet", kwlist, NULL, &plugin, &timeout, NULL, &identifier) == 0) return NULL;
559         Py_BEGIN_ALLOW_THREADS
560         plugin_flush(plugin, timeout, identifier);
561         Py_END_ALLOW_THREADS
562         PyMem_Free(plugin);
563         PyMem_Free(identifier);
564         Py_RETURN_NONE;
565 }
566
567 static PyObject *cpy_register_config(PyObject *self, PyObject *args, PyObject *kwds) {
568         return cpy_register_generic(&cpy_config_callbacks, args, kwds);
569 }
570
571 static PyObject *cpy_register_init(PyObject *self, PyObject *args, PyObject *kwds) {
572         return cpy_register_generic(&cpy_init_callbacks, args, kwds);
573 }
574
575 typedef int reg_function_t(const char *name, void *callback, void *data);
576
577 static PyObject *cpy_register_generic_userdata(void *reg, void *handler, PyObject *args, PyObject *kwds) {
578         char buf[512];
579         reg_function_t *register_function = (reg_function_t *) reg;
580         cpy_callback_t *c = NULL;
581         user_data_t user_data;
582         char *name = NULL;
583         PyObject *callback = NULL, *data = NULL;
584         static char *kwlist[] = {"callback", "data", "name", NULL};
585         
586         if (PyArg_ParseTupleAndKeywords(args, kwds, "O|Oet", kwlist, &callback, &data, NULL, &name) == 0) return NULL;
587         if (PyCallable_Check(callback) == 0) {
588                 PyMem_Free(name);
589                 PyErr_SetString(PyExc_TypeError, "callback needs a be a callable object.");
590                 return NULL;
591         }
592         cpy_build_name(buf, sizeof(buf), callback, name);
593         PyMem_Free(name);
594         
595         Py_INCREF(callback);
596         Py_XINCREF(data);
597
598         c = malloc(sizeof(*c));
599         if (c == NULL)
600                 return NULL;
601         memset (c, 0, sizeof (*c));
602
603         c->name = strdup(buf);
604         c->callback = callback;
605         c->data = data;
606         c->next = NULL;
607
608         memset (&user_data, 0, sizeof (user_data));
609         user_data.free_func = cpy_destroy_user_data;
610         user_data.data = c;
611
612         register_function(buf, handler, &user_data);
613         return cpy_string_to_unicode_or_bytes(buf);
614 }
615
616 static PyObject *cpy_register_read(PyObject *self, PyObject *args, PyObject *kwds) {
617         char buf[512];
618         cpy_callback_t *c = NULL;
619         user_data_t user_data;
620         double interval = 0;
621         char *name = NULL;
622         PyObject *callback = NULL, *data = NULL;
623         struct timespec ts;
624         static char *kwlist[] = {"callback", "interval", "data", "name", NULL};
625         
626         if (PyArg_ParseTupleAndKeywords(args, kwds, "O|dOet", kwlist, &callback, &interval, &data, NULL, &name) == 0) return NULL;
627         if (PyCallable_Check(callback) == 0) {
628                 PyMem_Free(name);
629                 PyErr_SetString(PyExc_TypeError, "callback needs a be a callable object.");
630                 return NULL;
631         }
632         cpy_build_name(buf, sizeof(buf), callback, name);
633         PyMem_Free(name);
634         
635         Py_INCREF(callback);
636         Py_XINCREF(data);
637
638         c = malloc(sizeof(*c));
639         if (c == NULL)
640                 return NULL;
641         memset (c, 0, sizeof (*c));
642
643         c->name = strdup(buf);
644         c->callback = callback;
645         c->data = data;
646         c->next = NULL;
647
648         memset (&user_data, 0, sizeof (user_data));
649         user_data.free_func = cpy_destroy_user_data;
650         user_data.data = c;
651
652         ts.tv_sec = interval;
653         ts.tv_nsec = (interval - ts.tv_sec) * 1000000000;
654         plugin_register_complex_read(/* group = */ "python", buf,
655                         cpy_read_callback, &ts, &user_data);
656
657         return cpy_string_to_unicode_or_bytes(buf);
658 }
659
660 static PyObject *cpy_register_log(PyObject *self, PyObject *args, PyObject *kwds) {
661         return cpy_register_generic_userdata((void *) plugin_register_log,
662                         (void *) cpy_log_callback, args, kwds);
663 }
664
665 static PyObject *cpy_register_write(PyObject *self, PyObject *args, PyObject *kwds) {
666         return cpy_register_generic_userdata((void *) plugin_register_write,
667                         (void *) cpy_write_callback, args, kwds);
668 }
669
670 static PyObject *cpy_register_notification(PyObject *self, PyObject *args, PyObject *kwds) {
671         return cpy_register_generic_userdata((void *) plugin_register_notification,
672                         (void *) cpy_notification_callback, args, kwds);
673 }
674
675 static PyObject *cpy_register_flush(PyObject *self, PyObject *args, PyObject *kwds) {
676         return cpy_register_generic_userdata((void *) plugin_register_flush,
677                         (void *) cpy_flush_callback, args, kwds);
678 }
679
680 static PyObject *cpy_register_shutdown(PyObject *self, PyObject *args, PyObject *kwds) {
681         return cpy_register_generic(&cpy_shutdown_callbacks, args, kwds);
682 }
683
684 static PyObject *cpy_error(PyObject *self, PyObject *args) {
685         char *text;
686         if (PyArg_ParseTuple(args, "et", NULL, &text) == 0) return NULL;
687         Py_BEGIN_ALLOW_THREADS
688         plugin_log(LOG_ERR, "%s", text);
689         Py_END_ALLOW_THREADS
690         PyMem_Free(text);
691         Py_RETURN_NONE;
692 }
693
694 static PyObject *cpy_warning(PyObject *self, PyObject *args) {
695         char *text;
696         if (PyArg_ParseTuple(args, "et", NULL, &text) == 0) return NULL;
697         Py_BEGIN_ALLOW_THREADS
698         plugin_log(LOG_WARNING, "%s", text);
699         Py_END_ALLOW_THREADS
700         PyMem_Free(text);
701         Py_RETURN_NONE;
702 }
703
704 static PyObject *cpy_notice(PyObject *self, PyObject *args) {
705         char *text;
706         if (PyArg_ParseTuple(args, "et", NULL, &text) == 0) return NULL;
707         Py_BEGIN_ALLOW_THREADS
708         plugin_log(LOG_NOTICE, "%s", text);
709         Py_END_ALLOW_THREADS
710         PyMem_Free(text);
711         Py_RETURN_NONE;
712 }
713
714 static PyObject *cpy_info(PyObject *self, PyObject *args) {
715         char *text;
716         if (PyArg_ParseTuple(args, "et", NULL, &text) == 0) return NULL;
717         Py_BEGIN_ALLOW_THREADS
718         plugin_log(LOG_INFO, "%s", text);
719         Py_END_ALLOW_THREADS
720         PyMem_Free(text);
721         Py_RETURN_NONE;
722 }
723
724 static PyObject *cpy_debug(PyObject *self, PyObject *args) {
725 #ifdef COLLECT_DEBUG
726         char *text;
727         if (PyArg_ParseTuple(args, "et", NULL, &text) == 0) return NULL;
728         Py_BEGIN_ALLOW_THREADS
729         plugin_log(LOG_DEBUG, "%s", text);
730         Py_END_ALLOW_THREADS
731         PyMem_Free(text);
732 #endif
733         Py_RETURN_NONE;
734 }
735
736 static PyObject *cpy_unregister_generic(cpy_callback_t **list_head, PyObject *arg, const char *desc) {
737         char buf[512];
738         const char *name;
739         cpy_callback_t *prev = NULL, *tmp;
740
741         Py_INCREF(arg);
742         name = cpy_unicode_or_bytes_to_string(&arg);
743         if (name == NULL) {
744                 PyErr_Clear();
745                 if (!PyCallable_Check(arg)) {
746                         PyErr_SetString(PyExc_TypeError, "This function needs a string or a callable object as its only parameter.");
747                         Py_DECREF(arg);
748                         return NULL;
749                 }
750                 cpy_build_name(buf, sizeof(buf), arg, NULL);
751                 name = buf;
752         }
753         for (tmp = *list_head; tmp; prev = tmp, tmp = tmp->next)
754                 if (strcmp(name, tmp->name) == 0)
755                         break;
756         
757         Py_DECREF(arg);
758         if (tmp == NULL) {
759                 PyErr_Format(PyExc_RuntimeError, "Unable to unregister %s callback '%s'.", desc, name);
760                 return NULL;
761         }
762         /* Yes, this is actually save. To call this function the caller has to
763          * hold the GIL. Well, save as long as there is only one GIL anyway ... */
764         if (prev == NULL)
765                 *list_head = tmp->next;
766         else
767                 prev->next = tmp->next;
768         cpy_destroy_user_data(tmp);
769         Py_RETURN_NONE;
770 }
771
772 typedef int cpy_unregister_function_t(const char *name);
773
774 static PyObject *cpy_unregister_generic_userdata(cpy_unregister_function_t *unreg, PyObject *arg, const char *desc) {
775         char buf[512];
776         const char *name;
777
778         Py_INCREF(arg);
779         name = cpy_unicode_or_bytes_to_string(&arg);
780         if (name == NULL) {
781                 PyErr_Clear();
782                 if (!PyCallable_Check(arg)) {
783                         PyErr_SetString(PyExc_TypeError, "This function needs a string or a callable object as its only parameter.");
784                         Py_DECREF(arg);
785                         return NULL;
786                 }
787                 cpy_build_name(buf, sizeof(buf), arg, NULL);
788                 name = buf;
789         }
790         if (unreg(name) == 0) {
791                 Py_DECREF(arg);
792                 Py_RETURN_NONE;
793         }
794         PyErr_Format(PyExc_RuntimeError, "Unable to unregister %s callback '%s'.", desc, name);
795         Py_DECREF(arg);
796         return NULL;
797 }
798
799 static PyObject *cpy_unregister_log(PyObject *self, PyObject *arg) {
800         return cpy_unregister_generic_userdata(plugin_unregister_log, arg, "log");
801 }
802
803 static PyObject *cpy_unregister_init(PyObject *self, PyObject *arg) {
804         return cpy_unregister_generic(&cpy_init_callbacks, arg, "init");
805 }
806
807 static PyObject *cpy_unregister_config(PyObject *self, PyObject *arg) {
808         return cpy_unregister_generic(&cpy_config_callbacks, arg, "config");
809 }
810
811 static PyObject *cpy_unregister_read(PyObject *self, PyObject *arg) {
812         return cpy_unregister_generic_userdata(plugin_unregister_read, arg, "read");
813 }
814
815 static PyObject *cpy_unregister_write(PyObject *self, PyObject *arg) {
816         return cpy_unregister_generic_userdata(plugin_unregister_write, arg, "write");
817 }
818
819 static PyObject *cpy_unregister_notification(PyObject *self, PyObject *arg) {
820         return cpy_unregister_generic_userdata(plugin_unregister_notification, arg, "notification");
821 }
822
823 static PyObject *cpy_unregister_flush(PyObject *self, PyObject *arg) {
824         return cpy_unregister_generic_userdata(plugin_unregister_flush, arg, "flush");
825 }
826
827 static PyObject *cpy_unregister_shutdown(PyObject *self, PyObject *arg) {
828         return cpy_unregister_generic(&cpy_shutdown_callbacks, arg, "shutdown");
829 }
830
831 static PyMethodDef cpy_methods[] = {
832         {"debug", cpy_debug, METH_VARARGS, log_doc},
833         {"info", cpy_info, METH_VARARGS, log_doc},
834         {"notice", cpy_notice, METH_VARARGS, log_doc},
835         {"warning", cpy_warning, METH_VARARGS, log_doc},
836         {"error", cpy_error, METH_VARARGS, log_doc},
837         {"flush", (PyCFunction) cpy_flush, METH_VARARGS | METH_KEYWORDS, flush_doc},
838         {"register_log", (PyCFunction) cpy_register_log, METH_VARARGS | METH_KEYWORDS, reg_log_doc},
839         {"register_init", (PyCFunction) cpy_register_init, METH_VARARGS | METH_KEYWORDS, reg_init_doc},
840         {"register_config", (PyCFunction) cpy_register_config, METH_VARARGS | METH_KEYWORDS, reg_config_doc},
841         {"register_read", (PyCFunction) cpy_register_read, METH_VARARGS | METH_KEYWORDS, reg_read_doc},
842         {"register_write", (PyCFunction) cpy_register_write, METH_VARARGS | METH_KEYWORDS, reg_write_doc},
843         {"register_notification", (PyCFunction) cpy_register_notification, METH_VARARGS | METH_KEYWORDS, reg_notification_doc},
844         {"register_flush", (PyCFunction) cpy_register_flush, METH_VARARGS | METH_KEYWORDS, reg_flush_doc},
845         {"register_shutdown", (PyCFunction) cpy_register_shutdown, METH_VARARGS | METH_KEYWORDS, reg_shutdown_doc},
846         {"unregister_log", cpy_unregister_log, METH_O, unregister_doc},
847         {"unregister_init", cpy_unregister_init, METH_O, unregister_doc},
848         {"unregister_config", cpy_unregister_config, METH_O, unregister_doc},
849         {"unregister_read", cpy_unregister_read, METH_O, unregister_doc},
850         {"unregister_write", cpy_unregister_write, METH_O, unregister_doc},
851         {"unregister_notification", cpy_unregister_notification, METH_O, unregister_doc},
852         {"unregister_flush", cpy_unregister_flush, METH_O, unregister_doc},
853         {"unregister_shutdown", cpy_unregister_shutdown, METH_O, unregister_doc},
854         {0, 0, 0, 0}
855 };
856
857 static int cpy_shutdown(void) {
858         cpy_callback_t *c;
859         PyObject *ret;
860         
861         /* This can happen if the module was loaded but not configured. */
862         if (state != NULL)
863                 PyEval_RestoreThread(state);
864
865         for (c = cpy_shutdown_callbacks; c; c = c->next) {
866                 ret = PyObject_CallFunctionObjArgs(c->callback, c->data, (void *) 0); /* New reference. */
867                 if (ret == NULL)
868                         cpy_log_exception("shutdown callback");
869                 else
870                         Py_DECREF(ret);
871         }
872         PyErr_Print();
873         Py_Finalize();
874         return 0;
875 }
876
877 static void cpy_int_handler(int sig) {
878         return;
879 }
880
881 static void *cpy_interactive(void *data) {
882         sigset_t sigset;
883         struct sigaction sig_int_action, old;
884         
885         /* Signal handler in a plugin? Bad stuff, but the best way to
886          * handle it I guess. In an interactive session people will
887          * press Ctrl+C at some time, which will generate a SIGINT.
888          * This will cause collectd to shutdown, thus killing the
889          * interactive interpreter, and leaving the terminal in a
890          * mess. Chances are, this isn't what the user wanted to do.
891          * 
892          * So this is the plan:
893          * 1. Block SIGINT in the main thread.
894          * 2. Install our own signal handler that does nothing.
895          * 3. Unblock SIGINT in the interactive thread.
896          *
897          * This will make sure that SIGINT won't kill collectd but
898          * still interrupt syscalls like sleep and pause.
899          * It does not raise a KeyboardInterrupt exception because so
900          * far nobody managed to figure out how to do that. */
901         memset (&sig_int_action, '\0', sizeof (sig_int_action));
902         sig_int_action.sa_handler = cpy_int_handler;
903         sigaction (SIGINT, &sig_int_action, &old);
904         
905         sigemptyset(&sigset);
906         sigaddset(&sigset, SIGINT);
907         pthread_sigmask(SIG_UNBLOCK, &sigset, NULL);
908         PyEval_AcquireThread(state);
909         if (PyImport_ImportModule("readline") == NULL) {
910                 /* This interactive session will suck. */
911                 cpy_log_exception("interactive session init");
912         }
913         PyRun_InteractiveLoop(stdin, "<stdin>");
914         PyErr_Print();
915         PyEval_ReleaseThread(state);
916         NOTICE("python: Interactive interpreter exited, stopping collectd ...");
917         /* Restore the original collectd SIGINT handler and raise SIGINT.
918          * The main thread still has SIGINT blocked and there's nothing we
919          * can do about that so this thread will handle it. But that's not
920          * important, except that it won't interrupt the main loop and so
921          * it might take a few seconds before collectd really shuts down. */
922         sigaction (SIGINT, &old, NULL);
923         raise(SIGINT);
924         pause();
925         return NULL;
926 }
927
928 static int cpy_init(void) {
929         cpy_callback_t *c;
930         PyObject *ret;
931         static pthread_t thread;
932         sigset_t sigset;
933         
934         if (!Py_IsInitialized()) {
935                 WARNING("python: Plugin loaded but not configured.");
936                 plugin_unregister_shutdown("python");
937                 return 0;
938         }
939         PyEval_InitThreads();
940         /* Now it's finally OK to use python threads. */
941         for (c = cpy_init_callbacks; c; c = c->next) {
942                 ret = PyObject_CallFunctionObjArgs(c->callback, c->data, (void *) 0); /* New reference. */
943                 if (ret == NULL)
944                         cpy_log_exception("init callback");
945                 else
946                         Py_DECREF(ret);
947         }
948         sigemptyset(&sigset);
949         sigaddset(&sigset, SIGINT);
950         pthread_sigmask(SIG_BLOCK, &sigset, NULL);
951         state = PyEval_SaveThread();
952         if (do_interactive) {
953                 if (plugin_thread_create(&thread, NULL, cpy_interactive, NULL)) {
954                         ERROR("python: Error creating thread for interactive interpreter.");
955                 }
956         }
957
958         return 0;
959 }
960
961 static PyObject *cpy_oconfig_to_pyconfig(oconfig_item_t *ci, PyObject *parent) {
962         int i;
963         PyObject *item, *values, *children, *tmp;
964         
965         if (parent == NULL)
966                 parent = Py_None;
967         
968         values = PyTuple_New(ci->values_num); /* New reference. */
969         for (i = 0; i < ci->values_num; ++i) {
970                 if (ci->values[i].type == OCONFIG_TYPE_STRING) {
971                         PyTuple_SET_ITEM(values, i, cpy_string_to_unicode_or_bytes(ci->values[i].value.string));
972                 } else if (ci->values[i].type == OCONFIG_TYPE_NUMBER) {
973                         PyTuple_SET_ITEM(values, i, PyFloat_FromDouble(ci->values[i].value.number));
974                 } else if (ci->values[i].type == OCONFIG_TYPE_BOOLEAN) {
975                         PyTuple_SET_ITEM(values, i, PyBool_FromLong(ci->values[i].value.boolean));
976                 }
977         }
978         
979         tmp = cpy_string_to_unicode_or_bytes(ci->key);
980         item = PyObject_CallFunction((void *) &ConfigType, "NONO", tmp, parent, values, Py_None);
981         if (item == NULL)
982                 return NULL;
983         children = PyTuple_New(ci->children_num); /* New reference. */
984         for (i = 0; i < ci->children_num; ++i) {
985                 PyTuple_SET_ITEM(children, i, cpy_oconfig_to_pyconfig(ci->children + i, item));
986         }
987         tmp = ((Config *) item)->children;
988         ((Config *) item)->children = children;
989         Py_XDECREF(tmp);
990         return item;
991 }
992
993 #ifdef IS_PY3K
994 static struct PyModuleDef collectdmodule = {
995         PyModuleDef_HEAD_INIT,
996         "collectd",   /* name of module */
997         "The python interface to collectd", /* module documentation, may be NULL */
998         -1,
999         cpy_methods
1000 };
1001
1002 PyMODINIT_FUNC PyInit_collectd(void) {
1003         return PyModule_Create(&collectdmodule);
1004 }
1005 #endif
1006
1007 static int cpy_init_python() {
1008         char *argv = "";
1009         PyObject *sys;
1010         PyObject *module;
1011
1012 #ifdef IS_PY3K
1013         /* Add a builtin module, before Py_Initialize */
1014         PyImport_AppendInittab("collectd", PyInit_collectd);
1015 #endif
1016         
1017         Py_Initialize();
1018         
1019         PyType_Ready(&ConfigType);
1020         PyType_Ready(&PluginDataType);
1021         ValuesType.tp_base = &PluginDataType;
1022         PyType_Ready(&ValuesType);
1023         NotificationType.tp_base = &PluginDataType;
1024         PyType_Ready(&NotificationType);
1025         SignedType.tp_base = &PyLong_Type;
1026         PyType_Ready(&SignedType);
1027         UnsignedType.tp_base = &PyLong_Type;
1028         PyType_Ready(&UnsignedType);
1029         sys = PyImport_ImportModule("sys"); /* New reference. */
1030         if (sys == NULL) {
1031                 cpy_log_exception("python initialization");
1032                 return 1;
1033         }
1034         sys_path = PyObject_GetAttrString(sys, "path"); /* New reference. */
1035         Py_DECREF(sys);
1036         if (sys_path == NULL) {
1037                 cpy_log_exception("python initialization");
1038                 return 1;
1039         }
1040         PySys_SetArgv(1, &argv);
1041         PyList_SetSlice(sys_path, 0, 1, NULL);
1042
1043 #ifdef IS_PY3K
1044         module = PyImport_ImportModule("collectd");
1045 #else
1046         module = Py_InitModule("collectd", cpy_methods); /* Borrowed reference. */
1047 #endif
1048         PyModule_AddObject(module, "Config", (void *) &ConfigType); /* Steals a reference. */
1049         PyModule_AddObject(module, "Values", (void *) &ValuesType); /* Steals a reference. */
1050         PyModule_AddObject(module, "Notification", (void *) &NotificationType); /* Steals a reference. */
1051         PyModule_AddObject(module, "Signed", (void *) &SignedType); /* Steals a reference. */
1052         PyModule_AddObject(module, "Unsigned", (void *) &UnsignedType); /* Steals a reference. */
1053         PyModule_AddIntConstant(module, "LOG_DEBUG", LOG_DEBUG);
1054         PyModule_AddIntConstant(module, "LOG_INFO", LOG_INFO);
1055         PyModule_AddIntConstant(module, "LOG_NOTICE", LOG_NOTICE);
1056         PyModule_AddIntConstant(module, "LOG_WARNING", LOG_WARNING);
1057         PyModule_AddIntConstant(module, "LOG_ERROR", LOG_ERR);
1058         PyModule_AddIntConstant(module, "NOTIF_FAILURE", NOTIF_FAILURE);
1059         PyModule_AddIntConstant(module, "NOTIF_WARNING", NOTIF_WARNING);
1060         PyModule_AddIntConstant(module, "NOTIF_OKAY", NOTIF_OKAY);
1061         return 0;
1062 }
1063
1064 static int cpy_config(oconfig_item_t *ci) {
1065         int i;
1066         PyObject *tb;
1067
1068         /* Ok in theory we shouldn't do initialization at this point
1069          * but we have to. In order to give python scripts a chance
1070          * to register a config callback we need to be able to execute
1071          * python code during the config callback so we have to start
1072          * the interpreter here. */
1073         /* Do *not* use the python "thread" module at this point! */
1074
1075         if (!Py_IsInitialized() && cpy_init_python()) return 1;
1076
1077         for (i = 0; i < ci->children_num; ++i) {
1078                 oconfig_item_t *item = ci->children + i;
1079                 
1080                 if (strcasecmp(item->key, "Interactive") == 0) {
1081                         if (item->values_num != 1 || item->values[0].type != OCONFIG_TYPE_BOOLEAN)
1082                                 continue;
1083                         do_interactive = item->values[0].value.boolean;
1084                 } else if (strcasecmp(item->key, "Encoding") == 0) {
1085                         if (item->values_num != 1 || item->values[0].type != OCONFIG_TYPE_STRING)
1086                                 continue;
1087                         /* Why is this even necessary? And undocumented? */
1088                         if (PyUnicode_SetDefaultEncoding(item->values[0].value.string))
1089                                 cpy_log_exception("setting default encoding");
1090                 } else if (strcasecmp(item->key, "LogTraces") == 0) {
1091                         if (item->values_num != 1 || item->values[0].type != OCONFIG_TYPE_BOOLEAN)
1092                                 continue;
1093                         if (!item->values[0].value.boolean) {
1094                                 Py_XDECREF(cpy_format_exception);
1095                                 cpy_format_exception = NULL;
1096                                 continue;
1097                         }
1098                         if (cpy_format_exception)
1099                                 continue;
1100                         tb = PyImport_ImportModule("traceback"); /* New reference. */
1101                         if (tb == NULL) {
1102                                 cpy_log_exception("python initialization");
1103                                 continue;
1104                         }
1105                         cpy_format_exception = PyObject_GetAttrString(tb, "format_exception"); /* New reference. */
1106                         Py_DECREF(tb);
1107                         if (cpy_format_exception == NULL)
1108                                 cpy_log_exception("python initialization");
1109                 } else if (strcasecmp(item->key, "ModulePath") == 0) {
1110                         char *dir = NULL;
1111                         PyObject *dir_object;
1112                         
1113                         if (cf_util_get_string(item, &dir) != 0) 
1114                                 continue;
1115                         dir_object = cpy_string_to_unicode_or_bytes(dir); /* New reference. */
1116                         if (dir_object == NULL) {
1117                                 ERROR("python plugin: Unable to convert \"%s\" to "
1118                                       "a python object.", dir);
1119                                 free(dir);
1120                                 cpy_log_exception("python initialization");
1121                                 continue;
1122                         }
1123                         if (PyList_Append(sys_path, dir_object) != 0) {
1124                                 ERROR("python plugin: Unable to append \"%s\" to "
1125                                       "python module path.", dir);
1126                                 cpy_log_exception("python initialization");
1127                         }
1128                         Py_DECREF(dir_object);
1129                         free(dir);
1130                 } else if (strcasecmp(item->key, "Import") == 0) {
1131                         char *module_name = NULL;
1132                         PyObject *module;
1133                         
1134                         if (cf_util_get_string(item, &module_name) != 0) 
1135                                 continue;
1136                         module = PyImport_ImportModule(module_name); /* New reference. */
1137                         if (module == NULL) {
1138                                 ERROR("python plugin: Error importing module \"%s\".", module_name);
1139                                 cpy_log_exception("importing module");
1140                         }
1141                         free(module_name);
1142                         Py_XDECREF(module);
1143                 } else if (strcasecmp(item->key, "Module") == 0) {
1144                         char *name = NULL;
1145                         cpy_callback_t *c;
1146                         PyObject *ret;
1147                         
1148                         if (cf_util_get_string(item, &name) != 0)
1149                                 continue;
1150                         for (c = cpy_config_callbacks; c; c = c->next) {
1151                                 if (strcasecmp(c->name + 7, name) == 0)
1152                                         break;
1153                         }
1154                         if (c == NULL) {
1155                                 WARNING("python plugin: Found a configuration for the \"%s\" plugin, "
1156                                         "but the plugin isn't loaded or didn't register "
1157                                         "a configuration callback.", name);
1158                                 free(name);
1159                                 continue;
1160                         }
1161                         free(name);
1162                         if (c->data == NULL)
1163                                 ret = PyObject_CallFunction(c->callback, "N",
1164                                         cpy_oconfig_to_pyconfig(item, NULL)); /* New reference. */
1165                         else
1166                                 ret = PyObject_CallFunction(c->callback, "NO",
1167                                         cpy_oconfig_to_pyconfig(item, NULL), c->data); /* New reference. */
1168                         if (ret == NULL)
1169                                 cpy_log_exception("loading module");
1170                         else
1171                                 Py_DECREF(ret);
1172                 } else {
1173                         WARNING("python plugin: Ignoring unknown config key \"%s\".", item->key);
1174                 }
1175         }
1176         return 0;
1177 }
1178
1179 void module_register(void) {
1180         plugin_register_complex_config("python", cpy_config);
1181         plugin_register_init("python", cpy_init);
1182         plugin_register_shutdown("python", cpy_shutdown);
1183 }