python plugin: Fix memory leak.
[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         c = malloc(sizeof(*c));
538         c->name = strdup(buf);
539         c->callback = callback;
540         c->data = data;
541         c->next = *list_head;
542         *list_head = c;
543         Py_XDECREF(mod);
544         PyMem_Free(name);
545         return cpy_string_to_unicode_or_bytes(buf);
546 }
547
548 static PyObject *cpy_flush(cpy_callback_t **list_head, PyObject *args, PyObject *kwds) {
549         int timeout = -1;
550         char *plugin = NULL, *identifier = NULL;
551         static char *kwlist[] = {"plugin", "timeout", "identifier", NULL};
552         
553         if (PyArg_ParseTupleAndKeywords(args, kwds, "|etiet", kwlist, NULL, &plugin, &timeout, NULL, &identifier) == 0) return NULL;
554         Py_BEGIN_ALLOW_THREADS
555         plugin_flush(plugin, timeout, identifier);
556         Py_END_ALLOW_THREADS
557         PyMem_Free(plugin);
558         PyMem_Free(identifier);
559         Py_RETURN_NONE;
560 }
561
562 static PyObject *cpy_register_config(PyObject *self, PyObject *args, PyObject *kwds) {
563         return cpy_register_generic(&cpy_config_callbacks, args, kwds);
564 }
565
566 static PyObject *cpy_register_init(PyObject *self, PyObject *args, PyObject *kwds) {
567         return cpy_register_generic(&cpy_init_callbacks, args, kwds);
568 }
569
570 typedef int reg_function_t(const char *name, void *callback, void *data);
571
572 static PyObject *cpy_register_generic_userdata(void *reg, void *handler, PyObject *args, PyObject *kwds) {
573         char buf[512];
574         reg_function_t *register_function = (reg_function_t *) reg;
575         cpy_callback_t *c = NULL;
576         user_data_t user_data;
577         char *name = NULL;
578         PyObject *callback = NULL, *data = NULL;
579         static char *kwlist[] = {"callback", "data", "name", NULL};
580         
581         if (PyArg_ParseTupleAndKeywords(args, kwds, "O|Oet", kwlist, &callback, &data, NULL, &name) == 0) return NULL;
582         if (PyCallable_Check(callback) == 0) {
583                 PyMem_Free(name);
584                 PyErr_SetString(PyExc_TypeError, "callback needs a be a callable object.");
585                 return NULL;
586         }
587         cpy_build_name(buf, sizeof(buf), callback, name);
588         PyMem_Free(name);
589         
590         Py_INCREF(callback);
591         Py_XINCREF(data);
592         c = malloc(sizeof(*c));
593         c->name = strdup(buf);
594         c->callback = callback;
595         c->data = data;
596         c->next = NULL;
597
598         memset (&user_data, 0, sizeof (user_data));
599         user_data.free_func = cpy_destroy_user_data;
600         user_data.data = c;
601
602         register_function(buf, handler, &user_data);
603         return cpy_string_to_unicode_or_bytes(buf);
604 }
605
606 static PyObject *cpy_register_read(PyObject *self, PyObject *args, PyObject *kwds) {
607         char buf[512];
608         cpy_callback_t *c = NULL;
609         user_data_t user_data;
610         double interval = 0;
611         char *name = NULL;
612         PyObject *callback = NULL, *data = NULL;
613         struct timespec ts;
614         static char *kwlist[] = {"callback", "interval", "data", "name", NULL};
615         
616         if (PyArg_ParseTupleAndKeywords(args, kwds, "O|dOet", kwlist, &callback, &interval, &data, NULL, &name) == 0) return NULL;
617         if (PyCallable_Check(callback) == 0) {
618                 PyMem_Free(name);
619                 PyErr_SetString(PyExc_TypeError, "callback needs a be a callable object.");
620                 return NULL;
621         }
622         cpy_build_name(buf, sizeof(buf), callback, name);
623         PyMem_Free(name);
624         
625         Py_INCREF(callback);
626         Py_XINCREF(data);
627         c = malloc(sizeof(*c));
628         c->name = strdup(buf);
629         c->callback = callback;
630         c->data = data;
631         c->next = NULL;
632
633         memset (&user_data, 0, sizeof (user_data));
634         user_data.free_func = cpy_destroy_user_data;
635         user_data.data = c;
636
637         ts.tv_sec = interval;
638         ts.tv_nsec = (interval - ts.tv_sec) * 1000000000;
639         plugin_register_complex_read(/* group = */ "python", buf,
640                         cpy_read_callback, &ts, &user_data);
641
642         return cpy_string_to_unicode_or_bytes(buf);
643 }
644
645 static PyObject *cpy_register_log(PyObject *self, PyObject *args, PyObject *kwds) {
646         return cpy_register_generic_userdata((void *) plugin_register_log,
647                         (void *) cpy_log_callback, args, kwds);
648 }
649
650 static PyObject *cpy_register_write(PyObject *self, PyObject *args, PyObject *kwds) {
651         return cpy_register_generic_userdata((void *) plugin_register_write,
652                         (void *) cpy_write_callback, args, kwds);
653 }
654
655 static PyObject *cpy_register_notification(PyObject *self, PyObject *args, PyObject *kwds) {
656         return cpy_register_generic_userdata((void *) plugin_register_notification,
657                         (void *) cpy_notification_callback, args, kwds);
658 }
659
660 static PyObject *cpy_register_flush(PyObject *self, PyObject *args, PyObject *kwds) {
661         return cpy_register_generic_userdata((void *) plugin_register_flush,
662                         (void *) cpy_flush_callback, args, kwds);
663 }
664
665 static PyObject *cpy_register_shutdown(PyObject *self, PyObject *args, PyObject *kwds) {
666         return cpy_register_generic(&cpy_shutdown_callbacks, args, kwds);
667 }
668
669 static PyObject *cpy_error(PyObject *self, PyObject *args) {
670         char *text;
671         if (PyArg_ParseTuple(args, "et", NULL, &text) == 0) return NULL;
672         Py_BEGIN_ALLOW_THREADS
673         plugin_log(LOG_ERR, "%s", text);
674         Py_END_ALLOW_THREADS
675         PyMem_Free(text);
676         Py_RETURN_NONE;
677 }
678
679 static PyObject *cpy_warning(PyObject *self, PyObject *args) {
680         char *text;
681         if (PyArg_ParseTuple(args, "et", NULL, &text) == 0) return NULL;
682         Py_BEGIN_ALLOW_THREADS
683         plugin_log(LOG_WARNING, "%s", text);
684         Py_END_ALLOW_THREADS
685         PyMem_Free(text);
686         Py_RETURN_NONE;
687 }
688
689 static PyObject *cpy_notice(PyObject *self, PyObject *args) {
690         char *text;
691         if (PyArg_ParseTuple(args, "et", NULL, &text) == 0) return NULL;
692         Py_BEGIN_ALLOW_THREADS
693         plugin_log(LOG_NOTICE, "%s", text);
694         Py_END_ALLOW_THREADS
695         PyMem_Free(text);
696         Py_RETURN_NONE;
697 }
698
699 static PyObject *cpy_info(PyObject *self, PyObject *args) {
700         char *text;
701         if (PyArg_ParseTuple(args, "et", NULL, &text) == 0) return NULL;
702         Py_BEGIN_ALLOW_THREADS
703         plugin_log(LOG_INFO, "%s", text);
704         Py_END_ALLOW_THREADS
705         PyMem_Free(text);
706         Py_RETURN_NONE;
707 }
708
709 static PyObject *cpy_debug(PyObject *self, PyObject *args) {
710 #ifdef COLLECT_DEBUG
711         char *text;
712         if (PyArg_ParseTuple(args, "et", NULL, &text) == 0) return NULL;
713         Py_BEGIN_ALLOW_THREADS
714         plugin_log(LOG_DEBUG, "%s", text);
715         Py_END_ALLOW_THREADS
716         PyMem_Free(text);
717 #endif
718         Py_RETURN_NONE;
719 }
720
721 static PyObject *cpy_unregister_generic(cpy_callback_t **list_head, PyObject *arg, const char *desc) {
722         char buf[512];
723         const char *name;
724         cpy_callback_t *prev = NULL, *tmp;
725
726         Py_INCREF(arg);
727         name = cpy_unicode_or_bytes_to_string(&arg);
728         if (name == NULL) {
729                 PyErr_Clear();
730                 if (!PyCallable_Check(arg)) {
731                         PyErr_SetString(PyExc_TypeError, "This function needs a string or a callable object as its only parameter.");
732                         Py_DECREF(arg);
733                         return NULL;
734                 }
735                 cpy_build_name(buf, sizeof(buf), arg, NULL);
736                 name = buf;
737         }
738         for (tmp = *list_head; tmp; prev = tmp, tmp = tmp->next)
739                 if (strcmp(name, tmp->name) == 0)
740                         break;
741         
742         Py_DECREF(arg);
743         if (tmp == NULL) {
744                 PyErr_Format(PyExc_RuntimeError, "Unable to unregister %s callback '%s'.", desc, name);
745                 return NULL;
746         }
747         /* Yes, this is actually save. To call this function the caller has to
748          * hold the GIL. Well, save as long as there is only one GIL anyway ... */
749         if (prev == NULL)
750                 *list_head = tmp->next;
751         else
752                 prev->next = tmp->next;
753         cpy_destroy_user_data(tmp);
754         Py_RETURN_NONE;
755 }
756
757 typedef int cpy_unregister_function_t(const char *name);
758
759 static PyObject *cpy_unregister_generic_userdata(cpy_unregister_function_t *unreg, PyObject *arg, const char *desc) {
760         char buf[512];
761         const char *name;
762
763         Py_INCREF(arg);
764         name = cpy_unicode_or_bytes_to_string(&arg);
765         if (name == NULL) {
766                 PyErr_Clear();
767                 if (!PyCallable_Check(arg)) {
768                         PyErr_SetString(PyExc_TypeError, "This function needs a string or a callable object as its only parameter.");
769                         Py_DECREF(arg);
770                         return NULL;
771                 }
772                 cpy_build_name(buf, sizeof(buf), arg, NULL);
773                 name = buf;
774         }
775         if (unreg(name) == 0) {
776                 Py_DECREF(arg);
777                 Py_RETURN_NONE;
778         }
779         PyErr_Format(PyExc_RuntimeError, "Unable to unregister %s callback '%s'.", desc, name);
780         Py_DECREF(arg);
781         return NULL;
782 }
783
784 static PyObject *cpy_unregister_log(PyObject *self, PyObject *arg) {
785         return cpy_unregister_generic_userdata(plugin_unregister_log, arg, "log");
786 }
787
788 static PyObject *cpy_unregister_init(PyObject *self, PyObject *arg) {
789         return cpy_unregister_generic(&cpy_init_callbacks, arg, "init");
790 }
791
792 static PyObject *cpy_unregister_config(PyObject *self, PyObject *arg) {
793         return cpy_unregister_generic(&cpy_config_callbacks, arg, "config");
794 }
795
796 static PyObject *cpy_unregister_read(PyObject *self, PyObject *arg) {
797         return cpy_unregister_generic_userdata(plugin_unregister_read, arg, "read");
798 }
799
800 static PyObject *cpy_unregister_write(PyObject *self, PyObject *arg) {
801         return cpy_unregister_generic_userdata(plugin_unregister_write, arg, "write");
802 }
803
804 static PyObject *cpy_unregister_notification(PyObject *self, PyObject *arg) {
805         return cpy_unregister_generic_userdata(plugin_unregister_notification, arg, "notification");
806 }
807
808 static PyObject *cpy_unregister_flush(PyObject *self, PyObject *arg) {
809         return cpy_unregister_generic_userdata(plugin_unregister_flush, arg, "flush");
810 }
811
812 static PyObject *cpy_unregister_shutdown(PyObject *self, PyObject *arg) {
813         return cpy_unregister_generic(&cpy_shutdown_callbacks, arg, "shutdown");
814 }
815
816 static PyMethodDef cpy_methods[] = {
817         {"debug", cpy_debug, METH_VARARGS, log_doc},
818         {"info", cpy_info, METH_VARARGS, log_doc},
819         {"notice", cpy_notice, METH_VARARGS, log_doc},
820         {"warning", cpy_warning, METH_VARARGS, log_doc},
821         {"error", cpy_error, METH_VARARGS, log_doc},
822         {"flush", (PyCFunction) cpy_flush, METH_VARARGS | METH_KEYWORDS, flush_doc},
823         {"register_log", (PyCFunction) cpy_register_log, METH_VARARGS | METH_KEYWORDS, reg_log_doc},
824         {"register_init", (PyCFunction) cpy_register_init, METH_VARARGS | METH_KEYWORDS, reg_init_doc},
825         {"register_config", (PyCFunction) cpy_register_config, METH_VARARGS | METH_KEYWORDS, reg_config_doc},
826         {"register_read", (PyCFunction) cpy_register_read, METH_VARARGS | METH_KEYWORDS, reg_read_doc},
827         {"register_write", (PyCFunction) cpy_register_write, METH_VARARGS | METH_KEYWORDS, reg_write_doc},
828         {"register_notification", (PyCFunction) cpy_register_notification, METH_VARARGS | METH_KEYWORDS, reg_notification_doc},
829         {"register_flush", (PyCFunction) cpy_register_flush, METH_VARARGS | METH_KEYWORDS, reg_flush_doc},
830         {"register_shutdown", (PyCFunction) cpy_register_shutdown, METH_VARARGS | METH_KEYWORDS, reg_shutdown_doc},
831         {"unregister_log", cpy_unregister_log, METH_O, unregister_doc},
832         {"unregister_init", cpy_unregister_init, METH_O, unregister_doc},
833         {"unregister_config", cpy_unregister_config, METH_O, unregister_doc},
834         {"unregister_read", cpy_unregister_read, METH_O, unregister_doc},
835         {"unregister_write", cpy_unregister_write, METH_O, unregister_doc},
836         {"unregister_notification", cpy_unregister_notification, METH_O, unregister_doc},
837         {"unregister_flush", cpy_unregister_flush, METH_O, unregister_doc},
838         {"unregister_shutdown", cpy_unregister_shutdown, METH_O, unregister_doc},
839         {0, 0, 0, 0}
840 };
841
842 static int cpy_shutdown(void) {
843         cpy_callback_t *c;
844         PyObject *ret;
845         
846         /* This can happen if the module was loaded but not configured. */
847         if (state != NULL)
848                 PyEval_RestoreThread(state);
849
850         for (c = cpy_shutdown_callbacks; c; c = c->next) {
851                 ret = PyObject_CallFunctionObjArgs(c->callback, c->data, (void *) 0); /* New reference. */
852                 if (ret == NULL)
853                         cpy_log_exception("shutdown callback");
854                 else
855                         Py_DECREF(ret);
856         }
857         PyErr_Print();
858         Py_Finalize();
859         return 0;
860 }
861
862 static void cpy_int_handler(int sig) {
863         return;
864 }
865
866 static void *cpy_interactive(void *data) {
867         sigset_t sigset;
868         struct sigaction sig_int_action, old;
869         
870         /* Signal handler in a plugin? Bad stuff, but the best way to
871          * handle it I guess. In an interactive session people will
872          * press Ctrl+C at some time, which will generate a SIGINT.
873          * This will cause collectd to shutdown, thus killing the
874          * interactive interpreter, and leaving the terminal in a
875          * mess. Chances are, this isn't what the user wanted to do.
876          * 
877          * So this is the plan:
878          * 1. Block SIGINT in the main thread.
879          * 2. Install our own signal handler that does nothing.
880          * 3. Unblock SIGINT in the interactive thread.
881          *
882          * This will make sure that SIGINT won't kill collectd but
883          * still interrupt syscalls like sleep and pause.
884          * It does not raise a KeyboardInterrupt exception because so
885          * far nobody managed to figure out how to do that. */
886         memset (&sig_int_action, '\0', sizeof (sig_int_action));
887         sig_int_action.sa_handler = cpy_int_handler;
888         sigaction (SIGINT, &sig_int_action, &old);
889         
890         sigemptyset(&sigset);
891         sigaddset(&sigset, SIGINT);
892         pthread_sigmask(SIG_UNBLOCK, &sigset, NULL);
893         PyEval_AcquireThread(state);
894         if (PyImport_ImportModule("readline") == NULL) {
895                 /* This interactive session will suck. */
896                 cpy_log_exception("interactive session init");
897         }
898         PyRun_InteractiveLoop(stdin, "<stdin>");
899         PyErr_Print();
900         PyEval_ReleaseThread(state);
901         NOTICE("python: Interactive interpreter exited, stopping collectd ...");
902         /* Restore the original collectd SIGINT handler and raise SIGINT.
903          * The main thread still has SIGINT blocked and there's nothing we
904          * can do about that so this thread will handle it. But that's not
905          * important, except that it won't interrupt the main loop and so
906          * it might take a few seconds before collectd really shuts down. */
907         sigaction (SIGINT, &old, NULL);
908         raise(SIGINT);
909         pause();
910         return NULL;
911 }
912
913 static int cpy_init(void) {
914         cpy_callback_t *c;
915         PyObject *ret;
916         static pthread_t thread;
917         sigset_t sigset;
918         
919         if (!Py_IsInitialized()) {
920                 WARNING("python: Plugin loaded but not configured.");
921                 plugin_unregister_shutdown("python");
922                 return 0;
923         }
924         PyEval_InitThreads();
925         /* Now it's finally OK to use python threads. */
926         for (c = cpy_init_callbacks; c; c = c->next) {
927                 ret = PyObject_CallFunctionObjArgs(c->callback, c->data, (void *) 0); /* New reference. */
928                 if (ret == NULL)
929                         cpy_log_exception("init callback");
930                 else
931                         Py_DECREF(ret);
932         }
933         sigemptyset(&sigset);
934         sigaddset(&sigset, SIGINT);
935         pthread_sigmask(SIG_BLOCK, &sigset, NULL);
936         state = PyEval_SaveThread();
937         if (do_interactive) {
938                 if (plugin_thread_create(&thread, NULL, cpy_interactive, NULL)) {
939                         ERROR("python: Error creating thread for interactive interpreter.");
940                 }
941         }
942
943         return 0;
944 }
945
946 static PyObject *cpy_oconfig_to_pyconfig(oconfig_item_t *ci, PyObject *parent) {
947         int i;
948         PyObject *item, *values, *children, *tmp;
949         
950         if (parent == NULL)
951                 parent = Py_None;
952         
953         values = PyTuple_New(ci->values_num); /* New reference. */
954         for (i = 0; i < ci->values_num; ++i) {
955                 if (ci->values[i].type == OCONFIG_TYPE_STRING) {
956                         PyTuple_SET_ITEM(values, i, cpy_string_to_unicode_or_bytes(ci->values[i].value.string));
957                 } else if (ci->values[i].type == OCONFIG_TYPE_NUMBER) {
958                         PyTuple_SET_ITEM(values, i, PyFloat_FromDouble(ci->values[i].value.number));
959                 } else if (ci->values[i].type == OCONFIG_TYPE_BOOLEAN) {
960                         PyTuple_SET_ITEM(values, i, PyBool_FromLong(ci->values[i].value.boolean));
961                 }
962         }
963         
964         tmp = cpy_string_to_unicode_or_bytes(ci->key);
965         item = PyObject_CallFunction((void *) &ConfigType, "NONO", tmp, parent, values, Py_None);
966         if (item == NULL)
967                 return NULL;
968         children = PyTuple_New(ci->children_num); /* New reference. */
969         for (i = 0; i < ci->children_num; ++i) {
970                 PyTuple_SET_ITEM(children, i, cpy_oconfig_to_pyconfig(ci->children + i, item));
971         }
972         tmp = ((Config *) item)->children;
973         ((Config *) item)->children = children;
974         Py_XDECREF(tmp);
975         return item;
976 }
977
978 #ifdef IS_PY3K
979 static struct PyModuleDef collectdmodule = {
980         PyModuleDef_HEAD_INIT,
981         "collectd",   /* name of module */
982         "The python interface to collectd", /* module documentation, may be NULL */
983         -1,
984         cpy_methods
985 };
986
987 PyMODINIT_FUNC PyInit_collectd(void) {
988         return PyModule_Create(&collectdmodule);
989 }
990 #endif
991
992 static int cpy_init_python() {
993         char *argv = "";
994         PyObject *sys;
995         PyObject *module;
996
997 #ifdef IS_PY3K
998         /* Add a builtin module, before Py_Initialize */
999         PyImport_AppendInittab("collectd", PyInit_collectd);
1000 #endif
1001         
1002         Py_Initialize();
1003         
1004         PyType_Ready(&ConfigType);
1005         PyType_Ready(&PluginDataType);
1006         ValuesType.tp_base = &PluginDataType;
1007         PyType_Ready(&ValuesType);
1008         NotificationType.tp_base = &PluginDataType;
1009         PyType_Ready(&NotificationType);
1010         SignedType.tp_base = &PyLong_Type;
1011         PyType_Ready(&SignedType);
1012         UnsignedType.tp_base = &PyLong_Type;
1013         PyType_Ready(&UnsignedType);
1014         sys = PyImport_ImportModule("sys"); /* New reference. */
1015         if (sys == NULL) {
1016                 cpy_log_exception("python initialization");
1017                 return 1;
1018         }
1019         sys_path = PyObject_GetAttrString(sys, "path"); /* New reference. */
1020         Py_DECREF(sys);
1021         if (sys_path == NULL) {
1022                 cpy_log_exception("python initialization");
1023                 return 1;
1024         }
1025         PySys_SetArgv(1, &argv);
1026         PyList_SetSlice(sys_path, 0, 1, NULL);
1027
1028 #ifdef IS_PY3K
1029         module = PyImport_ImportModule("collectd");
1030 #else
1031         module = Py_InitModule("collectd", cpy_methods); /* Borrowed reference. */
1032 #endif
1033         PyModule_AddObject(module, "Config", (void *) &ConfigType); /* Steals a reference. */
1034         PyModule_AddObject(module, "Values", (void *) &ValuesType); /* Steals a reference. */
1035         PyModule_AddObject(module, "Notification", (void *) &NotificationType); /* Steals a reference. */
1036         PyModule_AddObject(module, "Signed", (void *) &SignedType); /* Steals a reference. */
1037         PyModule_AddObject(module, "Unsigned", (void *) &UnsignedType); /* Steals a reference. */
1038         PyModule_AddIntConstant(module, "LOG_DEBUG", LOG_DEBUG);
1039         PyModule_AddIntConstant(module, "LOG_INFO", LOG_INFO);
1040         PyModule_AddIntConstant(module, "LOG_NOTICE", LOG_NOTICE);
1041         PyModule_AddIntConstant(module, "LOG_WARNING", LOG_WARNING);
1042         PyModule_AddIntConstant(module, "LOG_ERROR", LOG_ERR);
1043         PyModule_AddIntConstant(module, "NOTIF_FAILURE", NOTIF_FAILURE);
1044         PyModule_AddIntConstant(module, "NOTIF_WARNING", NOTIF_WARNING);
1045         PyModule_AddIntConstant(module, "NOTIF_OKAY", NOTIF_OKAY);
1046         return 0;
1047 }
1048
1049 static int cpy_config(oconfig_item_t *ci) {
1050         int i;
1051         PyObject *tb;
1052
1053         /* Ok in theory we shouldn't do initialization at this point
1054          * but we have to. In order to give python scripts a chance
1055          * to register a config callback we need to be able to execute
1056          * python code during the config callback so we have to start
1057          * the interpreter here. */
1058         /* Do *not* use the python "thread" module at this point! */
1059
1060         if (!Py_IsInitialized() && cpy_init_python()) return 1;
1061
1062         for (i = 0; i < ci->children_num; ++i) {
1063                 oconfig_item_t *item = ci->children + i;
1064                 
1065                 if (strcasecmp(item->key, "Interactive") == 0) {
1066                         if (item->values_num != 1 || item->values[0].type != OCONFIG_TYPE_BOOLEAN)
1067                                 continue;
1068                         do_interactive = item->values[0].value.boolean;
1069                 } else if (strcasecmp(item->key, "Encoding") == 0) {
1070                         if (item->values_num != 1 || item->values[0].type != OCONFIG_TYPE_STRING)
1071                                 continue;
1072                         /* Why is this even necessary? And undocumented? */
1073                         if (PyUnicode_SetDefaultEncoding(item->values[0].value.string))
1074                                 cpy_log_exception("setting default encoding");
1075                 } else if (strcasecmp(item->key, "LogTraces") == 0) {
1076                         if (item->values_num != 1 || item->values[0].type != OCONFIG_TYPE_BOOLEAN)
1077                                 continue;
1078                         if (!item->values[0].value.boolean) {
1079                                 Py_XDECREF(cpy_format_exception);
1080                                 cpy_format_exception = NULL;
1081                                 continue;
1082                         }
1083                         if (cpy_format_exception)
1084                                 continue;
1085                         tb = PyImport_ImportModule("traceback"); /* New reference. */
1086                         if (tb == NULL) {
1087                                 cpy_log_exception("python initialization");
1088                                 continue;
1089                         }
1090                         cpy_format_exception = PyObject_GetAttrString(tb, "format_exception"); /* New reference. */
1091                         Py_DECREF(tb);
1092                         if (cpy_format_exception == NULL)
1093                                 cpy_log_exception("python initialization");
1094                 } else if (strcasecmp(item->key, "ModulePath") == 0) {
1095                         char *dir = NULL;
1096                         PyObject *dir_object;
1097                         
1098                         if (cf_util_get_string(item, &dir) != 0) 
1099                                 continue;
1100                         dir_object = cpy_string_to_unicode_or_bytes(dir); /* New reference. */
1101                         if (dir_object == NULL) {
1102                                 ERROR("python plugin: Unable to convert \"%s\" to "
1103                                       "a python object.", dir);
1104                                 free(dir);
1105                                 cpy_log_exception("python initialization");
1106                                 continue;
1107                         }
1108                         if (PyList_Append(sys_path, dir_object) != 0) {
1109                                 ERROR("python plugin: Unable to append \"%s\" to "
1110                                       "python module path.", dir);
1111                                 cpy_log_exception("python initialization");
1112                         }
1113                         Py_DECREF(dir_object);
1114                         free(dir);
1115                 } else if (strcasecmp(item->key, "Import") == 0) {
1116                         char *module_name = NULL;
1117                         PyObject *module;
1118                         
1119                         if (cf_util_get_string(item, &module_name) != 0) 
1120                                 continue;
1121                         module = PyImport_ImportModule(module_name); /* New reference. */
1122                         if (module == NULL) {
1123                                 ERROR("python plugin: Error importing module \"%s\".", module_name);
1124                                 cpy_log_exception("importing module");
1125                         }
1126                         free(module_name);
1127                         Py_XDECREF(module);
1128                 } else if (strcasecmp(item->key, "Module") == 0) {
1129                         char *name = NULL;
1130                         cpy_callback_t *c;
1131                         PyObject *ret;
1132                         
1133                         if (cf_util_get_string(item, &name) != 0)
1134                                 continue;
1135                         for (c = cpy_config_callbacks; c; c = c->next) {
1136                                 if (strcasecmp(c->name + 7, name) == 0)
1137                                         break;
1138                         }
1139                         if (c == NULL) {
1140                                 WARNING("python plugin: Found a configuration for the \"%s\" plugin, "
1141                                         "but the plugin isn't loaded or didn't register "
1142                                         "a configuration callback.", name);
1143                                 free(name);
1144                                 continue;
1145                         }
1146                         free(name);
1147                         if (c->data == NULL)
1148                                 ret = PyObject_CallFunction(c->callback, "N",
1149                                         cpy_oconfig_to_pyconfig(item, NULL)); /* New reference. */
1150                         else
1151                                 ret = PyObject_CallFunction(c->callback, "NO",
1152                                         cpy_oconfig_to_pyconfig(item, NULL), c->data); /* New reference. */
1153                         if (ret == NULL)
1154                                 cpy_log_exception("loading module");
1155                         else
1156                                 Py_DECREF(ret);
1157                 } else {
1158                         WARNING("python plugin: Ignoring unknown config key \"%s\".", item->key);
1159                 }
1160         }
1161         return 0;
1162 }
1163
1164 void module_register(void) {
1165         plugin_register_complex_config("python", cpy_config);
1166         plugin_register_init("python", cpy_init);
1167         plugin_register_shutdown("python", cpy_shutdown);
1168 }