lua worker stuff

This commit is contained in:
whottgen 2004-09-21 12:53:35 +00:00
parent 6f06324736
commit 1f5605b795
4 changed files with 196 additions and 6 deletions

View File

@ -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
View 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;
}

View File

@ -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
View 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