lua worker stuff
This commit is contained in:
@ -17,8 +17,10 @@ endif
|
|||||||
ifeq ($(OS), Linux)
|
ifeq ($(OS), Linux)
|
||||||
BDB_INC ?= /usr/include
|
BDB_INC ?= /usr/include
|
||||||
BDB_LIB ?= /usr/lib/libdb.a
|
BDB_LIB ?= /usr/lib/libdb.a
|
||||||
CFLAGS = $(COMMON_CFLAGS) -DLINUX -I$(BDB_INC)
|
LUA_INC ?= /usr/include/lua50
|
||||||
LDFLAGS = $(COMMON_LDFLAGS) -lresolv -pthread -ldl
|
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
|
SHARED = -shared
|
||||||
endif
|
endif
|
||||||
|
|
||||||
@ -36,7 +38,7 @@ LIBS =
|
|||||||
MOD_LIBS =
|
MOD_LIBS =
|
||||||
CC = gcc
|
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)
|
smmapd: $(MAIN_OBJ)
|
||||||
$(CC) $(LDFLAGS) -o $@ $^ $(LIBS)
|
$(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
|
cyrus_worker.so: cyrus_worker.o config_public.o smtp.o dns.o
|
||||||
$(CC) $(LDFLAGS) $(SHARED) -o $@ $^
|
$(CC) $(LDFLAGS) $(SHARED) -o $@ $^
|
||||||
|
|
||||||
|
lua_worker.so: lua_worker.o config_public.o $(LUA_LIB)
|
||||||
|
$(CC) $(LDFLAGS) $(SHARED) -o $@ $^
|
||||||
|
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
-rm -f *o *so smmapd
|
-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]
|
[global]
|
||||||
do_fork = 1
|
do_fork = 0
|
||||||
pid_file = smmapd.pid
|
pid_file = smmapd.pid
|
||||||
address = 127.0.0.1
|
address = 127.0.0.1
|
||||||
port = 8887
|
port = 8887
|
||||||
plugin_dir = /home/who/Sources/private/smmapd
|
plugin_dir = /home/who/Sources/sf/smmapdfw
|
||||||
plugins = test_worker1 test_worker2 verifier cyruscheck
|
; plugins = test_worker1 test_worker2 verifier cyruscheck lua_worker
|
||||||
|
plugins = lua_worker
|
||||||
|
|
||||||
[test_worker1]
|
[test_worker1]
|
||||||
obj = test_workers.so
|
obj = test_workers.so
|
||||||
@ -30,3 +31,11 @@ timeout = 10
|
|||||||
sender_address = <testsender>
|
sender_address = <testsender>
|
||||||
lhlo_arg = local
|
lhlo_arg = local
|
||||||
lmtp_port = 24
|
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
|
Reference in New Issue
Block a user