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