summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--CMakeLists.txt24
-rw-r--r--config.h.in1
-rw-r--r--degesch.c98
3 files changed, 116 insertions, 7 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt
index aa0d3e0..64bb667 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -38,6 +38,20 @@ list (APPEND project_libraries ${libssl_LIBRARIES})
include_directories (${libssl_INCLUDE_DIRS})
link_directories (${libssl_LIBRARY_DIRS})
+# FIXME: other Lua versions may be acceptable, don't know yet
+pkg_search_module (lua lua5.3 lua-5.3 lua>=5.3)
+option (WITH_LUA "Enable experimental support for Lua plugins" ${lua_FOUND})
+
+if (WITH_LUA)
+ if (NOT lua_FOUND)
+ message (FATAL_ERROR "Lua library not found")
+ endif (NOT lua_FOUND)
+
+ list (APPEND project_libraries ${lua_LIBRARIES})
+ include_directories (${lua_INCLUDE_DIRS})
+ link_directories (${lua_LIBRARY_DIRS})
+endif (WITH_LUA)
+
# -lpthread is only there for debugging (gdb & errno)
# -lrt is only for glibc < 2.17
# -liconv may or may not be a part of libc
@@ -75,13 +89,9 @@ elseif (WANT_LIBEDIT)
endif ((WANT_READLINE AND WANT_LIBEDIT) OR (NOT WANT_READLINE AND NOT WANT_LIBEDIT))
# Generate a configuration file
-if (WANT_READLINE)
- set (HAVE_READLINE 1)
-endif (WANT_READLINE)
-
-if (WANT_LIBEDIT)
- set (HAVE_EDITLINE 1)
-endif (WANT_LIBEDIT)
+set (HAVE_READLINE "${WANT_READLINE}")
+set (HAVE_EDITLINE "${WANT_LIBEDIT}")
+set (HAVE_LUA "${WITH_LUA}")
include (GNUInstallDirs)
set (plugin_dir ${CMAKE_INSTALL_LIBDIR}/${PROJECT_NAME})
diff --git a/config.h.in b/config.h.in
index 63eca68..833f874 100644
--- a/config.h.in
+++ b/config.h.in
@@ -6,5 +6,6 @@
#cmakedefine HAVE_READLINE
#cmakedefine HAVE_EDITLINE
+#cmakedefine HAVE_LUA
#endif // ! CONFIG_H
diff --git a/degesch.c b/degesch.c
index 1a2ae20..ac54ded 100644
--- a/degesch.c
+++ b/degesch.c
@@ -79,6 +79,12 @@ enum
#include <histedit.h>
#endif // HAVE_EDITLINE
+#ifdef HAVE_LUA
+#include <lua.h>
+#include <lualib.h>
+#include <lauxlib.h>
+#endif // HAVE_LUA
+
/// Some arbitrary limit for the history file
#define HISTORY_LIMIT 10000
@@ -7129,6 +7135,95 @@ server_rename (struct app_context *ctx, struct server *s, const char *new_name)
}
}
+// --- Lua ---------------------------------------------------------------------
+
+#ifdef HAVE_LUA
+
+struct lua_plugin
+{
+ struct plugin super; ///< The structure we're deriving
+ struct app_context *ctx; ///< Application context
+ lua_State *L; ///< Lua state
+};
+
+static void
+lua_plugin_free (struct plugin *self_)
+{
+ struct lua_plugin *self = (struct lua_plugin *) self_;
+ lua_close (self->L);
+}
+
+struct plugin_vtable lua_plugin_vtable =
+{
+ .free = lua_plugin_free,
+};
+
+// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+
+static void *
+lua_plugin_alloc (void *ud, void *ptr, size_t o_size, size_t n_size)
+{
+ (void) ud;
+ (void) o_size;
+
+ if (n_size)
+ return realloc (ptr, n_size);
+
+ free (ptr);
+ return NULL;
+}
+
+static int
+lua_plugin_panic (lua_State *L)
+{
+ // XXX: we might be able to do something better
+ print_fatal ("Lua panicked: %s", lua_tostring (L, -1));
+ lua_close (L);
+ exit (EXIT_FAILURE);
+ return 0;
+}
+
+static luaL_Reg lua_plugin_library[] =
+{
+ { NULL, NULL },
+};
+
+static struct plugin *
+lua_plugin_load (struct app_context *ctx, const char *filename,
+ struct error **e)
+{
+ lua_State *L = lua_newstate (lua_plugin_alloc, NULL);
+ if (!L)
+ {
+ error_set (e, "Lua initialization failed");
+ return NULL;
+ }
+
+ lua_atpanic (L, lua_plugin_panic);
+ luaL_openlibs (L);
+
+ luaL_newlib (L, lua_plugin_library);
+ lua_setglobal (L, PROGRAM_NAME);
+
+ int ret;
+ if ((ret = luaL_loadfile (L, filename))
+ || (ret = lua_pcall (L, 0, 0, 0)))
+ {
+ error_set (e, "%s: %s", "Lua", lua_tostring (L, -1));
+ lua_close (L);
+ return NULL;
+ }
+
+ struct lua_plugin *plugin = xcalloc (1, sizeof *plugin);
+ plugin->super.name = NULL;
+ plugin->super.vtable = &lua_plugin_vtable;
+ plugin->ctx = ctx;
+ plugin->L = L;
+ return &plugin->super;
+}
+
+#endif // HAVE_LUA
+
// --- Plugins -----------------------------------------------------------------
typedef struct plugin *(*plugin_load_fn)
@@ -7138,6 +7233,9 @@ typedef struct plugin *(*plugin_load_fn)
// however this possibility is just a byproduct of abstraction
static plugin_load_fn g_plugin_loaders[] =
{
+#ifdef HAVE_LUA
+ lua_plugin_load,
+#endif // HAVE_LUA
};
static struct plugin *