]> granicus.if.org Git - icinga2/commitdiff
Implemented the 'Script' type.
authorGunnar Beutner <gunnar.beutner@netways.de>
Thu, 14 Feb 2013 13:58:26 +0000 (14:58 +0100)
committerGunnar Beutner <gunnar.beutner@netways.de>
Thu, 14 Feb 2013 13:58:26 +0000 (14:58 +0100)
24 files changed:
configure.ac
icinga-app/Makefile.am
lib/Makefile.am
lib/base/Makefile.am
lib/base/dynamicobject.cpp
lib/base/dynamicobject.h
lib/base/dynamictype.cpp
lib/base/script.cpp
lib/base/script.h
lib/base/scriptinterpreter.cpp
lib/base/scriptinterpreter.h
lib/base/scriptlanguage.cpp
lib/base/scriptlanguage.h
lib/config/Makefile.am
lib/icinga/Makefile.am
lib/python/Makefile.am [new file with mode: 0644]
lib/python/i2-python.cpp [new file with mode: 0644]
lib/python/i2-python.h [new file with mode: 0644]
lib/python/pythoninterpreter.cpp [new file with mode: 0644]
lib/python/pythoninterpreter.h [new file with mode: 0644]
lib/python/pythonlanguage.cpp [new file with mode: 0644]
lib/python/pythonlanguage.h [new file with mode: 0644]
lib/remoting/Makefile.am
m4/ax_python_embed.m4 [new file with mode: 0644]

index fc0fe88ef7e169c133a79ecdfbb000f2df2ddc82..f1bc33f51055ad5a51bcbc8a7ecbba94d7884be2 100644 (file)
@@ -78,6 +78,12 @@ if test "$ax_cv___attribute__" = "yes"; then
        CXXFLAGS="$CXXFLAGS -fvisibility=hidden"
 fi
 
+AX_PYTHON_DEFAULT
+AX_PYTHON_ENABLE
+AX_PYTHON_VERSION_ENSURE([2.5])
+AX_PYTHON_CSPEC
+AX_PYTHON_LSPEC
+
 AC_MSG_CHECKING(whether to enable debugging)
 AC_ARG_ENABLE(debug, [  --enable-debug=[no/yes]   turn on debugging (default=no)],, enable_debug=no)
 if test "x$enable_debug" = "xyes"; then
@@ -121,6 +127,7 @@ lib/Makefile
 lib/base/Makefile
 lib/config/Makefile
 lib/icinga/Makefile
+lib/python/Makefile
 lib/remoting/Makefile
 test/Makefile
 third-party/Makefile
index 4e6baccc76643aa43bfb8465ce431c7072f499cb..25a87a6d7a2b10accc8b1bcbe906bfde487cdabb 100644 (file)
@@ -28,8 +28,8 @@ icinga2_LDADD = \
        $(BOOST_PROGRAM_OPTIONS_LIB) \
        ${top_builddir}/lib/base/libbase.la \
        ${top_builddir}/lib/config/libconfig.la \
-       ${top_builddir}/lib/remoting/libremoting.la \
        -dlopen ${top_builddir}/lib/icinga/libicinga.la \
+       -dlopen ${top_builddir}/lib/python/libpython.la \
        -dlopen ${top_builddir}/components/checker/checker.la \
        -dlopen ${top_builddir}/components/replication/replication.la \
        -dlopen ${top_builddir}/components/compat/compat.la \
index 3e680a2eb34e9a40fe0f19c4e475a7baebc88146..442f2058ab63aee1ed6df86228fb37a496d41e57 100644 (file)
@@ -5,4 +5,5 @@ SUBDIRS = \
        base \
        config \
        remoting \
-       icinga
+       icinga \
+       python
index ac4d619ff7d2ca27b467b98db86cd133c95ae368..1f105e1a8567a71b60571c4d1a453cbfae5071aa 100644 (file)
@@ -26,6 +26,7 @@ libbase_la_SOURCES =  \
        exception.h \
        fifo.cpp \
        fifo.h \
+       i2-base.cpp \
        i2-base.h \
        logger.cpp \
        logger.h \
index b3ad74084591fad595737dbdc65a084fbe438135..10ae87196554f540775607f8c9562abfa68ada6c 100644 (file)
@@ -481,6 +481,9 @@ void DynamicObject::FlushTx(void)
        BeginTx();
 }
 
+void DynamicObject::OnInitCompleted(void)
+{ }
+
 void DynamicObject::OnAttributeChanged(const String&, const Value&)
 { }
 
index 7260efa6a9039435f298957e1956ec59d1b49a15..8e02d075da4df3197eafa47442eb9ce52b203545 100644 (file)
@@ -132,6 +132,7 @@ public:
        static void FlushTx(void);
 
 protected:
+       virtual void OnInitCompleted(void);
        virtual void OnAttributeChanged(const String& name, const Value& oldValue);
 
 private:
@@ -148,6 +149,8 @@ private:
        /* This has to be a set of raw pointers because the DynamicObject
         * constructor has to be able to insert objects into this list. */
        static set<DynamicObject *> m_ModifiedObjects;
+
+       friend class DynamicType; /* for OnInitCompleted. */
 };
 
 }
index 05efe7b5a6bdd0a389701329322909e27eb9cb24..75ec7fae619c1b1d8815abb4a4ba3f233b49ece4 100644 (file)
@@ -93,6 +93,9 @@ DynamicObject::Ptr DynamicType::CreateObject(const Dictionary::Ptr& serializedUp
        /* apply the object's non-config attributes */
        obj->ApplyUpdate(serializedUpdate, Attribute_All & ~Attribute_Config);
 
+       /* notify the object that it's been fully initialized */
+       obj->OnInitCompleted();
+
        return obj;
 }
 
index 23418af47bddb34b8773659d3bb89c56e613a3e5..0bcc5ca77380f50c63f74b60e7883d2652a1b067 100644 (file)
@@ -32,6 +32,11 @@ Script::Script(const Dictionary::Ptr& properties)
        : DynamicObject(properties)
 { }
 
+void Script::OnInitCompleted(void)
+{
+       SpawnInterpreter();
+}
+
 String Script::GetLanguage(void) const
 {
        return Get("language");
@@ -44,17 +49,14 @@ String Script::GetCode(void) const
 
 void Script::OnAttributeUpdate(const String& name, const Value& oldValue)
 {
-       if (name == "code")
-               Reload();
+       if (name == "language" || name == "code")
+               SpawnInterpreter();
 }
 
-void Script::Reload(void)
+void Script::SpawnInterpreter(void)
 {
-       if (!m_Interpreter) {
-               ScriptLanguage::Ptr language = ScriptLanguage::GetByName(GetLanguage());
+       Logger::Write(LogInformation, "base", "Reloading script '" + GetName() + "'");
 
-               m_Interpreter = language->CreateInterpreter(GetSelf());
-       } else {
-               m_Interpreter->Reload();
-       }
+       ScriptLanguage::Ptr language = ScriptLanguage::GetByName(GetLanguage());
+       m_Interpreter = language->CreateInterpreter(GetSelf());
 }
index 47c3002460f620525eab162e897f918c717dba83..daaf288e1059fe336bf219d2be3a63d1b5f36e7a 100644 (file)
@@ -42,12 +42,13 @@ public:
        String GetCode(void) const;
 
 protected:
+       virtual void OnInitCompleted(void);
        virtual void OnAttributeUpdate(const String& name, const Value& oldValue);
 
 private:
        shared_ptr<ScriptInterpreter> m_Interpreter;
 
-       void Reload(void);
+       void SpawnInterpreter(void);
 };
 
 }
index 0d2b24b66624a5dac6c6a380e173dcb3894824b0..787ce6883455fe8af1a40ae0354d7a6fbae89107 100644 (file)
 using namespace icinga;
 
 ScriptInterpreter::ScriptInterpreter(const Script::Ptr& script)
-       : m_Thread(&ScriptInterpreter::ThreadWorkerProc, this, script)
+       : m_Thread(&ScriptInterpreter::ThreadWorkerProc, this)
 {
        m_Thread.detach();
 }
 
-void ScriptInterpreter::ThreadWorkerProc(const Script::Ptr& script)
+void ScriptInterpreter::ThreadWorkerProc(void)
 {
        ScriptCall call;
 
@@ -55,3 +55,7 @@ bool ScriptInterpreter::WaitForCall(ScriptCall *call)
        return true;
 }
 
+void ScriptInterpreter::RegisterMethod(const String& name)
+{
+       // TODO: implement
+}
index 629e990754d9940dafbdb1e71c1d4e281668e688..1a6dc10ec870e3f9743209d025867cc48bd9c828 100644 (file)
@@ -41,8 +41,6 @@ public:
        typedef shared_ptr<ScriptInterpreter> Ptr;
        typedef weak_ptr<ScriptInterpreter> WeakPtr;
 
-       virtual void Reload(void) = 0;
-
        void EnqueueCall(const ScriptCall& call);
 
 protected:
@@ -52,6 +50,8 @@ protected:
 
        bool WaitForCall(ScriptCall *call);
 
+       void RegisterMethod(const String& name);
+
 private:
        boost::mutex m_Mutex;
        deque<ScriptCall> m_Calls;
@@ -59,7 +59,7 @@ private:
 
        boost::thread m_Thread;
 
-       void ThreadWorkerProc(const Script::Ptr& script);
+       void ThreadWorkerProc(void);
 };
 
 }
index eac9078e4614dae48e4232a48585ebf64eb8124a..9c131807b8d0361bee49c288c63df99aafa5ba03 100644 (file)
@@ -21,6 +21,9 @@
 
 using namespace icinga;
 
+ScriptLanguage::ScriptLanguage(void)
+{ }
+
 void ScriptLanguage::Register(const String& name, const ScriptLanguage::Ptr& language)
 {
        GetLanguages()[name] = language;
index 7972a0b098ecdc65eb051852cf888b2ad2e4a740..da6e30e535f76a99b1859ce521c4328eee3d4ffd 100644 (file)
@@ -47,6 +47,24 @@ private:
        static 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, boost::make_shared<klass>())
+
 }
 
 #endif /* SCRIPTLANGUAGE_H */
index 8737d31bd036ff63d8b6ec02cfb731384b11669b..18ad41c77c0a66656aeb9df352110936747b0c10 100644 (file)
@@ -15,6 +15,7 @@ libconfig_la_SOURCES = \
        configcompilercontext.h \
        config_lexer.ll \
        config_parser.yy \
+       i2-config.cpp \
        i2-config.h \
        configitem.cpp \
        configitem.h \
index 72358dbacd5d1d433c1e68789a832cf0cdbd8290..2dff520ab51b4909c9841628e5dc0c06ba8f9136 100644 (file)
@@ -15,6 +15,7 @@ libicinga_la_SOURCES =  \
        hostgroup.cpp \
        hostgroup.h \
        host.h \
+       i2-icinga.cpp \
        i2-icinga.h \
        icingaapplication.cpp \
        icingaapplication.h \
diff --git a/lib/python/Makefile.am b/lib/python/Makefile.am
new file mode 100644 (file)
index 0000000..d314d69
--- /dev/null
@@ -0,0 +1,35 @@
+## Process this file with automake to produce Makefile.in
+
+if PYTHON_USE
+pkglib_LTLIBRARIES =  \
+       libpython.la
+
+libpython_la_SOURCES =  \
+       i2-python.h \
+       pythoninterpreter.cpp \
+       pythoninterpreter.h \
+       pythonlanguage.cpp \
+       pythonlanguage.h
+
+libpython_la_CPPFLAGS = \
+       -DI2_PYTHON_BUILD \
+       $(BOOST_CPPFLAGS) \
+       @PYTHON_CSPEC@ \
+       -I${top_srcdir}/lib/base \
+       -I${top_srcdir}/lib/config \
+       -I${top_srcdir}/lib/remoting \
+       -I${top_srcdir}
+
+libpython_la_LDFLAGS = \
+       $(BOOST_LDFLAGS) \
+       @PYTHON_LSPEC@
+       -no-undefined \
+       @RELEASE_INFO@ \
+       @VERSION_INFO@
+
+libpython_la_LIBADD = \
+       $(BOOST_THREAD_LIB) \
+       ${top_builddir}/lib/base/libbase.la \
+       ${top_builddir}/lib/config/libconfig.la \
+       ${top_builddir}/lib/remoting/libremoting.la
+endif
diff --git a/lib/python/i2-python.cpp b/lib/python/i2-python.cpp
new file mode 100644 (file)
index 0000000..405d820
--- /dev/null
@@ -0,0 +1,22 @@
+/******************************************************************************
+ * Icinga 2                                                                   *
+ * Copyright (C) 2012 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.             *
+ ******************************************************************************/
+
+/* This file is used by MSVC to generate the pre-compiled hedader. */
+
+#include "i2-python.h"
diff --git a/lib/python/i2-python.h b/lib/python/i2-python.h
new file mode 100644 (file)
index 0000000..8b6a687
--- /dev/null
@@ -0,0 +1,44 @@
+/******************************************************************************
+ * Icinga 2                                                                   *
+ * Copyright (C) 2012 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 I2PYTHON_H
+#define I2PYTHON_H
+
+/**
+ * @defgroup python Icinga python support
+ *
+ * Lets you integrate Python scripts into Icinga.
+ */
+
+#include <Python.h>
+
+#include <i2-base.h>
+#include <i2-config.h>
+#include <i2-remoting.h>
+
+#ifdef I2_PYTHON_BUILD
+#      define I2_PYTHON_API I2_EXPORT
+#else /* I2_PYTHON_BUILD */
+#      define I2_PYTHON_API I2_IMPORT
+#endif /* I2_PYTHON_BUILD */
+
+#include "pythonlanguage.h"
+#include "pythoninterpreter.h"
+
+#endif /* I2PYTHON_H */
diff --git a/lib/python/pythoninterpreter.cpp b/lib/python/pythoninterpreter.cpp
new file mode 100644 (file)
index 0000000..b4f0e3f
--- /dev/null
@@ -0,0 +1,56 @@
+/******************************************************************************
+ * Icinga 2                                                                   *
+ * Copyright (C) 2012 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 "i2-python.h"
+
+using namespace icinga;
+
+PythonInterpreter::PythonInterpreter(const PythonLanguage::Ptr& language, const Script::Ptr& script)
+       : ScriptInterpreter(script), m_Language(language), m_ThreadState(NULL)
+{
+       PyEval_AcquireLock();
+
+       PyInterpreterState *interp = m_Language->GetMainThreadState()->interp;
+       m_ThreadState = PyThreadState_New(interp);
+
+       PyEval_ReleaseLock();
+
+       PyEval_AcquireThread(m_ThreadState);
+       PyRun_SimpleString(script->GetCode().CStr());
+       PyEval_ReleaseThread(m_ThreadState);
+}
+
+PythonInterpreter::~PythonInterpreter(void)
+{
+       PyEval_AcquireLock();
+
+       PyThreadState_Clear(m_ThreadState);
+       PyThreadState_Delete(m_ThreadState);
+
+       PyEval_ReleaseLock();
+}
+
+void PythonInterpreter::ProcessCall(const ScriptCall& call)
+{
+       PyEval_AcquireThread(m_ThreadState);
+       PyRun_SimpleString("import antigravity");
+       PyEval_ReleaseThread(m_ThreadState);
+
+       call.Task->FinishResult(0);
+}
diff --git a/lib/python/pythoninterpreter.h b/lib/python/pythoninterpreter.h
new file mode 100644 (file)
index 0000000..70d19ef
--- /dev/null
@@ -0,0 +1,49 @@
+/******************************************************************************
+ * Icinga 2                                                                   *
+ * Copyright (C) 2012 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
+
+namespace icinga
+{
+
+/**
+ * A Python script interpreter.
+ *
+ * @ingroup base
+ */
+class I2_PYTHON_API PythonInterpreter : public ScriptInterpreter
+{
+public:
+       typedef shared_ptr<PythonInterpreter> Ptr;
+       typedef weak_ptr<PythonInterpreter> WeakPtr;
+
+       PythonInterpreter(const PythonLanguage::Ptr& language, const Script::Ptr& script);
+       ~PythonInterpreter(void);
+
+protected:
+       PythonLanguage::Ptr m_Language;
+       PyThreadState *m_ThreadState;
+
+       virtual void ProcessCall(const ScriptCall& call);
+};
+
+}
+
+#endif /* PYTHONINTERPRETER_H */
diff --git a/lib/python/pythonlanguage.cpp b/lib/python/pythonlanguage.cpp
new file mode 100644 (file)
index 0000000..5226081
--- /dev/null
@@ -0,0 +1,54 @@
+/******************************************************************************
+ * Icinga 2                                                                   *
+ * Copyright (C) 2012 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 "i2-python.h"
+
+using namespace icinga;
+
+REGISTER_SCRIPTLANGUAGE("Python", PythonLanguage);
+
+PythonLanguage::PythonLanguage(void)
+       : ScriptLanguage()
+{
+       Py_Initialize();
+       PyEval_InitThreads();
+
+       //PySys_SetArgv(argc, argv);
+
+       m_MainThreadState = PyThreadState_Get();
+
+       PyThreadState_Swap(NULL);
+
+       PyEval_ReleaseLock();
+}
+
+PythonLanguage::~PythonLanguage(void)
+{
+       Py_Finalize();
+}
+
+ScriptInterpreter::Ptr PythonLanguage::CreateInterpreter(const Script::Ptr& script)
+{
+       return boost::make_shared<PythonInterpreter>(GetSelf(), script);
+}
+
+PyThreadState *PythonLanguage::GetMainThreadState(void) const
+{
+       return m_MainThreadState;
+}
diff --git a/lib/python/pythonlanguage.h b/lib/python/pythonlanguage.h
new file mode 100644 (file)
index 0000000..bf0a519
--- /dev/null
@@ -0,0 +1,49 @@
+/******************************************************************************
+ * Icinga 2                                                                   *
+ * Copyright (C) 2012 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
+
+namespace icinga
+{
+
+/**
+ * The Python scripting language.
+ *
+ * @ingroup base
+ */
+class I2_PYTHON_API PythonLanguage : public ScriptLanguage
+{
+public:
+       typedef shared_ptr<PythonLanguage> Ptr;
+       typedef weak_ptr<PythonLanguage> WeakPtr;
+
+       PythonLanguage(void);
+       ~PythonLanguage(void);
+
+       virtual ScriptInterpreter::Ptr CreateInterpreter(const Script::Ptr& script);
+
+       PyThreadState *GetMainThreadState(void) const;
+private:
+       PyThreadState *m_MainThreadState;
+};
+
+}
+
+#endif /* PYTHONLANGUAGE_H */
index eee7801c7a9495708bc5916921bd37359dfbb4a1..372dcca81541fe0d079bf5b9e0aae3c103c3c146 100644 (file)
@@ -9,6 +9,7 @@ libremoting_la_SOURCES = \
        endpoint.h \
        endpointmanager.cpp \
        endpointmanager.h \
+       i2-remoting.cpp \
        i2-remoting.h \
        jsonrpcconnection.cpp \
        jsonrpcconnection.h \
diff --git a/m4/ax_python_embed.m4 b/m4/ax_python_embed.m4
new file mode 100644 (file)
index 0000000..31f3547
--- /dev/null
@@ -0,0 +1,515 @@
+# ===========================================================================
+#      http://www.gnu.org/software/autoconf-archive/ax_python_embed.html
+# ===========================================================================
+#
+# SYNOPSIS
+#
+#   AX_PYTHON_DEFAULT
+#   AX_PYTHON_ENABLE
+#   AX_PYTHON_WITH
+#   AX_PYTHON_PATH
+#   AX_PYTHON_VERSION_ENSURE( [2.2] )
+#   AX_PYTHON_CSPEC
+#   AX_PYTHON_LSPEC
+#
+# DESCRIPTION
+#
+#   This file provides autoconf support for those applications that want to
+#   embed python. It supports all pythons >= 2.2 which is the first official
+#   release containing distutils. Version 2.2 of python was released
+#   December 21, 2001. Since it actually executes the python, cross platform
+#   configuration will probably not work. Also, most of the platforms
+#   supported are consistent until you look into Mac OS X. The python
+#   included with it is installed as a framework which is a very different
+#   environment to set up the normal tools such as gcc and libtool to deal
+#   with. Therefore, once we establish which python that we are going to
+#   use, we use its distutils to actually compile and link our modules or
+#   applications.
+#
+#   At this time, it does NOT support linking with Python statically. It
+#   does support dynamic linking.
+#
+#   This set of macros help define $PYTHON, $PYTHON_USE, $PYTHON_CSPEC and
+#   $PYTHON_LSPEC. $PYTHON defines the full executable path for the Python
+#   being linked to and is used within these macros to determine if that has
+#   been specified or found. These macros do execute this python version so
+#   it must be present on the system at configure time.
+#
+#   $PYTHON_USE is an automake variable that defines whether Python support
+#   should be included or not in your application. $PYTHON_CSPEC is a
+#   variable that supplies additional CFLAGS for the compilation of the
+#   application/shared library. $PYTHON_LSPEC is a variable that supplies
+#   additional LDFLAGS for linking the application/shared library.
+#
+#   The following is an example of how to set up for python usage within
+#   your application in your configure.in:
+#
+#     AX_PYTHON_DEFAULT( )
+#     AX_PYTHON_ENABLE( )             # Optional
+#     AX_PYTHON_WITH( )               # Optional
+#     AX_PYTHON_PATH( )               # or AX_PYTHON_INSIST( )
+#     # if $PYTHON is not defined, then the following do nothing.
+#     AX_PYTHON_VERSION_ENSURE( [2.2] )
+#     AX_PYTHON_CSPEC
+#     AX_PYTHON_LSPEC
+#
+#   The AX_PYTHON_DEFAULT sets the $PYTHON_USE to false. Thereby, excluding
+#   it if it was optional.
+#
+#   The AX_PYTHON_ENABLE looks for the optional configure parameters of
+#   --enable-python/--disable-python and establishes the $PYTHON and
+#   $PYTHON_USE variables accordingly.
+#
+#   The AX_PYTHON_WITH looks for the optional configure parameters of
+#   --with-python/--without-python and establishes the $PYTHON and
+#   $PYTHON_USE variables accordingly.
+#
+#   The AX_PYTHON_PATH looks for python assuming that none has been
+#   previously found or defined and issues an error if it does not find it.
+#   If it does find it, it establishes the $PYTHON and $PYTHON_USE variables
+#   accordingly. AX_PYTHON_INSIST could be used here instead if you want to
+#   insist that Python support be included using the --enable-python or
+#   --with-python checks previously done.
+#
+#   The AX_PYTHON_VERSION_ENSURE issues an error if the Python previously
+#   found is not of version 2.2 or greater.
+#
+#   Once that these macros have be run, we can use PYTHON_USE within the
+#   makefile.am file to conditionally add the Python support such as:
+#
+#   Makefile.am example showing optional inclusion of directories:
+#
+#    if PYTHON_USE
+#    plugins = plugins
+#    src = src
+#    else
+#    plugins =
+#    src =
+#    endif
+#
+#    SUBDIRS = . $(plugins) $(src)
+#
+#   Makefile.am example showing optional shared library build:
+#
+#    if PYTHON_USE
+#    lib_LTLIBRARIES        = libElemList.la
+#    libElemList_la_SOURCES = libElemList.c
+#    libElemList_la_CFLAGS  = @PYTHON_CSPEC@
+#    libElemList_la_LDFLAGS = @PYTHON_LSPEC@
+#    endif
+#
+#   Makefile.am example showing optional program build:
+#
+#    if PYTHON_USE
+#    bin_PROGRAMS    = runFunc
+#    runFunc_SOURCES = runFunc.c
+#    runFunc_CFLAGS  = @PYTHON_CSPEC@
+#    runFunc_LDFLAGS = @PYTHON_LSPEC@
+#    endif
+#
+#   The above compiles the modules only if PYTHON_USE was specified as true.
+#   Also, the else portion of the if was optional.
+#
+# LICENSE
+#
+#   Copyright (c) 2008 Robert White <kranki@mac.com>
+#   Copyright (c) 2008 Dustin J. Mitchell <dustin@cs.uchicago.edu>
+#
+#   Copying and distribution of this file, with or without modification, are
+#   permitted in any medium without royalty provided the copyright notice
+#   and this notice are preserved. This file is offered as-is, without any
+#   warranty.
+
+#serial 8
+
+# AX_PYTHON_DEFAULT( )
+# -----------------
+# Sets the default to not include Python support.
+
+AC_DEFUN([AX_PYTHON_DEFAULT],
+[
+    ax_python_use=false
+    AM_CONDITIONAL(PYTHON_USE, test x"$ax_python_use" = x"true")
+])
+
+
+
+# AX_PYTHON_ENABLE( [path] )
+# -----------------------------------------------------------------
+# Handles the various --enable-python commands.
+# Input:
+#   $1 is the optional search path for the python executable if needed
+# Ouput:
+#   PYTHON_USE (AM_CONDITIONAL) is true if python executable found
+#   and --enable-python was requested; otherwise false.
+#   $PYTHON contains the full executable path to python if PYTHON_ENABLE_USE
+#   is true.
+#
+# Example:
+#   AX_PYTHON_ENABLE( )
+#   or
+#   AX_PYTHON_ENABLE( "/usr/bin" )
+
+AC_DEFUN([AX_PYTHON_ENABLE],
+[
+    AC_ARG_VAR([PYTHON],[Python Executable Path])
+
+    # unless PYTHON was supplied to us (as a precious variable),
+    # see if --enable-python[=PythonExecutablePath], --enable-python,
+    # --disable-python or --enable-python=no was given.
+    if test -z "$PYTHON"
+    then
+        AC_MSG_CHECKING(for --enable-python)
+        AC_ARG_ENABLE(
+            python,
+            AS_HELP_STRING([--enable-python@<:@=PYTHON@:>@],
+                [absolute path name of Python executable]
+            ),
+            [
+                if test "$enableval" = "yes"
+                then
+                    # "yes" was specified, but we don't have a path
+                    # for the executable.
+                    # So, let's searth the PATH Environment Variable.
+                    AC_MSG_RESULT(yes)
+                    AC_PATH_PROG(
+                        [PYTHON],
+                        python,
+                        [],
+                        $1
+                    )
+                    if test -z "$PYTHON"
+                    then
+                        AC_MSG_ERROR(no path to python found)
+                    fi
+                    ax_python_use=true
+                    AM_CONDITIONAL(PYTHON_USE, test x"$ax_python_use" = x"true")
+                    AX_PYTHON_PREFIX( )
+                elif test "$enableval" = "no"
+                then
+                    AC_MSG_RESULT(no)
+                    ax_python_use=false
+                    AM_CONDITIONAL(PYTHON_USE, test x"$ax_python_use" = x"true")
+                else
+                    # $enableval must be the executable path then.
+                    AC_SUBST([PYTHON], ["${enableval}"])
+                    AC_MSG_RESULT($withval)
+                    ax_python_use=true
+                    AM_CONDITIONAL(PYTHON_USE, test x"$ax_python_use" = x"true")
+                    AX_PYTHON_PREFIX( )
+                fi
+            ],
+            [
+                # --with-python was not specified.
+                AC_MSG_RESULT(no)
+                ax_python_use=false
+                AM_CONDITIONAL(PYTHON_USE, test x"$ax_python_use" = x"true")
+            ]
+        )
+    fi
+
+])
+
+
+
+# AX_PYTHON_CSPEC( )
+# -----------------
+# Set up the c compiler options to compile Python
+# embedded programs/libraries in $PYTHON_CSPEC if
+# $PYTHON has been defined.
+
+AC_DEFUN([AX_PYTHON_CSPEC],
+[
+    AC_ARG_VAR( [PYTHON], [Python Executable Path] )
+    if test -n "$PYTHON"
+    then
+        ax_python_prefix=`${PYTHON} -c "import sys; print sys.prefix"`
+        if test -z "$ax_python_prefix"
+        then
+            AC_MSG_ERROR([Python Prefix is not known])
+        fi
+        ax_python_execprefix=`${PYTHON} -c "import sys; print sys.exec_prefix"`
+        ax_python_version=`$PYTHON -c "import sys; print sys.version[[:3]]"`
+        ax_python_includespec="-I${ax_python_prefix}/include/python${ax_python_version}"
+        if test x"$python_prefix" != x"$python_execprefix"; then
+            ax_python_execspec="-I${ax_python_execprefix}/include/python${ax_python_version}"
+            ax_python_includespec="${ax_python_includespec} $ax_python_execspec"
+        fi
+        ax_python_ccshared=`${PYTHON} -c "import distutils.sysconfig; print distutils.sysconfig.get_config_var('CFLAGSFORSHARED')"`
+        ax_python_cspec="${ax_python_ccshared} ${ax_python_includespec}"
+        AC_SUBST([PYTHON_CSPEC], [${ax_python_cspec}])
+        AC_MSG_NOTICE([PYTHON_CSPEC=${ax_python_cspec}])
+    fi
+])
+
+
+
+# AX_PYTHON_INSIST( )
+# -----------------
+# Look for Python and set the output variable 'PYTHON'
+# to 'python' if found, empty otherwise.
+
+AC_DEFUN([AX_PYTHON_INSIST],
+[
+    AC_ARG_VAR( [PYTHON], [Python Executable Path] )
+    if test -z "$PYTHON"
+    then
+        AC_MSG_ERROR([Python Executable not found])
+    fi
+])
+
+
+
+# AX_PYTHON_LSPEC( )
+# -----------------
+# Set up the linker options to link Python embedded
+# programs/libraries in $PYTHON_LSPEC if $PYTHON
+# has been defined.
+
+AC_DEFUN([AX_PYTHON_LSPEC],
+[
+    AC_ARG_VAR( [PYTHON], [Python Executable Path] )
+    if test -n "$PYTHON"
+    then
+        AX_PYTHON_RUN([
+import sys
+import distutils.sysconfig
+strUseFrameWork = "--enable-framework"
+dictConfig = distutils.sysconfig.get_config_vars( )
+strConfigArgs = dictConfig.get("CONFIG_ARGS")
+strLinkSpec =  dictConfig.get('LDFLAGS')
+if -1 ==  strConfigArgs.find(strUseFrameWork):
+    strLibPL = dictConfig.get("LIBPL")
+    if strLibPL and (strLibPL != ""):
+        strLinkSpec += " -L%s" % (strLibPL)
+    strSys = dictConfig.get("SYSLIBS")
+    if strSys and (strSys != ""):
+        strLinkSpec += " %s" % (strSys)
+    strSHL = dictConfig.get("SHLIBS")
+    if strSHL and (strSHL != ""):
+        strLinkSpec += " %s" % (strSHL)
+    # Construct the Python Library Name.
+    strTmplte = " -lpython%d.%d"
+    if (sys.platform == "win32") or (sys.platform == "os2emx"):
+        strTmplte = " -lpython%d%d"
+    strWrk = strTmplte % ( (sys.hexversion >> 24),
+                            ((sys.hexversion >> 16) & 0xff))
+    strLinkSpec += strWrk
+else:
+    # This is not ideal since it changes the search path
+    # for Frameworks which could have side-effects on
+    # other included Frameworks.  However, it is necessary
+    # where someone has installed more than one frameworked
+    # Python.  Frameworks are really only used in MacOSX.
+    strLibFW = dictConfig.get("PYTHONFRAMEWORKPREFIX")
+    if strLibFW and (strLibFW != ""):
+        strLinkSpec += " -F%s" % (strLibFW)
+strLinkSpec += " %s" % (dictConfig.get('LINKFORSHARED'))
+print strLinkSpec
+        ])
+        AC_SUBST([PYTHON_LSPEC], [${ax_python_output}])
+        AC_MSG_NOTICE([PYTHON_LSPEC=${ax_python_output}])
+    fi
+])
+
+
+
+# AX_PYTHON_PATH( )
+# -----------------
+# Look for Python and set the output variable 'PYTHON'
+# to 'python' if found, empty otherwise.
+
+AC_DEFUN([AX_PYTHON_PATH],
+[
+    AC_ARG_VAR( [PYTHON], [Python Executable Path] )
+    AC_PATH_PROG( PYTHON, python, [], $1 )
+    if test -z "$PYTHON"
+    then
+        AC_MSG_ERROR([Python Executable not found])
+    else
+        ax_python_use=true
+    fi
+    AM_CONDITIONAL(PYTHON_USE, test "$ax_python_use" = "true")
+])
+
+
+
+# AX_PYTHON_PREFIX( )
+# -------------------
+# Use the values of $prefix and $exec_prefix for the corresponding
+# values of PYTHON_PREFIX and PYTHON_EXEC_PREFIX.
+
+AC_DEFUN([AX_PYTHON_PREFIX],
+[
+    if test -z "$PYTHON"
+    then
+        AC_MSG_ERROR([Python Executable Path is not known])
+    fi
+    ax_python_prefix=`${PYTHON} -c "import sys; print sys.prefix"`
+    ax_python_execprefix=`${PYTHON} -c "import sys; print sys.exec_prefix"`
+    AC_SUBST([PYTHON_PREFIX], ["${ax_python_prefix}"])
+    AC_SUBST([PYTHON_EXECPREFIX], ["${ax_python_execprefix}"])
+])
+
+
+
+# AX_PYTHON_RUN( PYTHON_PROGRAM )
+# -----------------
+# Run a Python Test Program saving its output
+# in ax_python_output and its condition code
+# in ax_python_cc.
+
+AC_DEFUN([AX_PYTHON_RUN],
+[
+    AC_ARG_VAR( [PYTHON], [Python Executable Path] )
+    if test -z "$PYTHON"
+    then
+        AC_MSG_ERROR([Python Executable not found])
+    else
+        cat >conftest.py <<_ACEOF
+$1
+_ACEOF
+        ax_python_output=`$PYTHON conftest.py`
+        ax_python_cc=$?
+        rm conftest.py
+        if test -f "conftest.pyc"
+        then
+            rm conftest.pyc
+        fi
+    fi
+])
+
+
+
+# AX_PYTHON_VERSION_CHECK( VERSION, [ACTION-IF-TRUE], [ACTION-IF-FALSE] )
+# -----------------------------------------------------------------------------
+# Run ACTION-IF-TRUE if the Python interpreter has version >= VERSION.
+# Run ACTION-IF-FALSE otherwise.
+# This test uses sys.hexversion instead of the string equivalant (first
+# word of sys.version), in order to cope with versions such as 2.2c1.
+# hexversion has been introduced in Python 1.5.2; it's probably not
+# worth to support older versions (1.5.1 was released on October 31, 1998).
+
+AC_DEFUN([AX_PYTHON_VERSION_CHECK],
+ [
+    AC_ARG_VAR( [PYTHON], [Python Executable Path] )
+    if test -n "$PYTHON"
+    then
+        AC_MSG_CHECKING([whether $PYTHON version >= $1])
+        AX_PYTHON_RUN([
+import sys, string
+# split strings by '.' and convert to numeric.  Append some zeros
+# because we need at least 4 digits for the hex conversion.
+minver = map(int, string.split('$1', '.')) + [[0, 0, 0]]
+minverhex = 0
+for i in xrange(0, 4): minverhex = (minverhex << 8) + minver[[i]]
+if sys.hexversion >= minverhex:
+    sys.exit( 0 )
+else:
+    sys.exit( 1 )
+        ])
+        if test $ax_python_cc -eq 0
+        then
+            $2
+        m4_ifvaln(
+            [$3],
+            [else $3]
+        )
+        fi
+    fi
+])
+
+
+
+# AX_PYTHON_VERSION_ENSURE( VERSION )
+# -----------------
+# Insure that the Python Interpreter Version
+# is greater than or equal to the VERSION
+# parameter.
+
+AC_DEFUN([AX_PYTHON_VERSION_ENSURE],
+[
+    AX_PYTHON_VERSION_CHECK(
+        [$1],
+        [AC_MSG_RESULT(yes)],
+        [AC_MSG_ERROR(too old)]
+    )
+])
+
+
+
+# AX_PYTHON_WITH( [path] )
+# -----------------------------------------------------------------
+# Handles the various --with-python commands.
+# Input:
+#   $1 is the optional search path for the python executable if needed
+# Ouput:
+#   PYTHON_USE (AM_CONDITIONAL) is true if python executable found
+#   and --with-python was requested; otherwise false.
+#   $PYTHON contains the full executable path to python if PYTHON_USE
+#   is true.
+#
+# Example:
+#   AX_PYTHON_WITH( )
+#   or
+#   AX_PYTHON_WITH("/usr/bin")
+
+AC_DEFUN([AX_PYTHON_WITH],
+[
+    AC_ARG_VAR([PYTHON],[Python Executable Path])
+
+    # unless PYTHON was supplied to us (as a precious variable),
+    # see if --with-python[=PythonExecutablePath], --with-python,
+    # --without-python or --with-python=no was given.
+    if test -z "$PYTHON"
+    then
+        AC_MSG_CHECKING(for --with-python)
+        AC_ARG_WITH(
+            python,
+            AS_HELP_STRING([--with-python@<:@=PYTHON@:>@],
+                [absolute path name of Python executable]
+            ),
+            [
+                if test "$withval" = "yes"
+                then
+                    # "yes" was specified, but we don't have a path
+                    # for the executable.
+                    # So, let's searth the PATH Environment Variable.
+                    AC_MSG_RESULT(yes)
+                    AC_PATH_PROG(
+                        [PYTHON],
+                        python,
+                        [],
+                        $1
+                    )
+                    if test -z "$PYTHON"
+                    then
+                        AC_MSG_ERROR(no path to python found)
+                    fi
+                    ax_python_use=true
+                    AM_CONDITIONAL(PYTHON_USE, test x"$ax_python_use" = x"true")
+                    AX_PYTHON_PREFIX( )
+                elif test "$withval" = "no"
+                then
+                    AC_MSG_RESULT(no)
+                    ax_python_use=false
+                    AM_CONDITIONAL(PYTHON_USE, test x"$ax_python_use" = x"true")
+                else
+                    # $withval must be the executable path then.
+                    AC_SUBST([PYTHON], ["${withval}"])
+                    AC_MSG_RESULT($withval)
+                    ax_python_use=true
+                    AM_CONDITIONAL(PYTHON_USE, test x"$ax_python_use" = x"true")
+                    AX_PYTHON_PREFIX( )
+                fi
+            ],
+            [
+                # --with-python was not specified.
+                AC_MSG_RESULT(no)
+                ax_python_use=false
+                AM_CONDITIONAL(PYTHON_USE, test x"$ax_python_use" = x"true")
+            ]
+        )
+    fi
+
+])