aboutsummaryrefslogtreecommitdiffstats
path: root/src/lua
diff options
context:
space:
mode:
Diffstat (limited to 'src/lua')
-rw-r--r--src/lua/.gitignore2
-rw-r--r--src/lua/Makefile63
-rw-r--r--src/lua/lua-client.c81
-rw-r--r--src/lua/pingu.lua49
4 files changed, 195 insertions, 0 deletions
diff --git a/src/lua/.gitignore b/src/lua/.gitignore
new file mode 100644
index 0000000..5a99f6b
--- /dev/null
+++ b/src/lua/.gitignore
@@ -0,0 +1,2 @@
+client.so
+*.o
diff --git a/src/lua/Makefile b/src/lua/Makefile
new file mode 100644
index 0000000..aab3799
--- /dev/null
+++ b/src/lua/Makefile
@@ -0,0 +1,63 @@
+
+-include ../../config.mk
+
+TARGETS = client.so
+
+prefix ?= /usr/local
+exec_prefix ?= $(prefix)
+localstatedir ?= $(prefix)/var
+libdir ?= $(exec_prefix)/lib
+datarootdir ?= $(prefix)/share
+
+rundir ?= $(localstatedir)/run
+pingustatedir = $(rundir)/pingu
+
+DESTDIR ?=
+
+INSTALL = install
+INSTALLDIR = $(INSTALL) -d
+PKG_CONFIG ?= pkg-config
+
+LUA_CFLAGS := $(shell $(PKG_CONFIG) --cflags $(LUAPC))
+LUA_VERSION ?= $(shell $(PKG_CONFIG) --variable V $(LUAPC))
+
+luasharedir := $(datarootdir)/lua/$(LUA_VERSION)
+lualibdir := $(libdir)/lua/$(LUA_VERSION)
+
+SUBDIRS :=
+
+CFLAGS ?= -g
+CFLAGS += -I../../ -I..
+CFLAGS += -DPINGU_VERSION=\"$(PINGU_VERSION)\"
+CFLAGS += -Wall -Wstrict-prototypes -D_GNU_SOURCE -std=gnu99
+CFLAGS += -DDEFAULT_ADM_client=\"$(pingustatedir)/pingu.ctl\"
+
+
+lua-client.o_CFLAGS = $(LUA_CFLAGS)
+client.so_OBJS = \
+ lua-client.o
+
+client.so_LDFLAGS = -shared
+
+ALL_OBJS= $(client.so_OBJS)
+
+all: $(TARGETS)
+
+%.o: %.c
+ $(CC) $(CFLAGS) $($@_CFLAGS) -c $<
+
+$(TARGETS):
+ $(CC) $(LDFLAGS) $($@_LDFLAGS) $($@_OBJS) $($@_LIBS) -o $@
+
+client.so: $(client.so_OBJS)
+
+install: client.so pingu.lua
+ $(INSTALLDIR) $(DESTDIR)$(luasharedir) \
+ $(DESTDIR)$(lualibdir)/pingu
+ $(INSTALL) pingu.lua $(DESTDIR)$(luasharedir)/
+ $(INSTALL) client.so $(DESTDIR)$(lualibdir)/pingu/
+
+clean:
+ rm -f $(TARGETS) $(ALL_OBJS)
+
+.PHONY: clean all install
diff --git a/src/lua/lua-client.c b/src/lua/lua-client.c
new file mode 100644
index 0000000..ad18f30
--- /dev/null
+++ b/src/lua/lua-client.c
@@ -0,0 +1,81 @@
+
+#include <sys/socket.h>
+#include <sys/un.h>
+
+#include <errno.h>
+#include <stdio.h>
+#include <unistd.h>
+
+#include <lua.h>
+#include <lualib.h>
+#include <lauxlib.h>
+
+#include "pingu_adm.h"
+
+#define LIBNAME "pingu.client"
+
+#if LUA_VERSION_NUM < 502
+# define luaL_newlib(L,l) (lua_newtable(L), luaL_register(L,NULL,l))
+#endif
+
+static int pusherror(lua_State *L, const char *info)
+{
+ lua_pushnil(L);
+ if (info == NULL)
+ lua_pushstring(L, strerror(errno));
+ else
+ lua_pushfstring(L, "%s: %s", info, strerror(errno));
+ lua_pushinteger(L, errno);
+ return 3;
+}
+
+static int pushfile(lua_State *L, int fd, const char *mode)
+{
+ FILE **f = (FILE **)lua_newuserdata(L, sizeof(FILE *));
+ *f = NULL;
+ luaL_getmetatable(L, "FILE*");
+ lua_setmetatable(L, -2);
+ *f = fdopen(fd, mode);
+ return (*f != NULL);
+}
+
+static int Padm_open(lua_State *L)
+{
+ const char *socket_path = luaL_optstring(L, 1, DEFAULT_ADM_SOCKET);
+ struct sockaddr_un sun;
+ int fd, ret;
+
+ memset(&sun, 0, sizeof(sun));
+ sun.sun_family = AF_UNIX;
+ strncpy(sun.sun_path, socket_path, sizeof(sun.sun_path));
+
+ fd = socket(AF_UNIX, SOCK_STREAM, 0);
+ if (fd < 0)
+ return pusherror(L, "socket");
+
+ if (connect(fd, (struct sockaddr *) &sun, sizeof(sun)) < 0) {
+ ret = pusherror(L, socket_path);
+ goto close_err;
+ }
+
+ return pushfile(L, fd, "r+");
+
+close_err:
+ close(fd);
+ return ret;
+}
+
+static const luaL_Reg reg_pingu_methods[] = {
+ {"open", Padm_open},
+ {NULL, NULL},
+};
+
+
+LUALIB_API int luaopen_pingu_client(lua_State *L)
+{
+ luaL_newlib(L, reg_pingu_methods);
+ lua_pushliteral(L, "version");
+ lua_pushliteral(L, PINGU_VERSION);
+ lua_settable(L, -3);
+ return 1;
+}
diff --git a/src/lua/pingu.lua b/src/lua/pingu.lua
new file mode 100644
index 0000000..c29b276
--- /dev/null
+++ b/src/lua/pingu.lua
@@ -0,0 +1,49 @@
+
+module(..., package.seeall)
+
+
+local function run_command(self, cmd)
+ self.handle:write(cmd.."\n")
+ self.handle:flush()
+
+ local t = {}
+ local line = self.handle:read("*line")
+ while line ~= "" do
+ local key, value = string.match(line, "^(.*): (.*)$")
+ t[key] = value
+ line = self.handle:read("*line")
+ end
+ return t
+end
+
+local function host_status(self)
+ return self:run_command("host-status")
+end
+
+local function gateway_status(self)
+ return self:run_command("gateway-status")
+end
+
+local function close(self)
+ return self.handle:close()
+end
+
+function connect(socket_path)
+ local socket = require("pingu.client")
+ local fh, err
+ if socket ~= nil then
+ fh, err = socket.open(socket_path)
+ end
+ if fh == nil then
+ return fh, err
+ end
+ return {
+ ["handle"] = fh,
+ ["run_command"] = run_command,
+ ["host_status"] = host_status,
+ ["gateway_status"] = gateway_status,
+ ["close"] = close
+ }
+end
+
+