diff options
Diffstat (limited to 'external/unbound/pythonmod/pythonmod.c')
-rw-r--r-- | external/unbound/pythonmod/pythonmod.c | 111 |
1 files changed, 66 insertions, 45 deletions
diff --git a/external/unbound/pythonmod/pythonmod.c b/external/unbound/pythonmod/pythonmod.c index 48dbc0169..dde7e54b2 100644 --- a/external/unbound/pythonmod/pythonmod.c +++ b/external/unbound/pythonmod/pythonmod.c @@ -1,22 +1,22 @@ /* * pythonmod.c: unbound module C wrapper - * + * * Copyright (c) 2009, Zdenek Vasicek (vasicek AT fit.vutbr.cz) * Marek Vavrusa (xvavru00 AT stud.fit.vutbr.cz) * * This software is open source. - * + * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: - * + * * * Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. - * + * * * Redistributions in binary form must reproduce the above copyright notice, * this list of conditions and the following disclaimer in the documentation * and/or other materials provided with the distribution. - * + * * * Neither the name of the organization nor the names of its * contributors may be used to endorse or promote products derived from this * software without specific prior written permission. @@ -63,7 +63,7 @@ typedef void* PyGILState_STATE; #endif /** - * Global state for the module. + * Global state for the module. */ struct pythonmod_env { @@ -112,10 +112,12 @@ int pythonmod_init(struct module_env* env, int id) { /* Initialize module */ FILE* script_py = NULL; - PyObject* py_cfg, *res; + PyObject* py_init_arg, *res; PyGILState_STATE gil; + int init_standard = 1; + struct pythonmod_env* pe = (struct pythonmod_env*)calloc(1, sizeof(struct pythonmod_env)); - if (!pe) + if (!pe) { log_err("pythonmod: malloc failure"); return 0; @@ -131,7 +133,7 @@ int pythonmod_init(struct module_env* env, int id) } /* Initialize Python libraries */ - if (!Py_IsInitialized()) + if (!Py_IsInitialized()) { #if PY_MAJOR_VERSION >= 3 wchar_t progname[8]; @@ -141,6 +143,9 @@ int pythonmod_init(struct module_env* env, int id) #endif Py_SetProgramName(progname); Py_NoSiteFlag = 1; +#if PY_MAJOR_VERSION >= 3 + PyImport_AppendInittab(SWIG_name, (void*)SWIG_init); +#endif Py_Initialize(); PyEval_InitThreads(); SWIG_init(); @@ -153,10 +158,10 @@ int pythonmod_init(struct module_env* env, int id) PyRun_SimpleString("import sys \n"); PyRun_SimpleString("sys.path.append('.') \n"); if(env->cfg->directory && env->cfg->directory[0]) { - char wdir[1524]; - snprintf(wdir, sizeof(wdir), "sys.path.append('%s') \n", - env->cfg->directory); - PyRun_SimpleString(wdir); + char wdir[1524]; + snprintf(wdir, sizeof(wdir), "sys.path.append('%s') \n", + env->cfg->directory); + PyRun_SimpleString(wdir); } PyRun_SimpleString("sys.path.append('"RUN_DIR"') \n"); PyRun_SimpleString("sys.path.append('"SHARE_DIR"') \n"); @@ -164,13 +169,13 @@ int pythonmod_init(struct module_env* env, int id) PyRun_SimpleString("sys.path.append(distutils.sysconfig.get_python_lib(1,0)) \n"); if (PyRun_SimpleString("from unboundmodule import *\n") < 0) { - log_err("pythonmod: cannot initialize core module: unboundmodule.py"); + log_err("pythonmod: cannot initialize core module: unboundmodule.py"); PyGILState_Release(gil); return 0; } /* Check Python file load */ - if ((script_py = fopen(pe->fname, "r")) == NULL) + if ((script_py = fopen(pe->fname, "r")) == NULL) { log_err("pythonmod: can't open file %s for reading", pe->fname); PyGILState_Release(gil); @@ -185,8 +190,8 @@ int pythonmod_init(struct module_env* env, int id) PyModule_AddObject(pe->module, "mod_env", pe->data); /* TODO: deallocation of pe->... if an error occurs */ - - if (PyRun_SimpleFile(script_py, pe->fname) < 0) + + if (PyRun_SimpleFile(script_py, pe->fname) < 0) { log_err("pythonmod: can't parse Python script %s", pe->fname); PyGILState_Release(gil); @@ -195,41 +200,57 @@ int pythonmod_init(struct module_env* env, int id) fclose(script_py); - if ((pe->func_init = PyDict_GetItemString(pe->dict, "init")) == NULL) + if ((pe->func_init = PyDict_GetItemString(pe->dict, "init_standard")) == NULL) { - log_err("pythonmod: function init is missing in %s", pe->fname); - PyGILState_Release(gil); - return 0; + init_standard = 0; + if ((pe->func_init = PyDict_GetItemString(pe->dict, "init")) == NULL) + { + log_err("pythonmod: function init is missing in %s", pe->fname); + PyGILState_Release(gil); + return 0; + } } - if ((pe->func_deinit = PyDict_GetItemString(pe->dict, "deinit")) == NULL) + if ((pe->func_deinit = PyDict_GetItemString(pe->dict, "deinit")) == NULL) { log_err("pythonmod: function deinit is missing in %s", pe->fname); PyGILState_Release(gil); return 0; } - if ((pe->func_operate = PyDict_GetItemString(pe->dict, "operate")) == NULL) + if ((pe->func_operate = PyDict_GetItemString(pe->dict, "operate")) == NULL) { log_err("pythonmod: function operate is missing in %s", pe->fname); PyGILState_Release(gil); return 0; } - if ((pe->func_inform = PyDict_GetItemString(pe->dict, "inform_super")) == NULL) + if ((pe->func_inform = PyDict_GetItemString(pe->dict, "inform_super")) == NULL) { log_err("pythonmod: function inform_super is missing in %s", pe->fname); PyGILState_Release(gil); return 0; } - py_cfg = SWIG_NewPointerObj((void*) env->cfg, SWIGTYPE_p_config_file, 0); - res = PyObject_CallFunction(pe->func_init, "iO", id, py_cfg); - if (PyErr_Occurred()) + if (init_standard) + { + py_init_arg = SWIG_NewPointerObj((void*) env, SWIGTYPE_p_module_env, 0); + } + else + { + py_init_arg = SWIG_NewPointerObj((void*) env->cfg, + SWIGTYPE_p_config_file, 0); + } + res = PyObject_CallFunction(pe->func_init, "iO", id, py_init_arg); + if (PyErr_Occurred()) { log_err("pythonmod: Exception occurred in function init"); PyErr_Print(); + Py_XDECREF(res); + Py_XDECREF(py_init_arg); + PyGILState_Release(gil); + return 0; } Py_XDECREF(res); - Py_XDECREF(py_cfg); + Py_XDECREF(py_init_arg); PyGILState_Release(gil); return 1; @@ -283,20 +304,20 @@ void pythonmod_inform_super(struct module_qstate* qstate, int id, struct module_ py_qstate = SWIG_NewPointerObj((void*) qstate, SWIGTYPE_p_module_qstate, 0); py_sqstate = SWIG_NewPointerObj((void*) super, SWIGTYPE_p_module_qstate, 0); - res = PyObject_CallFunction(pe->func_inform, "iOOO", id, py_qstate, + res = PyObject_CallFunction(pe->func_inform, "iOOO", id, py_qstate, py_sqstate, pq->data); - if (PyErr_Occurred()) + if (PyErr_Occurred()) { log_err("pythonmod: Exception occurred in function inform_super"); PyErr_Print(); qstate->ext_state[id] = module_error; - } - else if ((res == NULL) || (!PyObject_IsTrue(res))) + } + else if ((res == NULL) || (!PyObject_IsTrue(res))) { log_err("pythonmod: python returned bad code in inform_super"); qstate->ext_state[id] = module_error; - } + } Py_XDECREF(res); Py_XDECREF(py_sqstate); @@ -305,7 +326,7 @@ void pythonmod_inform_super(struct module_qstate* qstate, int id, struct module_ PyGILState_Release(gil); } -void pythonmod_operate(struct module_qstate* qstate, enum module_ev event, +void pythonmod_operate(struct module_qstate* qstate, enum module_ev event, int id, struct outbound_entry* ATTR_UNUSED(outbound)) { struct pythonmod_env* pe = (struct pythonmod_env*)qstate->env->modinfo[id]; @@ -314,10 +335,10 @@ void pythonmod_operate(struct module_qstate* qstate, enum module_ev event, PyGILState_STATE gil = PyGILState_Ensure(); if ( pq == NULL) - { + { /* create qstate */ pq = qstate->minfo[id] = malloc(sizeof(struct pythonmod_qstate)); - + /* Initialize per query data */ pq->data = Py_None; Py_INCREF(pq->data); @@ -325,19 +346,19 @@ void pythonmod_operate(struct module_qstate* qstate, enum module_ev event, /* Call operate */ py_qstate = SWIG_NewPointerObj((void*) qstate, SWIGTYPE_p_module_qstate, 0); - res = PyObject_CallFunction(pe->func_operate, "iiOO", id, (int) event, + res = PyObject_CallFunction(pe->func_operate, "iiOO", id, (int) event, py_qstate, pq->data); - if (PyErr_Occurred()) + if (PyErr_Occurred()) { log_err("pythonmod: Exception occurred in function operate, event: %s", strmodulevent(event)); PyErr_Print(); qstate->ext_state[id] = module_error; - } - else if ((res == NULL) || (!PyObject_IsTrue(res))) + } + else if ((res == NULL) || (!PyObject_IsTrue(res))) { log_err("pythonmod: python returned bad code, event: %s", strmodulevent(event)); qstate->ext_state[id] = module_error; - } + } Py_XDECREF(res); Py_XDECREF(py_qstate); @@ -351,7 +372,7 @@ void pythonmod_clear(struct module_qstate* qstate, int id) return; pq = (struct pythonmod_qstate*)qstate->minfo[id]; - verbose(VERB_ALGO, "pythonmod: clear, id: %d, pq:%lX", id, + verbose(VERB_ALGO, "pythonmod: clear, id: %d, pq:%lX", id, (unsigned long int)pq); if(pq != NULL) { @@ -368,7 +389,7 @@ void pythonmod_clear(struct module_qstate* qstate, int id) size_t pythonmod_get_mem(struct module_env* env, int id) { struct pythonmod_env* pe = (struct pythonmod_env*)env->modinfo[id]; - verbose(VERB_ALGO, "pythonmod: get_mem, id: %d, pe:%lX", id, + verbose(VERB_ALGO, "pythonmod: get_mem, id: %d, pe:%lX", id, (unsigned long int)pe); if(!pe) return 0; @@ -376,11 +397,11 @@ size_t pythonmod_get_mem(struct module_env* env, int id) } /** - * The module function block + * The module function block */ static struct module_func_block pythonmod_block = { "python", - &pythonmod_init, &pythonmod_deinit, &pythonmod_operate, &pythonmod_inform_super, + &pythonmod_init, &pythonmod_deinit, &pythonmod_operate, &pythonmod_inform_super, &pythonmod_clear, &pythonmod_get_mem }; |