typedef void* PyGILState_STATE;
#endif
+/**
+ * counter for python module instances
+ * incremented by pythonmod_init(...)
+ */
+int py_mod_count = 0;
+
+/** Python main thread */
+PyThreadState* mainthr;
+
/**
* Global state for the module.
*/
/** Python script filename. */
const char* fname;
- /** Python main thread */
- PyThreadState* mainthr;
/** Python module. */
PyObject* module;
int pythonmod_init(struct module_env* env, int id)
{
+ int py_mod_idx = py_mod_count++;
+
/* Initialize module */
FILE* script_py = NULL;
PyObject* py_init_arg, *res;
PyGILState_STATE gil;
- int init_standard = 1;
+ int init_standard = 1, i = 0;
+
+ struct config_strlist* cfg_item = env->cfg->python_script;
struct pythonmod_env* pe = (struct pythonmod_env*)calloc(1, sizeof(struct pythonmod_env));
if (!pe)
env->modinfo[id] = (void*) pe;
/* Initialize module */
- pe->fname = env->cfg->python_script;
+ pe->fname=NULL; i = 0;
+ while (cfg_item!=NULL) {
+ if (py_mod_idx==i++) {
+ pe->fname=cfg_item->str;
+ break;
+ }
+ cfg_item = cfg_item->next;
+ }
if(pe->fname==NULL || pe->fname[0]==0) {
- log_err("pythonmod: no script given.");
+ log_err("pythonmod[%d]: no script given.", py_mod_idx);
return 0;
}
/* Initialize Python libraries */
- if (!Py_IsInitialized())
+ if (py_mod_count==1 && !Py_IsInitialized())
{
#if PY_MAJOR_VERSION >= 3
wchar_t progname[8];
Py_Initialize();
PyEval_InitThreads();
SWIG_init();
- pe->mainthr = PyEval_SaveThread();
+ mainthr = PyEval_SaveThread();
}
gil = PyGILState_Ensure();
- /* Initialize Python */
- 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);
- }
- PyRun_SimpleString("sys.path.append('"RUN_DIR"') \n");
- PyRun_SimpleString("sys.path.append('"SHARE_DIR"') \n");
- PyRun_SimpleString("import distutils.sysconfig \n");
- 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");
- PyGILState_Release(gil);
- return 0;
+ if (py_mod_count==1) {
+ /* Initialize Python */
+ 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);
+ }
+ PyRun_SimpleString("sys.path.append('"RUN_DIR"') \n");
+ PyRun_SimpleString("sys.path.append('"SHARE_DIR"') \n");
+ PyRun_SimpleString("import distutils.sysconfig \n");
+ 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");
+ PyGILState_Release(gil);
+ return 0;
+ }
}
/* Check Python file load */
(void)PyParser_SimpleParseFile(script_py, pe->fname, Py_file_input);
log_py_err();
PyGILState_Release(gil);
+ fclose(script_py);
return 0;
}
fclose(script_py);
Py_XDECREF(pe->data);
PyGILState_Release(gil);
- PyEval_RestoreThread(pe->mainthr);
- Py_Finalize();
- pe->mainthr = NULL;
+ if(--py_mod_count==0) {
+ PyEval_RestoreThread(mainthr);
+ Py_Finalize();
+ mainthr = NULL;
+ }
}
pe->fname = NULL;
free(pe);
else S_STR("control-key-file:", control_key_file)
else S_STR("control-cert-file:", control_cert_file)
else S_STR("module-config:", module_conf)
- else S_STR("python-script:", python_script)
+ else S_STRLIST("python-script:", python_script)
else S_YNO("disable-dnssec-lame-check:", disable_dnssec_lame_check)
#ifdef CLIENT_SUBNET
/* Can't set max subnet prefix here, since that value is used when
else O_YNO(opt, "unblock-lan-zones", unblock_lan_zones)
else O_YNO(opt, "insecure-lan-zones", insecure_lan_zones)
else O_DEC(opt, "max-udp-size", max_udp_size)
- else O_STR(opt, "python-script", python_script)
+ else O_LST(opt, "python-script", python_script)
else O_YNO(opt, "disable-dnssec-lame-check", disable_dnssec_lame_check)
else O_DEC(opt, "ip-ratelimit", ip_ratelimit)
else O_DEC(opt, "ratelimit", ratelimit)
free(cfg->dnstap_version);
config_deldblstrlist(cfg->ratelimit_for_domain);
config_deldblstrlist(cfg->ratelimit_below_domain);
+ config_delstrlist(cfg->python_script);
#ifdef USE_IPSECMOD
free(cfg->ipsecmod_hook);
config_delstrlist(cfg->ipsecmod_whitelist);
return 1;
}
+int
+cfg_strlist_append_ex(struct config_strlist** head, char* item)
+{
+ struct config_strlist *s;
+ if(!item || !head)
+ return 0;
+ s = (struct config_strlist*)calloc(1, sizeof(struct config_strlist));
+ if(!s)
+ return 0;
+ s->str = item;
+ s->next = NULL;
+
+ if (*head==NULL) {
+ *head = s;
+ } else {
+ struct config_strlist *last = *head;
+ while (last->next!=NULL) {
+ last = last->next;
+ }
+ last->next = s;
+ }
+
+ return 1;
+}
+
int
cfg_str2list_insert(struct config_str2list** head, char* item, char* i2)
{