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