mkclass_target(dynamicobject.ti dynamicobject.th)
mkclass_target(filelogger.ti filelogger.th)
mkclass_target(logger.ti logger.th)
-mkclass_target(script.ti script.th)
mkclass_target(streamlogger.ti streamlogger.th)
mkclass_target(sysloglogger.ti sysloglogger.th)
convert.cpp dictionary.cpp dynamicobject.cpp dynamicobject.th dynamictype.cpp
exception.cpp fifo.cpp filelogger.cpp filelogger.th logger.cpp logger.th
netstring.cpp networkstream.cpp object.cpp objectlock.cpp process.cpp
- process-unix.cpp process-windows.cpp qstring.cpp ringbuffer.cpp script.cpp
- script.th scriptfunction.cpp scriptfunctionwrapper.cpp scriptinterpreter.cpp
- scriptlanguage.cpp scriptutils.cpp scriptvariable.cpp serializer.cpp socket.cpp stacktrace.cpp
+ process-unix.cpp process-windows.cpp qstring.cpp ringbuffer.cpp
+ scriptfunction.cpp scriptfunctionwrapper.cpp scriptutils.cpp
+ scriptvariable.cpp serializer.cpp socket.cpp stacktrace.cpp
statsfunction.cpp stdiostream.cpp stream_bio.cpp stream.cpp streamlogger.cpp streamlogger.th
sysloglogger.cpp sysloglogger.th tcpsocket.cpp threadpool.cpp timer.cpp
tlsstream.cpp tlsutility.cpp type.cpp unixsocket.cpp utility.cpp value.cpp
+++ /dev/null
-/******************************************************************************
- * Icinga 2 *
- * Copyright (C) 2012-2014 Icinga Development Team (http://www.icinga.org) *
- * *
- * This program is free software; you can redistribute it and/or *
- * modify it under the terms of the GNU General Public License *
- * as published by the Free Software Foundation; either version 2 *
- * of the License, or (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program; if not, write to the Free Software Foundation *
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. *
- ******************************************************************************/
-
-#include "base/script.h"
-#include "base/scriptlanguage.h"
-#include "base/dynamictype.h"
-#include "base/logger_fwd.h"
-#include "base/objectlock.h"
-#include "base/debug.h"
-
-using namespace icinga;
-
-REGISTER_TYPE(Script);
-
-void Script::Start(void)
-{
- DynamicObject::Start();
-
- ASSERT(OwnsLock());
-
- SpawnInterpreter();
-}
-
-void Script::SpawnInterpreter(void)
-{
- Log(LogInformation, "base", "Reloading script '" + GetName() + "'");
-
- ScriptLanguage::Ptr language = ScriptLanguage::GetByName(GetLanguage());
- m_Interpreter = language->CreateInterpreter(GetSelf());
-}
+++ /dev/null
-/******************************************************************************
- * Icinga 2 *
- * Copyright (C) 2012-2014 Icinga Development Team (http://www.icinga.org) *
- * *
- * This program is free software; you can redistribute it and/or *
- * modify it under the terms of the GNU General Public License *
- * as published by the Free Software Foundation; either version 2 *
- * of the License, or (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program; if not, write to the Free Software Foundation *
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. *
- ******************************************************************************/
-
-#ifndef SCRIPT_H
-#define SCRIPT_H
-
-#include "base/i2-base.h"
-#include "base/script.th"
-
-namespace icinga
-{
-
-class ScriptInterpreter;
-
-/**
- * A script.
- *
- * @ingroup base
- */
-class I2_BASE_API Script : public ObjectImpl<Script>
-{
-public:
- DECLARE_PTR_TYPEDEFS(Script);
-
- virtual void Start(void);
-
-private:
- shared_ptr<ScriptInterpreter> m_Interpreter;
-
- void SpawnInterpreter(void);
-};
-
-}
-
-#endif /* SCRIPT_H */
+++ /dev/null
-#include "base/dynamicobject.h"
-
-namespace icinga
-{
-
-class Script : DynamicObject
-{
- [config] String language;
- [config] String "code";
-};
-
-}
+++ /dev/null
-/******************************************************************************
- * Icinga 2 *
- * Copyright (C) 2012-2014 Icinga Development Team (http://www.icinga.org) *
- * *
- * This program is free software; you can redistribute it and/or *
- * modify it under the terms of the GNU General Public License *
- * as published by the Free Software Foundation; either version 2 *
- * of the License, or (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program; if not, write to the Free Software Foundation *
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. *
- ******************************************************************************/
-
-#include "base/scriptinterpreter.h"
-#include "base/scriptfunction.h"
-#include "base/objectlock.h"
-#include <boost/bind.hpp>
-#include <boost/foreach.hpp>
-
-using namespace icinga;
-
-ScriptInterpreter::ScriptInterpreter(const Script::Ptr&)
-{ }
-
-ScriptInterpreter::~ScriptInterpreter(void)
-{
- BOOST_FOREACH(const String& function, m_SubscribedFunctions) {
- ScriptFunction::Unregister(function);
- }
-}
-
-void ScriptInterpreter::SubscribeFunction(const String& name)
-{
- ObjectLock olock(this);
-
- m_SubscribedFunctions.insert(name);
- ScriptFunction::Register(name, boost::bind(&ScriptInterpreter::ProcessCall, this, name, _1));
-}
-
-void ScriptInterpreter::UnsubscribeFunction(const String& name)
-{
- ObjectLock olock(this);
-
- m_SubscribedFunctions.erase(name);
- ScriptFunction::Unregister(name);
-}
+++ /dev/null
-/******************************************************************************
- * Icinga 2 *
- * Copyright (C) 2012-2014 Icinga Development Team (http://www.icinga.org) *
- * *
- * This program is free software; you can redistribute it and/or *
- * modify it under the terms of the GNU General Public License *
- * as published by the Free Software Foundation; either version 2 *
- * of the License, or (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program; if not, write to the Free Software Foundation *
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. *
- ******************************************************************************/
-
-#ifndef SCRIPTINTERPRETER_H
-#define SCRIPTINTERPRETER_H
-
-#include "base/i2-base.h"
-#include "base/script.h"
-#include <vector>
-#include <set>
-
-namespace icinga
-{
-
-/**
- * A script interpreter.
- *
- * @ingroup base
- */
-class I2_BASE_API ScriptInterpreter : public Object
-{
-public:
- DECLARE_PTR_TYPEDEFS(ScriptInterpreter);
-
- ~ScriptInterpreter(void);
-
-protected:
- ScriptInterpreter(const Script::Ptr& script);
-
- virtual Value ProcessCall(const String& function, const std::vector<Value>& arguments) = 0;
-
- void SubscribeFunction(const String& name);
- void UnsubscribeFunction(const String& name);
-
-private:
- std::set<String> m_SubscribedFunctions;
-};
-
-}
-
-#endif /* SCRIPTINTERPRETER_H */
+++ /dev/null
-/******************************************************************************
- * Icinga 2 *
- * Copyright (C) 2012-2014 Icinga Development Team (http://www.icinga.org) *
- * *
- * This program is free software; you can redistribute it and/or *
- * modify it under the terms of the GNU General Public License *
- * as published by the Free Software Foundation; either version 2 *
- * of the License, or (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program; if not, write to the Free Software Foundation *
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. *
- ******************************************************************************/
-
-#include "base/scriptlanguage.h"
-
-using namespace icinga;
-
-ScriptLanguage::ScriptLanguage(void)
-{ }
-
-void ScriptLanguage::Register(const String& name, const ScriptLanguage::Ptr& language)
-{
- boost::mutex::scoped_lock lock(GetMutex());
-
- GetLanguages()[name] = language;
-}
-
-void ScriptLanguage::Unregister(const String& name)
-{
- boost::mutex::scoped_lock lock(GetMutex());
-
- GetLanguages().erase(name);
-}
-
-ScriptLanguage::Ptr ScriptLanguage::GetByName(const String& name)
-{
- boost::mutex::scoped_lock lock(GetMutex());
-
- std::map<String, ScriptLanguage::Ptr>::iterator it;
-
- it = GetLanguages().find(name);
-
- if (it == GetLanguages().end())
- return ScriptLanguage::Ptr();
-
- return it->second;
-}
-
-boost::mutex& ScriptLanguage::GetMutex(void)
-{
- static boost::mutex mutex;
- return mutex;
-}
-
-std::map<String, ScriptLanguage::Ptr>& ScriptLanguage::GetLanguages(void)
-{
- static std::map<String, ScriptLanguage::Ptr> languages;
- return languages;
-}
+++ /dev/null
-/******************************************************************************
- * Icinga 2 *
- * Copyright (C) 2012-2014 Icinga Development Team (http://www.icinga.org) *
- * *
- * This program is free software; you can redistribute it and/or *
- * modify it under the terms of the GNU General Public License *
- * as published by the Free Software Foundation; either version 2 *
- * of the License, or (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program; if not, write to the Free Software Foundation *
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. *
- ******************************************************************************/
-
-#ifndef SCRIPTLANGUAGE_H
-#define SCRIPTLANGUAGE_H
-
-#include "base/i2-base.h"
-#include "base/scriptinterpreter.h"
-#include <map>
-
-namespace icinga
-{
-
-/**
- * A scripting language.
- *
- * @ingroup base
- */
-class I2_BASE_API ScriptLanguage : public Object
-{
-public:
- DECLARE_PTR_TYPEDEFS(ScriptLanguage);
-
- static void Register(const String& name, const ScriptLanguage::Ptr& language);
- static void Unregister(const String& name);
- static ScriptLanguage::Ptr GetByName(const String& name);
-
- virtual ScriptInterpreter::Ptr CreateInterpreter(const Script::Ptr& script) = 0;
-
- void SubscribeFunction(const String& name);
- void UnsubscribeFunction(const String& name);
-
-protected:
- ScriptLanguage(void);
-
-private:
- static boost::mutex& GetMutex(void);
- static std::map<String, ScriptLanguage::Ptr>& GetLanguages(void);
-};
-
-/**
- * Helper class for registering ScriptLanguage implementation classes.
- *
- * @ingroup base
- */
-class RegisterLanguageHelper
-{
-public:
- RegisterLanguageHelper(const String& name, const ScriptLanguage::Ptr& language)
- {
- if (!ScriptLanguage::GetByName(name))
- ScriptLanguage::Register(name, language);
- }
-};
-
-#define REGISTER_SCRIPTLANGUAGE(name, klass) \
- static RegisterLanguageHelper g_RegisterSL_ ## type(name, make_shared<klass>())
-
-}
-
-#endif /* SCRIPTLANGUAGE_H */
+++ /dev/null
-/******************************************************************************
- * Icinga 2 *
- * Copyright (C) 2012-2014 Icinga Development Team (http://www.icinga.org) *
- * *
- * This program is free software; you can redistribute it and/or *
- * modify it under the terms of the GNU General Public License *
- * as published by the Free Software Foundation; either version 2 *
- * of the License, or (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program; if not, write to the Free Software Foundation *
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. *
- ******************************************************************************/
-
-#include "python/pythoninterpreter.h"
-#include "base/objectlock.h"
-#include "base/utility.h"
-#include <boost/foreach.hpp>
-
-using namespace icinga;
-
-PythonInterpreter::PythonInterpreter(const PythonLanguage::Ptr& language,
- const Script::Ptr& script)
- : ScriptInterpreter(script), m_Language(language), m_ThreadState(NULL)
-{
- PyEval_AcquireLock();
- PythonInterpreter *interp = m_Language->GetCurrentInterpreter();
- m_Language->SetCurrentInterpreter(this);
-
- PyInterpreterState *pinterp = m_Language->GetMainThreadState()->interp;
- m_ThreadState = PyThreadState_New(pinterp);
-
- (void) PyThreadState_Swap(m_ThreadState);
- PyRun_SimpleString(script->GetCode().CStr());
- (void) PyThreadState_Swap(NULL);
-
- m_Language->SetCurrentInterpreter(interp);
- PyEval_ReleaseLock();
-}
-
-PythonInterpreter::~PythonInterpreter(void)
-{
- PyEval_AcquireLock();
-
- (void) PyThreadState_Swap(NULL);
-
- PyThreadState_Clear(m_ThreadState);
- PyThreadState_Delete(m_ThreadState);
-
- PyEval_ReleaseLock();
-}
-
-void PythonInterpreter::RegisterPythonFunction(const String& name, PyObject *function)
-{
- ObjectLock olock(this);
-
- SubscribeFunction(name);
-
- Py_INCREF(function);
- m_Functions[name] = function;
-}
-
-void PythonInterpreter::UnregisterPythonFunction(const String& name)
-{
- ObjectLock olock(this);
-
- UnsubscribeFunction(name);
-
- m_Functions.erase(name);
-}
-
-Value PythonInterpreter::ProcessCall(const String& function, const std::vector<Value>& arguments)
-{
- ObjectLock olock(this);
-
- PyEval_AcquireThread(m_ThreadState);
- PythonInterpreter *interp = m_Language->GetCurrentInterpreter();
- m_Language->SetCurrentInterpreter(this);
-
- try {
- std::map<String, PyObject *>::iterator it = m_Functions.find(function);
-
- if (it == m_Functions.end())
- BOOST_THROW_EXCEPTION(std::invalid_argument("Function '" + function + "' does not exist."));
-
- PyObject *func = it->second;
-
- PyObject *args = PyTuple_New(arguments.size());
-
- int i = 0;
- BOOST_FOREACH(const Value& argument, arguments) {
- PyObject *arg = PythonLanguage::MarshalToPython(argument);
- PyTuple_SetItem(args, i, arg);
- }
-
- PyObject *result = PyObject_CallObject(func, args);
-
- Py_DECREF(args);
-
- if (PyErr_Occurred()) {
- PyObject *ptype, *pvalue, *ptraceback;
-
- PyErr_Fetch(&ptype, &pvalue, &ptraceback);
-
- String msg = m_Language->ExceptionInfoToString(ptype, pvalue, ptraceback);
-
- Py_XDECREF(ptype);
- Py_XDECREF(pvalue);
- Py_XDECREF(ptraceback);
-
- BOOST_THROW_EXCEPTION(std::runtime_error("Error in Python script: " + msg));
- }
-
- Value vresult = PythonLanguage::MarshalFromPython(result);
- Py_DECREF(result);
-
- m_Language->SetCurrentInterpreter(interp);
- PyEval_ReleaseThread(m_ThreadState);
-
- return vresult;
- } catch (...) {
- m_Language->SetCurrentInterpreter(interp);
- PyEval_ReleaseThread(m_ThreadState);
-
- throw;
- }
-}
+++ /dev/null
-/******************************************************************************
- * Icinga 2 *
- * Copyright (C) 2012-2014 Icinga Development Team (http://www.icinga.org) *
- * *
- * This program is free software; you can redistribute it and/or *
- * modify it under the terms of the GNU General Public License *
- * as published by the Free Software Foundation; either version 2 *
- * of the License, or (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program; if not, write to the Free Software Foundation *
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. *
- ******************************************************************************/
-
-#ifndef PYTHONINTERPRETER_H
-#define PYTHONINTERPRETER_H
-
-#include <Python.h>
-#include "python/pythonlanguage.h"
-#include "base/scriptinterpreter.h"
-
-namespace icinga
-{
-
-/**
- * A Python script interpreter.
- *
- * @ingroup base
- */
-class PythonInterpreter : public ScriptInterpreter
-{
-public:
- DECLARE_PTR_TYPEDEFS(PythonInterpreter);
-
- PythonInterpreter(const PythonLanguage::Ptr& language, const Script::Ptr& script);
- ~PythonInterpreter(void);
-
- void RegisterPythonFunction(const String& name, PyObject *function);
- void UnregisterPythonFunction(const String& name);
-
-protected:
- PythonLanguage::Ptr m_Language;
- PyThreadState *m_ThreadState;
- std::map<String, PyObject *> m_Functions;
-
- virtual Value ProcessCall(const String& function, const std::vector<Value>& arguments);
-};
-
-}
-
-#endif /* PYTHONINTERPRETER_H */
+++ /dev/null
-/******************************************************************************
- * Icinga 2 *
- * Copyright (C) 2012-2014 Icinga Development Team (http://www.icinga.org) *
- * *
- * This program is free software; you can redistribute it and/or *
- * modify it under the terms of the GNU General Public License *
- * as published by the Free Software Foundation; either version 2 *
- * of the License, or (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program; if not, write to the Free Software Foundation *
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. *
- ******************************************************************************/
-
-#include "python/pythonlanguage.h"
-#include "python/pythoninterpreter.h"
-#include "base/scriptfunction.h"
-#include "base/dynamictype.h"
-#include "base/objectlock.h"
-#include "base/application.h"
-#include "base/array.h"
-#include <boost/foreach.hpp>
-#include <boost/tuple/tuple.hpp>
-
-using namespace icinga;
-
-PythonInterpreter *PythonLanguage::m_CurrentInterpreter;
-
-REGISTER_SCRIPTLANGUAGE("Python", PythonLanguage);
-
-PyMethodDef PythonLanguage::m_NativeMethodDef[] = {
- { "RegisterFunction", &PythonLanguage::PyRegisterFunction, METH_VARARGS, NULL },
- { NULL, NULL, 0, NULL } /* sentinel */
-};
-
-PythonLanguage::PythonLanguage(void)
- : ScriptLanguage(), m_Initialized(false)
-{ }
-
-void PythonLanguage::InitializeOnce(void)
-{
- ObjectLock olock(this);
-
- if (m_Initialized)
- return;
-
- Py_Initialize();
- PyEval_InitThreads();
-
- Py_SetProgramName(Application::GetArgV()[0]);
- PySys_SetArgv(Application::GetArgC(), Application::GetArgV());
-
- // See http://docs.python.org/2/c-api/init.html for an explanation.
- PyRun_SimpleString("import sys; sys.path.pop(0)\n");
-
- m_MainThreadState = PyThreadState_Get();
-
- m_TracebackModule = PyImport_ImportModule("traceback");
-
- m_NativeModule = Py_InitModule("ire", m_NativeMethodDef);
-
- (void) PyThreadState_Swap(NULL);
- PyEval_ReleaseLock();
-
- String name;
- BOOST_FOREACH(boost::tie(name, boost::tuples::ignore), ScriptFunctionRegistry::GetInstance()->GetItems()) {
- RegisterNativeFunction(name);
- }
-
- ScriptFunctionRegistry::GetInstance()->OnRegistered.connect(boost::bind(&PythonLanguage::RegisterNativeFunction, this, _1));
- ScriptFunctionRegistry::GetInstance()->OnUnregistered.connect(boost::bind(&PythonLanguage::UnregisterNativeFunction, this, _1));
-
- m_Initialized = true;
-}
-
-PythonLanguage::~PythonLanguage(void)
-{
- /* Due to how we're destructing objects it might not be safe to
- * call Py_Finalize() when the Icinga instance is being shut
- * down - so don't bother calling it. */
-}
-
-ScriptInterpreter::Ptr PythonLanguage::CreateInterpreter(const Script::Ptr& script)
-{
- InitializeOnce();
-
- return make_shared<PythonInterpreter>(GetSelf(), script);
-}
-
-PyThreadState *PythonLanguage::GetMainThreadState(void) const
-{
- ObjectLock olock(this);
-
- return m_MainThreadState;
-}
-
-PyObject *PythonLanguage::MarshalToPython(const Value& value)
-{
- String svalue;
-
- switch (value.GetType()) {
- case ValueEmpty:
- Py_INCREF(Py_None);
- return Py_None;
-
- case ValueNumber:
- return PyFloat_FromDouble(value);
-
- case ValueString:
- svalue = value;
- return PyString_FromString(svalue.CStr());
-
- case ValueObject:
- if (value.IsObjectType<DynamicObject>()) {
- DynamicObject::Ptr dobj = value;
-
- String type = dobj->GetType()->GetName();
- String name = dobj->GetName();
-
- PyObject *ptype = PyString_FromString(type.CStr());
-
- if (ptype == NULL)
- return NULL;
-
- PyObject *pname = PyString_FromString(name.CStr());
-
- if (pname == NULL) {
- Py_DECREF(ptype);
-
- return NULL;
- }
-
- PyObject *result = PyTuple_New(2);
-
- if (result == NULL) {
- Py_DECREF(ptype);
- Py_DECREF(pname);
-
- return NULL;
- }
-
- (void) PyTuple_SetItem(result, 0, ptype);
- (void) PyTuple_SetItem(result, 1, pname);
-
- return result;
- } else if (value.IsObjectType<Dictionary>()) {
- Dictionary::Ptr dict = value;
- ObjectLock olock(dict);
-
- PyObject *pdict = PyDict_New();
-
- String key;
- Value value;
- BOOST_FOREACH(boost::tie(key, value), dict) {
- PyObject *dv = MarshalToPython(value);
-
- PyDict_SetItemString(pdict, key.CStr(), dv);
-
- Py_DECREF(dv);
- }
-
- return pdict;
- } else if (value.IsObjectType<Array>()) {
- Array::Ptr arr = value;
- ObjectLock olock(arr);
-
- PyObject *plist = PyList_New(0);
-
- BOOST_FOREACH(const Value& value, arr) {
- PyObject *dv = MarshalToPython(value);
-
- PyList_Append(plist, dv);
-
- Py_DECREF(dv);
- }
-
- return plist;
- }
-
- Py_INCREF(Py_None);
- return Py_None;
-
- default:
- BOOST_THROW_EXCEPTION(std::invalid_argument("Unexpected variant type."));
- }
-}
-
-Value PythonLanguage::MarshalFromPython(PyObject *value)
-{
- if (value == Py_None) {
- return Empty;
- } else if (PyDict_Check(value)) {
- Dictionary::Ptr dict = make_shared<Dictionary>();
-
- PyObject *dk, *dv;
- Py_ssize_t pos = 0;
-
- while (PyDict_Next(value, &pos, &dk, &dv)) {
- String ik = PyString_AsString(dk);
- Value iv = MarshalFromPython(dv);
-
- dict->Set(ik, iv);
- }
-
- return dict;
- } else if (PyList_Check(value)) {
- Array::Ptr arr = make_shared<Array>();
-
- for (Py_ssize_t pos = 0; pos < PyList_Size(value); pos++) {
- PyObject *dv = PyList_GetItem(value, pos);
- Value iv = MarshalFromPython(dv);
-
- arr->Add(iv);
- }
-
- return arr;
- } else if (PyTuple_Check(value) && PyTuple_Size(value) == 2) {
- PyObject *ptype, *pname;
-
- ptype = PyTuple_GetItem(value, 0);
-
- if (ptype == NULL || !PyString_Check(ptype))
- BOOST_THROW_EXCEPTION(std::invalid_argument("Tuple must contain two strings."));
-
- String type = PyString_AsString(ptype);
-
- pname = PyTuple_GetItem(value, 1);
-
- if (pname == NULL || !PyString_Check(pname))
- BOOST_THROW_EXCEPTION(std::invalid_argument("Tuple must contain two strings."));
-
- String name = PyString_AsString(pname);
-
- DynamicType::Ptr dtype = DynamicType::GetByName(type);
-
- if (!dtype)
- BOOST_THROW_EXCEPTION(std::invalid_argument("Type '" + type + "' does not exist."));
-
- DynamicObject::Ptr object = dtype->GetObject(name);
-
- if (!object)
- BOOST_THROW_EXCEPTION(std::invalid_argument("Object '" + name + "' of type '" + type + "' does not exist."));
-
- return object;
- } else if (PyFloat_Check(value)) {
- return PyFloat_AsDouble(value);
- } else if (PyInt_Check(value)) {
- return PyInt_AsLong(value);
- } else if (PyString_Check(value)) {
- return PyString_AsString(value);
- } else {
- return Empty;
- }
-}
-
-String PythonLanguage::ExceptionInfoToString(PyObject *type, PyObject *exc, PyObject *tb) const
-{
- ObjectLock olock(this);
-
- PyObject *tb_dict = PyModule_GetDict(m_TracebackModule);
- PyObject *format_exception = PyDict_GetItemString(tb_dict, "format_exception");
-
- if (!PyCallable_Check(format_exception))
- return "Failed to format exception information.";
-
- PyObject *result = PyObject_CallFunctionObjArgs(format_exception, type, exc, tb, NULL);
-
- Py_DECREF(format_exception);
- Py_DECREF(tb_dict);
-
- if (!result || !PyList_Check(result)) {
- Py_XDECREF(result);
-
- return "format_exception() returned something that is not a list.";
- }
-
- String msg;
-
- for (Py_ssize_t i = 0; i < PyList_Size(result); i++) {
- PyObject *li = PyList_GetItem(result, i);
-
- if (!li || !PyString_Check(li)) {
- Py_DECREF(result);
-
- return "format_exception() returned something that is not a list of strings.";
- }
-
- msg += PyString_AsString(li);
- }
-
- Py_DECREF(result);
-
- return msg;
-}
-
-PyObject *PythonLanguage::PyCallNativeFunction(PyObject *self, PyObject *args)
-{
- assert(PyString_Check(self));
-
- char *name = PyString_AsString(self);
-
- ScriptFunction::Ptr function = ScriptFunctionRegistry::GetInstance()->GetItem(name);
-
- std::vector<Value> arguments;
-
- if (args != NULL) {
- if (PyTuple_Check(args)) {
- for (Py_ssize_t i = 0; i < PyTuple_Size(args); i++) {
- PyObject *arg = PyTuple_GetItem(args, i);
-
- arguments.push_back(MarshalFromPython(arg));
- }
- } else {
- arguments.push_back(MarshalFromPython(args));
- }
- }
-
- PyThreadState *tstate = PyEval_SaveThread();
-
- Value result;
-
- try {
- result = function->Invoke(arguments);
- } catch (const std::exception& ex) {
- PyEval_RestoreThread(tstate);
-
- String message = DiagnosticInformation(ex);
- PyErr_SetString(PyExc_RuntimeError, message.CStr());
-
- return NULL;
- }
-
- PyEval_RestoreThread(tstate);
-
- return MarshalToPython(result);
-}
-
-/**
- * Registers a native function.
- *
- * @param name The name of the native function.
- */
-void PythonLanguage::RegisterNativeFunction(const String& name)
-{
- ObjectLock olock(this);
-
- PyThreadState *tstate = PyThreadState_Swap(m_MainThreadState);
-
- PyObject *pname = PyString_FromString(name.CStr());
-
- PyMethodDef *md = new PyMethodDef;
- md->ml_name = strdup(name.CStr());
- md->ml_meth = &PythonLanguage::PyCallNativeFunction;
- md->ml_flags = METH_VARARGS;
- md->ml_doc = NULL;
-
- PyObject *pfunc = PyCFunction_NewEx(md, pname, m_NativeModule);
- (void) PyModule_AddObject(m_NativeModule, name.CStr(), pfunc);
-
- (void) PyThreadState_Swap(tstate);
-}
-
-/**
- * Unregisters a native function.
- *
- * @param name The name of the native function.
- */
-void PythonLanguage::UnregisterNativeFunction(const String& name)
-{
- ObjectLock olock(this);
-
- PyThreadState *tstate = PyThreadState_Swap(m_MainThreadState);
-
- PyObject *pdict = PyModule_GetDict(m_NativeModule);
- PyObject *pname = PyString_FromString(name.CStr());
- PyCFunctionObject *pfunc = (PyCFunctionObject *)PyDict_GetItem(pdict, pname);
-
- if (pfunc && PyCFunction_Check(pfunc)) {
- /* Eww. */
- free(const_cast<char *>(pfunc->m_ml->ml_name));
- delete pfunc->m_ml;
- }
-
- (void) PyDict_DelItem(pdict, pname);
- Py_DECREF(pname);
-
- (void) PyThreadState_Swap(tstate);
-}
-
-PyObject *PythonLanguage::PyRegisterFunction(PyObject *, PyObject *args)
-{
- char *name;
- PyObject *object;
-
- if (!PyArg_ParseTuple(args, "sO", &name, &object))
- return NULL;
-
- PythonInterpreter *interp = GetCurrentInterpreter();
-
- if (interp == NULL) {
- PyErr_SetString(PyExc_RuntimeError, "GetCurrentInterpreter() returned NULL.");
- return NULL;
- }
-
- if (!PyCallable_Check(object)) {
- PyErr_SetString(PyExc_RuntimeError, "Function object is not callable.");
- return NULL;
- }
-
- interp->RegisterPythonFunction(name, object);
-
- Py_INCREF(Py_None);
- return Py_None;
-}
-
-/**
- * Retrieves the current interpreter object. Caller must hold the GIL.
- *
- * @returns The current interpreter.
- */
-PythonInterpreter *PythonLanguage::GetCurrentInterpreter(void)
-{
- return m_CurrentInterpreter;
-}
-
-/**
- * Sets the current interpreter. Caller must hold the GIL.
- *
- * @param interpreter The interpreter.
- */
-void PythonLanguage::SetCurrentInterpreter(PythonInterpreter *interpreter)
-{
- m_CurrentInterpreter = interpreter;
-}
+++ /dev/null
-/******************************************************************************
- * Icinga 2 *
- * Copyright (C) 2012-2014 Icinga Development Team (http://www.icinga.org) *
- * *
- * This program is free software; you can redistribute it and/or *
- * modify it under the terms of the GNU General Public License *
- * as published by the Free Software Foundation; either version 2 *
- * of the License, or (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program; if not, write to the Free Software Foundation *
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. *
- ******************************************************************************/
-
-#ifndef PYTHONLANGUAGE_H
-#define PYTHONLANGUAGE_H
-
-#include <Python.h>
-#include "base/scriptlanguage.h"
-
-namespace icinga
-{
-
-class PythonInterpreter;
-
-/**
- * The Python scripting language.
- *
- * @ingroup base
- */
-class PythonLanguage : public ScriptLanguage
-{
-public:
- DECLARE_PTR_TYPEDEFS(PythonLanguage);
-
- PythonLanguage(void);
- ~PythonLanguage(void);
-
- virtual ScriptInterpreter::Ptr CreateInterpreter(const Script::Ptr& script);
-
- PyThreadState *GetMainThreadState(void) const;
-
- static PythonInterpreter *GetCurrentInterpreter(void);
- static void SetCurrentInterpreter(PythonInterpreter *interpreter);
-
- static PyObject *MarshalToPython(const Value& value);
- static Value MarshalFromPython(PyObject *value);
-
- String ExceptionInfoToString(PyObject *type, PyObject *exc, PyObject *tb) const;
-
-private:
- bool m_Initialized;
- PyThreadState *m_MainThreadState;
- PyObject *m_NativeModule;
- PyObject *m_TracebackModule;
- static PythonInterpreter *m_CurrentInterpreter;
-
- void RegisterNativeFunction(const String& name);
- void UnregisterNativeFunction(const String& name);
-
- static PyObject *PyCallNativeFunction(PyObject *self, PyObject *args);
- static PyObject *PyRegisterFunction(PyObject *self, PyObject *args);
-
- static PyMethodDef m_NativeMethodDef[];
-
- void InitializeOnce(void);
-};
-
-}
-
-#endif /* PYTHONLANGUAGE_H */