summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristian Pointner <equinox@helsinki.at>2010-01-11 20:37:13 (GMT)
committerChristian Pointner <equinox@helsinki.at>2010-01-11 20:37:13 (GMT)
commitd035636d833c393f86eb4eacb5c5934c94eb1a06 (patch)
tree3b4c7e7933878d0a0f47e11bbd2edf075801969c
parent16797549c7788b05583f241e5c788a666debf6d0 (diff)
added luaclient
-rw-r--r--Makefile19
-rwxr-xr-xconfigure80
-rw-r--r--l_log.c120
-rw-r--r--l_log.h40
-rw-r--r--l_sig_handler.c99
-rw-r--r--l_sig_handler.h40
-rw-r--r--luaclient.c256
-rw-r--r--mode-leds.lua47
-rw-r--r--options.c78
-rw-r--r--options.h10
10 files changed, 786 insertions, 3 deletions
diff --git a/Makefile b/Makefile
index 8a44ebc..0ba2cdb 100644
--- a/Makefile
+++ b/Makefile
@@ -27,6 +27,7 @@ EXE_SWITCHCTL := switchctl
EXE_SERIALCLIENT := serialclient
EXE_STDIOCLIENT := stdioclient
EXE_HEARTBEATCLIENT := heartbeatclient
+EXE_LUACLIENT := luaclient
COMMONOBJ := log.o \
sig_handler.o \
@@ -48,12 +49,17 @@ STDIOCLIENTOBJ := opt-stdioclient.o \
HEARTBEATCLIENTOBJ := opt-heartbeatclient.o \
heartbeatclient.o
+LUACLIENTOBJ := opt-luaclient.o \
+ l_log.o \
+ l_sig_handler.o \
+ luaclient.o
-SRC := $(COMMONOBJ:%.o=%.c) $(SWITCHCTLOBJ:%.o=%.c) $(SERIALCLIENTOBJ:%.o=%.c) $(STDIOCLIENTOBJ:%.o=%.c) $(HEARTBEATCLIENTOBJ:%.o=%.c) options.c
+
+SRC := $(COMMONOBJ:%.o=%.c) $(SWITCHCTLOBJ:%.o=%.c) $(SERIALCLIENTOBJ:%.o=%.c) $(STDIOCLIENTOBJ:%.o=%.c) $(HEARTBEATCLIENTOBJ:%.o=%.c) $(LUACLIENTOBJ:%.o=%.c) options.c
.PHONY: clean distclean
-all: $(EXE_SWITCHCTL) $(EXE_SERIALCLIENT) $(EXE_STDIOCLIENT) $(EXE_HEARTBEATCLIENT)
+all: $(EXE_SWITCHCTL) $(EXE_SERIALCLIENT) $(EXE_STDIOCLIENT) $(EXE_HEARTBEATCLIENT) $(EXE_LUACLIENT)
%.d: %.c
@set -e; rm -f $@; \
@@ -77,6 +83,9 @@ $(EXE_STDIOCLIENT): $(COMMONOBJ) $(STDIOCLIENTOBJ)
$(EXE_HEARTBEATCLIENT): $(COMMONOBJ) $(HEARTBEATCLIENTOBJ)
$(CC) $(COMMONOBJ) $(HEARTBEATCLIENTOBJ) -o $@ $(LDFLAGS)
+$(EXE_LUACLIENT): $(COMMONOBJ) $(LUACLIENTOBJ)
+ $(CC) $(COMMONOBJ) $(LUACLIENTOBJ) -o $@ $(LDFLAGS) $(LUA_LDFLAGS)
+
opt-switchctl.o: options.c
$(CC) $(CFLAGS) -DOPT_SWITCHCTL -o $@ -c $<
@@ -89,6 +98,9 @@ opt-stdioclient.o: options.c
opt-heartbeatclient.o: options.c
$(CC) $(CFLAGS) -DOPT_HEARTBEATCLIENT -o $@ -c $<
+opt-luaclient.o: options.c
+ $(CC) $(CFLAGS) -DOPT_LUACLIENT -o $@ -c $<
+
%.o: %.c
$(CC) $(CFLAGS) -c $<
@@ -105,4 +117,5 @@ clean:
rm -f $(EXE_SWITCHCTL)
rm -f $(EXE_SERIALCLIENT)
rm -f $(EXE_STDIOCLIENT)
- rm -f $(EXE_HEARTBEATCLIENT) \ No newline at end of file
+ rm -f $(EXE_HEARTBEATCLIENT)
+ rm -f $(EXE_LUACLIENT) \ No newline at end of file
diff --git a/configure b/configure
index f4b30be..d39c7f5 100755
--- a/configure
+++ b/configure
@@ -26,9 +26,15 @@ TARGET=`uname -s`
CFLAGS='-g -O2'
LDFLAGS='-g -Wall -O2'
+LUA_LDFLAGS='-lm'
+LUA_DIR=''
+LUA=''
+LUAC=''
+
print_usage() {
echo "configure --help print this"
echo " --target=<TARGET> build target i.e. Linux (default: autodetect)"
+ echo " --with-lua=<DIR> use this lua tree instead of system default"
}
for arg
@@ -37,6 +43,9 @@ do
--target=*)
TARGET=${arg#--target=}
;;
+ --with-lua=*)
+ LUA_DIR=${arg#--with-lua=}
+ ;;
--help)
print_usage
exit 0
@@ -53,6 +62,7 @@ rm -f include.mk
case $TARGET in
Linux)
echo "Linux specific build options"
+ LUA_LDFLAGS=$LUA_LDFLAGS' -ldl'
;;
OpenBSD|FreeBSD|NetBSD)
echo "BSD specific build options"
@@ -65,6 +75,73 @@ case $TARGET in
;;
esac
+test_lua_version()
+{
+ LUA_VERSION=`cat $1 | grep "#define LUA_VERSION[ ]" | cut -f2- | tr -d '"' | sed -e 's/Lua \([0-9][0-9.]*\)/\1/'`
+ LUA_VERSION_NUM=`cat $1 | grep "#define LUA_VERSION_NUM" | awk '{ print $3 }'`
+ LUA_RELEASE=`cat $1 | grep "#define LUA_RELEASE[ ]" | cut -f2-`
+
+ if [ $LUA_VERSION_NUM -ge 501 ]; then
+ return 1;
+ else
+ return 0;
+ fi
+}
+
+if [ -z "$LUA_DIR" ]; then
+ for prefix in /usr /usr/local; do
+ if [ -e $prefix/include/lua.h ]; then
+ test_lua_version $prefix/include/lua.h
+ if [ $? -eq 1 ]; then
+ echo "using Lua $LUA_VERSION ($LUA_RELEASE) found at $prefix/include"
+ CFLAGS="$CFLAGS -I$prefix/include"
+ LUA_LDFLAGS="$LUA_LDFLAGS -L$prefix/lib -llua"
+ LUA=$prefix/lua
+ LUAC=$prefix/luac
+ break
+ fi
+ else
+ for dir in `ls -d $prefix/include/lua* 2> /dev/null`; do
+ if [ -e $dir/lua.h ]; then
+ test_lua_version $dir/lua.h
+ if [ $? -eq 1 ]; then
+ echo "using Lua $LUA_VERSION ($LUA_RELEASE) found at $dir"
+ CFLAGS="$CFLAGS -I$dir"
+ if [ -x "$prefix/bin/lua$LUA_VERSION" ]; then
+ LUA_LDFLAGS="$LUA_LDFLAGS -L$prefix/lib -llua$LUA_VERSION"
+ LUA=$prefix/bin/lua$LUA_VERSION
+ LUAC=$prefix/bin/luac$LUA_VERSION
+ elif [ -x "$prefix/bin/lua-$LUA_VERSION" ]; then
+ LUA_LDFLAGS="$LUA_LDFLAGS -L$prefix/lib -llua-$LUA_VERSION"
+ LUA=$prefix/bin/lua-$LUA_VERSION
+ LUAC=$prefix/bin/luac-$LUA_VERSION
+ else
+ echo "ERROR: found lua.h at $dir/lua.h but no matching lua and luac"
+ return 1
+ fi
+ break
+ fi
+ fi
+ done
+ if [ -n "$LUAC" ]; then
+ break
+ fi
+ fi
+ done
+
+ if [ -z "$LUAC" ]; then
+ echo "ERROR: no suitable lua found .. please install lua 5.1 or higher or use --with-lua"
+ return 1
+ fi
+
+else
+ CFLAGS="$CFLAGS -I$LUA_DIR/include"
+ LUA_LDFLAGS="$LUA_LDFLAGS $LUA_DIR/lib/liblua.a"
+ LUA=$LUA_DIR/bin/lua
+ LUAC=$LUA_DIR/bin/luac
+fi
+
+
cat >> include.mk <<EOF
# this file was created automatically
# do not edit this file directly
@@ -74,6 +151,9 @@ TARGET := $TARGET
CC := gcc
CFLAGS := $CFLAGS
LDFLAGS := $LDFLAGS
+LUA_LDFLAGS := $LUA_LDFLAGS
+LUA := $LUA
+LUAC := $LUAC
EOF
exit 0
diff --git a/l_log.c b/l_log.c
new file mode 100644
index 0000000..528fe95
--- /dev/null
+++ b/l_log.c
@@ -0,0 +1,120 @@
+/*
+ * anylike
+ *
+ * anylike is an IKEv2 Implementation written in Lua and C. It's main
+ * design goal is to provide anytun and uanytun or any other SATP
+ * implementation with a key exchange mechanism but it should also be
+ * possible to use anylike as key exchange daemon for IPSec security
+ * associations. The use of Lua guarantees that anylike is easily
+ * portable to many platforms including very small ones like wireless
+ * routers.
+ *
+ *
+ * Copyright (C) 2009-2010 Markus Grueneis <gimpf@anylike.org>
+ * Christian Pointner <equinox@anylike.org>
+ *
+ * This file is part of anylike.
+ *
+ * anylike 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 3 of the License, or
+ * any later version.
+ *
+ * anylike 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 anylike. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <lua.h>
+#include <lauxlib.h>
+
+#include <stdlib.h>
+
+#include "datatypes.h"
+#include "log.h"
+
+#include "l_log.h"
+
+static int l_log_init(lua_State *L)
+{
+ log_init();
+ return 0;
+}
+
+static int l_log_close(lua_State *L)
+{
+ log_close();
+ return 0;
+}
+
+static int l_log_add_target(lua_State *L)
+{
+ int ret = log_add_target(luaL_checkstring(L,1));
+ if(ret) {
+ lua_pushboolean(L, 0);
+ switch(ret) {
+ case -2: lua_pushstring(L, "memory error at log_add_target"); break;
+ case -3: lua_pushstring(L, "unknown log target"); break;
+ case -4: lua_pushstring(L, "this log target is only allowed once"); break;
+ default: lua_pushstring(L, "syntax error"); break;
+ }
+ return 2;
+ }
+
+ lua_pushboolean(L, 1);
+ return 1;
+}
+
+static int l_log_printf(lua_State *L)
+{
+ int numargs = lua_gettop(L);
+ if(numargs < 2)
+ return luaL_error(L, "log.printf too few arguments");
+
+ if(numargs > 2) {
+ lua_getglobal(L, "string");
+ lua_pushliteral(L, "format");
+ lua_gettable(L, -2);
+ lua_insert(L, 2);
+ lua_remove(L, -1);
+ lua_call(L, numargs - 1, 1);
+ }
+
+ log_prio_t prio = luaL_checkint(L,1);
+ log_printf(prio, "%s", luaL_checkstring(L, 2));
+ return 0;
+}
+
+static const struct luaL_reg log_funcs [] = {
+ { "init", l_log_init },
+ { "close", l_log_close },
+ { "add_target", l_log_add_target },
+ { "printf", l_log_printf },
+ { NULL, NULL }
+};
+
+
+LUALIB_API int luaopen_log(lua_State *L)
+{
+ luaL_register(L, LUA_LOGLIBNAME, log_funcs);
+ lua_pushliteral(L, "ERROR");
+ lua_pushinteger(L, ERROR);
+ lua_settable(L, -3);
+ lua_pushliteral(L, "WARNING");
+ lua_pushinteger(L, WARNING);
+ lua_settable(L, -3);
+ lua_pushliteral(L, "NOTICE");
+ lua_pushinteger(L, NOTICE);
+ lua_settable(L, -3);
+ lua_pushliteral(L, "INFO");
+ lua_pushinteger(L, INFO);
+ lua_settable(L, -3);
+ lua_pushliteral(L, "DEBUG");
+ lua_pushinteger(L, DEBUG);
+ lua_settable(L, -3);
+ return 1;
+}
diff --git a/l_log.h b/l_log.h
new file mode 100644
index 0000000..8750a7a
--- /dev/null
+++ b/l_log.h
@@ -0,0 +1,40 @@
+/*
+ * anylike
+ *
+ * anylike is an IKEv2 Implementation written in Lua and C. It's main
+ * design goal is to provide anytun and uanytun or any other SATP
+ * implementation with a key exchange mechanism but it should also be
+ * possible to use anylike as key exchange daemon for IPSec security
+ * associations. The use of Lua guarantees that anylike is easily
+ * portable to many platforms including very small ones like wireless
+ * routers.
+ *
+ *
+ * Copyright (C) 2009-2010 Markus Grueneis <gimpf@anylike.org>
+ * Christian Pointner <equinox@anylike.org>
+ *
+ * This file is part of anylike.
+ *
+ * anylike 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 3 of the License, or
+ * any later version.
+ *
+ * anylike 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 anylike. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef ANYLIKE_l_log_h_INCLUDED
+#define ANYLIKE_l_log_h_INCLUDED
+
+#include <lua.h>
+
+#define LUA_LOGLIBNAME "log"
+LUALIB_API int luaopen_log(lua_State *L);
+
+#endif
diff --git a/l_sig_handler.c b/l_sig_handler.c
new file mode 100644
index 0000000..0bdcffc
--- /dev/null
+++ b/l_sig_handler.c
@@ -0,0 +1,99 @@
+/*
+ * anylike
+ *
+ * anylike is an IKEv2 Implementation written in Lua and C. It's main
+ * design goal is to provide anytun and uanytun or any other SATP
+ * implementation with a key exchange mechanism but it should also be
+ * possible to use anylike as key exchange daemon for IPSec security
+ * associations. The use of Lua guarantees that anylike is easily
+ * portable to many platforms including very small ones like wireless
+ * routers.
+ *
+ *
+ * Copyright (C) 2009-2010 Markus Grueneis <gimpf@anylike.org>
+ * Christian Pointner <equinox@anylike.org>
+ *
+ * This file is part of anylike.
+ *
+ * anylike 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 3 of the License, or
+ * any later version.
+ *
+ * anylike 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 anylike. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <lua.h>
+#include <lauxlib.h>
+
+#include "sig_handler.h"
+
+#include "l_sig_handler.h"
+
+static int l_signal_getfd(lua_State *L)
+{
+ if(!lua_istable(L, -1))
+ luaL_error(L, "can't retreive signal fd");
+
+ lua_pushliteral(L, "fd");
+ lua_gettable(L, -2);
+ return 1;
+}
+
+static int l_signal_dirty(lua_State *L)
+{
+ lua_pushboolean(L, 0);
+ return 1;
+}
+
+static int l_signal_init(lua_State *L)
+{
+ int sig_fd = signal_init();
+ if(sig_fd < 0)
+ luaL_error(L, "error at signal init");
+
+ lua_newtable(L);
+ lua_pushliteral(L, "fd");
+ lua_pushinteger(L, sig_fd);
+ lua_settable(L, -3);
+ lua_pushliteral(L, "getfd");
+ lua_pushcfunction(L, l_signal_getfd);
+ lua_settable(L, -3);
+ lua_pushliteral(L, "dirty");
+ lua_pushcfunction(L, l_signal_dirty);
+ lua_settable(L, -3);
+ return 1;
+}
+
+static int l_signal_stop(lua_State *L)
+{
+ signal_stop();
+ return 0;
+}
+
+static int l_signal_handle(lua_State *L)
+{
+ int ret = signal_handle();
+ lua_pushinteger(L, ret);
+ return 1;
+}
+
+static const struct luaL_reg signal_funcs [] = {
+ { "init", l_signal_init },
+ { "stop", l_signal_stop },
+ { "handle", l_signal_handle },
+ { NULL, NULL }
+};
+
+
+LUALIB_API int luaopen_signal(lua_State *L)
+{
+ luaL_register(L, LUA_SIGNALLIBNAME, signal_funcs);
+ return 1;
+}
diff --git a/l_sig_handler.h b/l_sig_handler.h
new file mode 100644
index 0000000..06a5f75
--- /dev/null
+++ b/l_sig_handler.h
@@ -0,0 +1,40 @@
+/*
+ * anylike
+ *
+ * anylike is an IKEv2 Implementation written in Lua and C. It's main
+ * design goal is to provide anytun and uanytun or any other SATP
+ * implementation with a key exchange mechanism but it should also be
+ * possible to use anylike as key exchange daemon for IPSec security
+ * associations. The use of Lua guarantees that anylike is easily
+ * portable to many platforms including very small ones like wireless
+ * routers.
+ *
+ *
+ * Copyright (C) 2009-2010 Markus Grueneis <gimpf@anylike.org>
+ * Christian Pointner <equinox@anylike.org>
+ *
+ * This file is part of anylike.
+ *
+ * anylike 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 3 of the License, or
+ * any later version.
+ *
+ * anylike 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 anylike. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef ANYLIKE_l_signal_handler_h_INCLUDED
+#define ANYLIKE_l_signal_handler_h_INCLUDED
+
+#include <lua.h>
+
+#define LUA_SIGNALLIBNAME "signal"
+LUALIB_API int luaopen_signal(lua_State *L);
+
+#endif
diff --git a/luaclient.c b/luaclient.c
new file mode 100644
index 0000000..f77dbe0
--- /dev/null
+++ b/luaclient.c
@@ -0,0 +1,256 @@
+/*
+ * rhctl
+ *
+ * Copyright (C) 2009 Christian Pointner <equinox@spreadspace.org>
+ *
+ * This file is part of rhctl.
+ *
+ * rhctl 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 3 of the License, or
+ * any later version.
+ *
+ * rhctl 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 rhctl. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "datatypes.h"
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <errno.h>
+
+#include <lua.h>
+#include <lualib.h>
+#include <lauxlib.h>
+
+#include "l_log.h"
+#include "l_sig_handler.h"
+
+#include "log.h"
+#include "options.h"
+
+#include "daemon.h"
+#include "utils.h"
+
+int process_cmd(const char* cmd, int fd, cmd_t **cmd_q, client_t* client_lst, options_t* opt)
+{
+ return 0;
+}
+
+#define LUA_MAIN_LOOP_FUNC "main_loop"
+
+static const luaL_Reg anylike_lualibs[] = {
+ {"", luaopen_base},
+ {LUA_LOADLIBNAME, luaopen_package},
+ {LUA_TABLIBNAME, luaopen_table},
+ {LUA_STRLIBNAME, luaopen_string},
+ {LUA_MATHLIBNAME, luaopen_math},
+ {LUA_SIGNALLIBNAME, luaopen_signal},
+ {LUA_LOGLIBNAME, luaopen_log},
+ {NULL, NULL}
+};
+
+int init_main_loop(lua_State *L, const char* filename)
+{
+ const luaL_Reg *lib = anylike_lualibs;
+ for (; lib->func; lib++) {
+ lua_pushcfunction(L, lib->func);
+ lua_pushstring(L, lib->name);
+ lua_call(L, 1, 0);
+ }
+
+ int ret = luaL_loadfile(L, filename);
+ if(ret) {
+ const char* err_str = luaL_checkstring(L, -1);
+ switch(ret) {
+ case LUA_ERRSYNTAX: log_printf(ERROR, "luaL_loadfile(%s) syntax error: %s", filename, err_str); break;
+ case LUA_ERRMEM: log_printf(ERROR, "luaL_loadfile(%s) malloc error: %s", filename, err_str); break;
+ case LUA_ERRFILE: log_printf(ERROR, "luaL_loadfile(%s) file access error: %s", filename, err_str); break;
+ default: log_printf(ERROR, "luaL_loadfile(%s) unknown error: %s", filename, err_str); break;
+ }
+ return -1;
+ }
+
+ ret = lua_pcall(L, 0, 0, 0);
+ if(ret) {
+ const char* err_str = luaL_checkstring(L, -1);
+ switch(ret) {
+ case LUA_ERRRUN: log_printf(ERROR, "lua_pcall() runtime error: %s", err_str); break;
+ case LUA_ERRMEM: log_printf(ERROR, "lua_pcall() malloc error: %s", err_str); break;
+ case LUA_ERRERR: log_printf(ERROR, "lua_pcall() error at error handler function: %s", err_str); break;
+ }
+ return -1;
+ }
+
+ return 0;
+}
+
+int call_main_loop(lua_State* L, int cmd_fd, options_t* opt)
+{
+ lua_getglobal(L, LUA_MAIN_LOOP_FUNC);
+ if(!lua_isfunction(L, -1)) {
+ log_printf(ERROR, "there is no function '%s' inside the load file", LUA_MAIN_LOOP_FUNC);
+ return -1;
+ };
+
+ options_lua_push(opt, L);
+
+ int ret = lua_pcall(L, 1, LUA_MULTRET, 0);
+ if(ret) {
+ const char* err_str = luaL_checkstring(L, -1);
+ switch(ret) {
+ case LUA_ERRRUN: log_printf(ERROR, "lua_pcall(%s) runtime error: %s", LUA_MAIN_LOOP_FUNC, err_str); break;
+ case LUA_ERRMEM: log_printf(ERROR, "lua_pcall(%s) malloc error: %s", LUA_MAIN_LOOP_FUNC, err_str); break;
+ case LUA_ERRERR: log_printf(ERROR, "lua_pcall(%s) error at error handler function: %s", LUA_MAIN_LOOP_FUNC, err_str); break;
+ }
+ return -1;
+ }
+
+ int n = lua_gettop(L);
+ log_printf(DEBUG, "%s returned %d values", LUA_MAIN_LOOP_FUNC, n);
+ int i;
+ for (i = 1; i <= n; i++)
+ log_printf(DEBUG, "return value [%d] = '%s'", i, luaL_checkstring(L, i));
+
+ ret = lua_tointeger(L, 1);
+ return ret;
+}
+
+int main_loop(int cmd_fd, options_t* opt)
+{
+ lua_State *L;
+ L = luaL_newstate();
+ if(!L) {
+ log_printf(ERROR, "error creating lua state");
+ return -1;
+ }
+
+ int ret = init_main_loop(L, opt->lua_file_);
+ if(!ret)
+ ret = call_main_loop(L, cmd_fd, opt);
+
+ lua_close(L);
+ return ret;
+}
+
+int main(int argc, char* argv[])
+{
+ log_init();
+
+ options_t opt;
+ int ret = options_parse(&opt, argc, argv);
+ if(ret) {
+ if(ret > 0) {
+ fprintf(stderr, "syntax error near: %s\n\n", argv[ret]);
+ }
+ if(ret == -2) {
+ fprintf(stderr, "memory error on options_parse, exiting\n");
+ }
+
+ if(ret != -2)
+ options_print_usage();
+
+ options_clear(&opt);
+ log_close();
+ exit(ret);
+ }
+ string_list_element_t* tmp = opt.log_targets_.first_;
+ if(!tmp) {
+ log_add_target("syslog:3,luaclient,daemon");
+ }
+ else {
+ while(tmp) {
+ ret = log_add_target(tmp->string_);
+ if(ret) {
+ switch(ret) {
+ case -2: fprintf(stderr, "memory error on log_add_target, exitting\n"); break;
+ case -3: fprintf(stderr, "unknown log target: '%s', exitting\n", tmp->string_); break;
+ case -4: fprintf(stderr, "this log target is only allowed once: '%s', exitting\n", tmp->string_); break;
+ default: fprintf(stderr, "syntax error near: '%s', exitting\n", tmp->string_); break;
+ }
+
+ options_clear(&opt);
+ log_close();
+ exit(ret);
+ }
+ tmp = tmp->next_;
+ }
+ }
+ log_printf(NOTICE, "just started...");
+ if(options_parse_post(&opt)) {
+ options_clear(&opt);
+ log_close();
+ exit(-1);
+ }
+
+ priv_info_t priv;
+ if(opt.username_)
+ if(priv_init(&priv, opt.username_, opt.groupname_)) {
+ options_clear(&opt);
+ log_close();
+ exit(-1);
+ }
+
+ FILE* pid_file = NULL;
+ if(opt.pid_file_) {
+ pid_file = fopen(opt.pid_file_, "w");
+ if(!pid_file) {
+ log_printf(WARNING, "unable to open pid file: %s", strerror(errno));
+ }
+ }
+
+ if(opt.chroot_dir_)
+ if(do_chroot(opt.chroot_dir_)) {
+ options_clear(&opt);
+ log_close();
+ exit(-1);
+ }
+ if(opt.username_)
+ if(priv_drop(&priv)) {
+ options_clear(&opt);
+ log_close();
+ exit(-1);
+ }
+
+ if(opt.daemonize_) {
+ pid_t oldpid = getpid();
+ daemonize();
+ log_printf(INFO, "running in background now (old pid: %d)", oldpid);
+ }
+
+ if(pid_file) {
+ pid_t pid = getpid();
+ fprintf(pid_file, "%d", pid);
+ fclose(pid_file);
+ }
+
+ int cmd_fd = connect_command_socket(opt.command_sock_);
+ if(cmd_fd < 0) {
+ options_clear(&opt);
+ log_close();
+ exit(-1);
+ }
+
+ ret = main_loop(cmd_fd, &opt);
+
+ close(cmd_fd);
+
+ if(!ret)
+ log_printf(NOTICE, "normal shutdown");
+ else if(ret < 0)
+ log_printf(NOTICE, "shutdown after error");
+ else
+ log_printf(NOTICE, "shutdown after signal");
+
+ options_clear(&opt);
+ log_close();
+
+ return ret;
+}
diff --git a/mode-leds.lua b/mode-leds.lua
new file mode 100644
index 0000000..51568f8
--- /dev/null
+++ b/mode-leds.lua
@@ -0,0 +1,47 @@
+--
+-- rhctl
+--
+-- Copyright (C) 2009 Christian Pointner <equinox@spreadspace.org>
+--
+-- This file is part of rhctl.
+--
+-- rhctl 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 3 of the License, or
+-- any later version.
+--
+-- rhctl 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 rhctl. If not, see <http://www.gnu.org/licenses/>.
+--
+
+socket = require("socket")
+
+function main_loop(opt)
+ log.printf(log.NOTICE, "main_loop started")
+ local sig = signal.init()
+
+
+ local return_value = 0
+ while return_value == 0 do
+ local readable, _, err = socket.select({ sig }, nil)
+ if(err) then
+ log.printf(log.ERROR, "select returned with error: %s", err)
+ return_value = -1
+ else
+ for _, input in ipairs(readable) do
+ if(input == sig) then
+ return_value = signal.handle()
+ if(return_value == 1) then break end
+ end
+ end
+ end
+ end
+
+ signal.stop()
+ return return_value
+end
diff --git a/options.c b/options.c
index 3200d65..0aa8f24 100644
--- a/options.c
+++ b/options.c
@@ -198,6 +198,9 @@ int options_parse(options_t* opt, int argc, char* argv[])
PARSE_INT_PARAM("-t","--timeout", opt->timeout_)
PARSE_STRING_PARAM("-l","--led", opt->led_filename_)
#endif
+#ifdef OPT_LUACLIENT
+ PARSE_STRING_PARAM("-f","--lua-file", opt->lua_file_)
+#endif
else
return i;
}
@@ -299,6 +302,9 @@ void options_default(options_t* opt)
#ifdef OPT_HEARTBEATCLIENT
opt->progname_ = strdup("heartbeatclient");
#endif
+#ifdef OPT_LUACLIENT
+ opt->progname_ = strdup("luaclient");
+#endif
/* common */
opt->daemonize_ = 1;
@@ -327,8 +333,69 @@ void options_default(options_t* opt)
/* heartbeatclient only */
opt->timeout_ = 15;
opt->led_filename_ = NULL;
+
+/* luaclient only */
+ opt->lua_file_ = strdup("/usr/share/rhctl/mode-leds.lua");
+}
+
+#ifdef OPT_LUACLIENT
+void options_lua_push_string(lua_State* L, const int tidx, const char* key, const char* value)
+{
+ lua_pushstring(L, key);
+ lua_pushstring(L, value);
+ lua_settable(L, tidx);
+}
+
+void options_lua_push_int(lua_State* L, const int tidx, const char* key, const u_int32_t value)
+{
+ lua_pushstring(L, key);
+ lua_pushinteger(L, value);
+ lua_settable(L, tidx);
}
+void options_lua_push_boolean(lua_State* L, const int tidx, const char* key, const u_int32_t value)
+{
+ lua_pushstring(L, key);
+ lua_pushboolean(L, value);
+ lua_settable(L, tidx);
+}
+
+void options_lua_push_string_list(lua_State* L, const int tidx, string_list_t* lst)
+{
+ if(!lst)
+ return;
+
+ string_list_element_t* tmp = lst->first_;
+ if(tmp) {
+ lua_pushstring(L, "log_targets");
+ lua_newtable(L);
+ int i = 1;
+ while(tmp) {
+ lua_pushinteger(L, i++);
+ lua_pushstring(L, tmp->string_);
+ lua_settable(L, -3);
+ tmp = tmp->next_;
+ }
+ lua_settable(L, tidx);
+ }
+}
+
+void options_lua_push(options_t* opt, lua_State* L)
+{
+ lua_newtable(L);
+
+ options_lua_push_string(L, -3, "progname", opt->progname_);
+ options_lua_push_boolean(L, -3, "daemonize", opt->daemonize_);
+ options_lua_push_string(L, -3, "username", opt->username_);
+ options_lua_push_string(L, -3, "groupname", opt->groupname_);
+ options_lua_push_string(L, -3, "chroot_dir", opt->chroot_dir_);
+ options_lua_push_string(L, -3, "pid_file", opt->pid_file_);
+ options_lua_push_string_list(L, -3, &(opt->log_targets_));
+ options_lua_push_string(L, -3, "command_sock", opt->command_sock_);
+ options_lua_push_string(L, -3, "lua_file", opt->lua_file_);
+}
+#endif
+
void options_clear(options_t* opt)
{
if(!opt)
@@ -368,6 +435,10 @@ void options_clear(options_t* opt)
/* heartbeatcleint only */
if(opt->led_filename_)
free(opt->led_filename_);
+
+/* luacleint only */
+ if(opt->lua_file_)
+ free(opt->lua_file_);
}
void options_print_usage()
@@ -414,6 +485,9 @@ void options_print_usage()
printf(" [-t|--timeout] <timeout> heartbeat timeout in tenths of a second e.g. 15 -> 1.5s\n");
printf(" [-l|--led] <led filename> sysfs filename of led device to blink\n");
#endif
+#ifdef OPT_LUACLIENT
+ printf(" [-f|--lua-file] <file> the configuration file e.g. /usr/share/rhctl/mode-leds.lua\n");
+#endif
}
void options_print(options_t* opt)
@@ -469,4 +543,8 @@ void options_print(options_t* opt)
printf("timeout: %d\n", opt->timeout_);
printf("led_filename: '%s'\n", opt->led_filename_);
#endif
+
+#ifdef OPT_LUACLIENT
+ printf("lua_file: '%s'\n", opt->lua_file_);
+#endif
}
diff --git a/options.h b/options.h
index e2a98fb..64ce12b 100644
--- a/options.h
+++ b/options.h
@@ -22,6 +22,8 @@
#ifndef RHCTL_options_h_INCLUDED
#define RHCTL_options_h_INCLUDED
+#include <lua.h>
+
#include "string_list.h"
#include "key_value_storage.h"
#include <termios.h>
@@ -61,6 +63,9 @@ struct options_struct {
/* heartbeatclient only */
u_int32_t timeout_;
char* led_filename_;
+
+/* luaclient only */
+ char* lua_file_;
};
typedef struct options_struct options_t;
@@ -69,6 +74,11 @@ int options_parse_hex_string(const char* hex, buffer_t* buffer);
int options_parse(options_t* opt, int argc, char* argv[]);
int options_parse_post(options_t* opt);
void options_default(options_t* opt);
+void options_lua_push_string(lua_State* L, const int tidx, const char* key, const char* value);
+void options_lua_push_int(lua_State* L, const int tidx, const char* key, const u_int32_t value);
+void options_lua_push_boolean(lua_State* L, const int tidx, const char* key, const u_int32_t value);
+void options_lua_push_string_list(lua_State* L, const int tidx, string_list_t* lst);
+void options_lua_push(options_t* opt, lua_State* L);
void options_clear(options_t* opt);
void options_print_usage();
void options_print(options_t* opt);