lua worker stuff
This commit is contained in:
parent
6f06324736
commit
1f5605b795
@ -17,8 +17,10 @@ endif
|
||||
ifeq ($(OS), Linux)
|
||||
BDB_INC ?= /usr/include
|
||||
BDB_LIB ?= /usr/lib/libdb.a
|
||||
CFLAGS = $(COMMON_CFLAGS) -DLINUX -I$(BDB_INC)
|
||||
LDFLAGS = $(COMMON_LDFLAGS) -lresolv -pthread -ldl
|
||||
LUA_INC ?= /usr/include/lua50
|
||||
LUA_LIB ?= /usr/lib/liblualib50.a /usr/lib/liblua50.a
|
||||
CFLAGS = $(COMMON_CFLAGS) -DLINUX -I$(BDB_INC) -I$(LUA_INC)
|
||||
LDFLAGS = $(COMMON_LDFLAGS) -lresolv -pthread -ldl -lm
|
||||
SHARED = -shared
|
||||
endif
|
||||
|
||||
@ -36,7 +38,7 @@ LIBS =
|
||||
MOD_LIBS =
|
||||
CC = gcc
|
||||
|
||||
all: smmapd test_workers.so verify_worker.so cyrus_worker.so
|
||||
all: smmapd test_workers.so verify_worker.so cyrus_worker.so lua_worker.so
|
||||
|
||||
smmapd: $(MAIN_OBJ)
|
||||
$(CC) $(LDFLAGS) -o $@ $^ $(LIBS)
|
||||
@ -50,6 +52,10 @@ verify_worker.so: verify_worker.o config_public.o dns.o queue.o smtp.o $(BDB_LIB
|
||||
cyrus_worker.so: cyrus_worker.o config_public.o smtp.o dns.o
|
||||
$(CC) $(LDFLAGS) $(SHARED) -o $@ $^
|
||||
|
||||
lua_worker.so: lua_worker.o config_public.o $(LUA_LIB)
|
||||
$(CC) $(LDFLAGS) $(SHARED) -o $@ $^
|
||||
|
||||
|
||||
clean:
|
||||
-rm -f *o *so smmapd
|
||||
|
||||
|
170
smmapdfw/lua_worker.c
Normal file
170
smmapdfw/lua_worker.c
Normal file
@ -0,0 +1,170 @@
|
||||
#include <stdlib.h>
|
||||
#include <syslog.h>
|
||||
#include <string.h>
|
||||
#include <lua.h>
|
||||
#include <lualib.h>
|
||||
#include <lauxlib.h>
|
||||
|
||||
#include "containers_public.h"
|
||||
#include "smmapd.h"
|
||||
|
||||
|
||||
#define CFG_LUALIB_NAMES "load"
|
||||
#define CFG_LUALIB_DELIMITER " "
|
||||
#define CFG_LUA_ENTRYPOINT "entrypoint"
|
||||
#define CFG_LUA_FILENAME "file"
|
||||
|
||||
int lua_init(cfgl_t *cfg, void **handle);
|
||||
int lua_destroy(void *handle);
|
||||
int lua_work_setup(void *handle, void **work_handle);
|
||||
int lua_work_destroy(void *handle, void *work_handle);
|
||||
int lua_work(void *handle, void *work_handle, char *input, char *output);
|
||||
|
||||
|
||||
static const luaL_reg lualibs[] = {
|
||||
{ "base", luaopen_base },
|
||||
{ "table", luaopen_table },
|
||||
{ "io", luaopen_io },
|
||||
{ "string", luaopen_string },
|
||||
{ "math", luaopen_math },
|
||||
{ "debug", luaopen_debug },
|
||||
{ "loadlib", luaopen_loadlib },
|
||||
{ NULL, NULL }
|
||||
};
|
||||
|
||||
|
||||
|
||||
class_descriptor_t lua_worker = {
|
||||
"lua_worker",
|
||||
&lua_init,
|
||||
&lua_destroy,
|
||||
&lua_work_setup,
|
||||
&lua_work,
|
||||
&lua_work_destroy
|
||||
};
|
||||
|
||||
struct lua_container_handle_s {
|
||||
cfgl_t *cfg;
|
||||
lua_State *l;
|
||||
char *lua_entrypoint;
|
||||
};
|
||||
|
||||
typedef struct lua_container_handle_s lua_container_handle_t;
|
||||
|
||||
struct lua_worker_handle_s {
|
||||
lua_container_handle_t *lch;
|
||||
lua_State *l;
|
||||
};
|
||||
|
||||
typedef struct lua_worker_handle_s lua_worker_handle_t;
|
||||
|
||||
|
||||
int lua_init(cfgl_t *cfg, void **handle) {
|
||||
lua_container_handle_t *lch;
|
||||
char *lualibname, *lualibnames;
|
||||
int res;
|
||||
char *lua_filename;
|
||||
const luaL_reg *lualib;
|
||||
|
||||
lch = (lua_container_handle_t*) malloc(sizeof(lua_container_handle_t));
|
||||
lch->cfg = cfg;
|
||||
|
||||
lua_filename = findcfgl(lch->cfg, CFG_LUA_FILENAME);
|
||||
if (NULL == lua_filename) {
|
||||
syslog(LOG_ERR, "lua_init: no lua_filename given in config");
|
||||
return -1;
|
||||
}
|
||||
|
||||
lch->lua_entrypoint = findcfglx(lch->cfg, CFG_LUA_ENTRYPOINT, "main");
|
||||
|
||||
lch->l = lua_open();
|
||||
|
||||
|
||||
lualibnames = findcfglx(lch->cfg, CFG_LUALIB_NAMES, "");
|
||||
while (NULL != (lualibname = strtok(lualibnames, CFG_LUALIB_DELIMITER))) {
|
||||
lualibnames = NULL; /* this is for subsequence calls of strtok */
|
||||
syslog(LOG_DEBUG, "lua_init: loading lib %s", lualibname);
|
||||
|
||||
for (lualib = lualibs; lualib->func != NULL; lualib++) {
|
||||
if (0 == strcmp(lualib->name, lualibname)) {
|
||||
lualib->func(lch->l);
|
||||
lua_settop(lch->l, 0);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
res = luaL_loadfile(lch->l, lua_filename);
|
||||
if (0 != res) {
|
||||
syslog(LOG_ERR, "lua_init: unable to load lua file %s", lua_filename);
|
||||
lua_close(lch->l);
|
||||
free(lch);
|
||||
return -1;
|
||||
}
|
||||
syslog(LOG_DEBUG, "lua_init: lua file %s loaded and compiled", lua_filename);
|
||||
|
||||
res = lua_pcall(lch->l, 0, 0, 0);
|
||||
if (0 != res) {
|
||||
syslog(LOG_ERR, "lua_init: unable to execute lua file %s", lua_filename);
|
||||
lua_close(lch->l);
|
||||
free(lch);
|
||||
}
|
||||
syslog(LOG_DEBUG, "lua_init: lua file %s executed", lua_filename);
|
||||
|
||||
|
||||
*handle = lch;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int lua_destroy(void *handle) {
|
||||
lua_container_handle_t *lch = (lua_container_handle_t*) handle;
|
||||
|
||||
lua_close(lch->l);
|
||||
free(lch);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int lua_work_setup(void *handle, void **work_handle) {
|
||||
lua_worker_handle_t *lwh = (lua_worker_handle_t*)malloc(sizeof(lua_worker_handle_t));
|
||||
lwh->lch = (lua_container_handle_t*) handle;
|
||||
|
||||
lwh->l = lua_newthread(lwh->lch->l);
|
||||
|
||||
*work_handle = lwh;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int lua_work_destroy(void *handle, void *work_handle) {
|
||||
lua_worker_handle_t *lwh = (lua_worker_handle_t*) work_handle;
|
||||
|
||||
free(lwh);
|
||||
}
|
||||
|
||||
int lua_work(void *handle, void *work_handle, char *input, char *output) {
|
||||
static const char *SCRIPT_ERROR = "error in lua script";
|
||||
|
||||
lua_worker_handle_t *lwh = (lua_worker_handle_t*) work_handle;
|
||||
int result, res;
|
||||
char *lua_output;
|
||||
|
||||
lua_getglobal(lwh->l, lwh->lch->lua_entrypoint);
|
||||
lua_pushstring(lwh->l, input);
|
||||
|
||||
res = lua_pcall(lwh->l, 1, 2, 0);
|
||||
|
||||
lua_output = (char*) lua_tostring(lwh->l, lua_gettop(lwh->l));
|
||||
lua_pop(lwh->l, 1);
|
||||
result = lua_tonumber(lwh->l, lua_gettop(lwh->l));
|
||||
lua_pop(lwh->l, 1);
|
||||
|
||||
if (0 != res) {
|
||||
syslog(LOG_ERR, "lua_work: error when calling entrypoint function: %d", res);
|
||||
result = SMM_TEMP_NOK;
|
||||
snprintf(output, ANSWER_BUFSIZE, "%s: %s", SCRIPT_ERROR, lua_output);
|
||||
} else {
|
||||
snprintf(output, ANSWER_BUFSIZE, lua_output);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
@ -1,10 +1,11 @@
|
||||
[global]
|
||||
do_fork = 1
|
||||
do_fork = 0
|
||||
pid_file = smmapd.pid
|
||||
address = 127.0.0.1
|
||||
port = 8887
|
||||
plugin_dir = /home/who/Sources/private/smmapd
|
||||
plugins = test_worker1 test_worker2 verifier cyruscheck
|
||||
plugin_dir = /home/who/Sources/sf/smmapdfw
|
||||
; plugins = test_worker1 test_worker2 verifier cyruscheck lua_worker
|
||||
plugins = lua_worker
|
||||
|
||||
[test_worker1]
|
||||
obj = test_workers.so
|
||||
@ -30,3 +31,11 @@ timeout = 10
|
||||
sender_address = <testsender>
|
||||
lhlo_arg = local
|
||||
lmtp_port = 24
|
||||
|
||||
[lua_worker]
|
||||
obj = lua_worker.so
|
||||
; load = base string table math loadlib io
|
||||
load = base string io
|
||||
lua_path = .
|
||||
file = worker.l
|
||||
entrypoint = f
|
||||
|
5
smmapdfw/worker.l
Normal file
5
smmapdfw/worker.l
Normal file
@ -0,0 +1,5 @@
|
||||
function f (i)
|
||||
io.write("[lua] output from lua\n")
|
||||
io.write("[lua] ", i, "\n")
|
||||
return 1, string.upper(i)
|
||||
end
|
Loading…
x
Reference in New Issue
Block a user