Files
smmapdfw/smmapdfw/lua_worker/lua_worker.c
whottgen 59e2a2d342 changes
2004-09-29 19:32:21 +00:00

192 lines
4.8 KiB
C

#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, cnt;
char *lua_filename;
const luaL_reg *lualib;
cfgl_t *cfgl_iter;
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)) {
res = lualib->func(lch->l);
/* syslog(LOG_DEBUG, "lua_init %s loaded, result %d", lualibname, res); */
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);
lua_newtable(lch->l);
cnt = 0;
for (cfgl_iter = lch->cfg; cfgl_iter != NULL; cfgl_iter = cfgl_iter->next) {
lua_pushstring(lch->l, cfgl_iter->name);
lua_pushstring(lch->l, cfgl_iter->value);
lua_rawset(lch->l, -3);
cnt++;
}
lua_pushliteral(lch->l, "n"); /* Pushes the literal */
lua_pushnumber(lch->l, cnt); /* Pushes the total number of cells */
lua_rawset(lch->l, -3); /* Stores the pair in the table */
lua_setglobal(lch->l, "config");
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);
return -1;
}
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);
/* peek the result from the stack */
lua_output = (char*) lua_tostring(lwh->l, lua_gettop(lwh->l));
result = lua_tonumber(lwh->l, lua_gettop(lwh->l));
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);
}
/* remove the result from the stack */
lua_pop(lwh->l, 2);
return result;
}