2011-03-06 06:58:58 -05:00
|
|
|
#include <stdio.h>
|
|
|
|
#include <stdlib.h>
|
|
|
|
#include <string.h>
|
|
|
|
|
|
|
|
#include <lua.h>
|
|
|
|
#include <lauxlib.h>
|
|
|
|
#include <lualib.h>
|
|
|
|
|
|
|
|
#include "imapfilter.h"
|
|
|
|
#include "pathnames.h"
|
|
|
|
|
|
|
|
|
|
|
|
extern options opts;
|
|
|
|
extern struct sessionhead sessions;
|
|
|
|
|
|
|
|
static lua_State *lua; /* Lua interpreter state. */
|
|
|
|
|
|
|
|
|
|
|
|
void init_options(void);
|
|
|
|
void interactive_mode(void);
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Start the Lua interpreter, export IMAP core and system functions, load the
|
|
|
|
* Lua interface functions, load and execute imapfilter's configuration file.
|
|
|
|
*/
|
|
|
|
void
|
|
|
|
start_lua()
|
|
|
|
{
|
|
|
|
|
|
|
|
lua = luaL_newstate();
|
|
|
|
|
|
|
|
luaL_openlibs(lua);
|
|
|
|
|
|
|
|
luaopen_ifcore(lua);
|
|
|
|
luaopen_ifsys(lua);
|
|
|
|
luaopen_ifre(lua);
|
|
|
|
|
|
|
|
lua_settop(lua, 0);
|
|
|
|
|
|
|
|
init_options();
|
|
|
|
|
|
|
|
if (luaL_loadfile(lua, PATHNAME_COMMON) ||
|
|
|
|
lua_pcall(lua, 0, LUA_MULTRET, 0))
|
|
|
|
fatal(ERROR_CONFIG, "%s\n", lua_tostring(lua, -1));
|
|
|
|
|
|
|
|
if (luaL_loadfile(lua, PATHNAME_SET) ||
|
|
|
|
lua_pcall(lua, 0, LUA_MULTRET, 0))
|
|
|
|
fatal(ERROR_CONFIG, "%s\n", lua_tostring(lua, -1));
|
|
|
|
|
|
|
|
if (luaL_loadfile(lua, PATHNAME_REGEX) ||
|
|
|
|
lua_pcall(lua, 0, LUA_MULTRET, 0))
|
|
|
|
fatal(ERROR_CONFIG, "%s\n", lua_tostring(lua, -1));
|
|
|
|
|
|
|
|
if (luaL_loadfile(lua, PATHNAME_ACCOUNT) ||
|
|
|
|
lua_pcall(lua, 0, LUA_MULTRET, 0))
|
|
|
|
fatal(ERROR_CONFIG, "%s\n", lua_tostring(lua, -1));
|
|
|
|
|
|
|
|
if (luaL_loadfile(lua, PATHNAME_MAILBOX) ||
|
|
|
|
lua_pcall(lua, 0, LUA_MULTRET, 0))
|
|
|
|
fatal(ERROR_CONFIG, "%s\n", lua_tostring(lua, -1));
|
|
|
|
|
|
|
|
if (luaL_loadfile(lua, PATHNAME_MESSAGE) ||
|
|
|
|
lua_pcall(lua, 0, LUA_MULTRET, 0))
|
|
|
|
fatal(ERROR_CONFIG, "%s\n", lua_tostring(lua, -1));
|
|
|
|
|
|
|
|
if (luaL_loadfile(lua, PATHNAME_OPTIONS) ||
|
|
|
|
lua_pcall(lua, 0, LUA_MULTRET, 0))
|
|
|
|
fatal(ERROR_CONFIG, "%s\n", lua_tostring(lua, -1));
|
|
|
|
|
|
|
|
if (luaL_loadfile(lua, PATHNAME_AUXILIARY) ||
|
|
|
|
lua_pcall(lua, 0, LUA_MULTRET, 0))
|
|
|
|
fatal(ERROR_CONFIG, "%s\n", lua_tostring(lua, -1));
|
|
|
|
|
|
|
|
if (opts.oneline != NULL) {
|
|
|
|
if (luaL_loadbuffer(lua, opts.oneline, strlen(opts.oneline),
|
|
|
|
"=<command line>") || lua_pcall(lua, 0, LUA_MULTRET, 0))
|
|
|
|
fatal(ERROR_CONFIG, "%s\n", lua_tostring(lua, -1));
|
|
|
|
} else {
|
|
|
|
if (luaL_loadfile(lua, opts.config) ||
|
|
|
|
lua_pcall(lua, 0, LUA_MULTRET, 0))
|
|
|
|
fatal(ERROR_CONFIG, "%s\n", lua_tostring(lua, -1));
|
|
|
|
}
|
|
|
|
|
|
|
|
if (opts.interactive)
|
|
|
|
interactive_mode();
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Stop the Lua interpreter.
|
|
|
|
*/
|
|
|
|
void
|
|
|
|
stop_lua(void)
|
|
|
|
{
|
|
|
|
|
|
|
|
lua_close(lua);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Set default values to program's options.
|
|
|
|
*/
|
|
|
|
void
|
|
|
|
init_options(void)
|
|
|
|
{
|
|
|
|
|
|
|
|
lua_newtable(lua);
|
|
|
|
|
|
|
|
set_table_boolean("certificates", 1);
|
|
|
|
set_table_boolean("crammd5", 1);
|
|
|
|
set_table_boolean("create", 0);
|
|
|
|
set_table_boolean("expunge", 1);
|
|
|
|
set_table_number("keepalive", 29);
|
|
|
|
set_table_boolean("namespace", 1);
|
2012-02-26 19:17:02 -05:00
|
|
|
set_table_string("recover", "all");
|
2011-03-06 06:58:58 -05:00
|
|
|
set_table_boolean("starttls", 1);
|
|
|
|
set_table_boolean("subscribe", 0);
|
2012-02-19 18:09:14 -05:00
|
|
|
set_table_number("timeout", 60);
|
2011-03-06 06:58:58 -05:00
|
|
|
|
|
|
|
lua_setglobal(lua, "options");
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Interactive mode.
|
|
|
|
*/
|
|
|
|
void
|
|
|
|
interactive_mode(void)
|
|
|
|
{
|
|
|
|
char buf[LINE_MAX];
|
|
|
|
|
|
|
|
for (;;) {
|
|
|
|
printf("> ");
|
|
|
|
fflush(stdout);
|
|
|
|
|
|
|
|
if (fgets(buf, sizeof(buf), stdin) == NULL) {
|
|
|
|
printf("\n");
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (luaL_loadbuffer(lua, buf, strlen(buf), "=<line>") ||
|
|
|
|
lua_pcall(lua, 0, LUA_MULTRET, 0)) {
|
|
|
|
error("%s\n", lua_tostring(lua, -1));
|
|
|
|
lua_pop(lua, 1);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Get from the configuration file the value of a boolean option variable.
|
|
|
|
*/
|
|
|
|
int
|
|
|
|
get_option_boolean(const char *opt)
|
|
|
|
{
|
|
|
|
int b;
|
|
|
|
|
2012-02-05 07:29:43 -05:00
|
|
|
lua_getglobal(lua, "options");
|
|
|
|
lua_getfield(lua, -1, opt);
|
2011-03-06 06:58:58 -05:00
|
|
|
b = lua_toboolean(lua, -1);
|
|
|
|
lua_pop(lua, 2);
|
|
|
|
|
|
|
|
return b;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Get from the configuration file the value of a number option variable.
|
|
|
|
*/
|
|
|
|
lua_Number
|
|
|
|
get_option_number(const char *opt)
|
|
|
|
{
|
|
|
|
lua_Number n;
|
|
|
|
|
2012-02-05 07:29:43 -05:00
|
|
|
lua_getglobal(lua, "options");
|
|
|
|
lua_getfield(lua, -1, opt);
|
2011-03-06 06:58:58 -05:00
|
|
|
n = lua_tonumber(lua, -1);
|
|
|
|
lua_pop(lua, 2);
|
|
|
|
|
|
|
|
return n;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Get from the configuration file the value of a string option variable.
|
|
|
|
*/
|
|
|
|
const char *
|
|
|
|
get_option_string(const char *opt)
|
|
|
|
{
|
|
|
|
const char *s;
|
|
|
|
|
2012-02-05 07:29:43 -05:00
|
|
|
lua_getglobal(lua, "options");
|
|
|
|
lua_getfield(lua, -1, opt);
|
2011-03-06 06:58:58 -05:00
|
|
|
s = lua_tostring(lua, -1);
|
|
|
|
lua_pop(lua, 2);
|
|
|
|
|
2012-02-26 19:17:02 -05:00
|
|
|
if (!s)
|
|
|
|
return "";
|
|
|
|
|
2011-03-06 06:58:58 -05:00
|
|
|
return s;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Set a table's element value to the specified boolean.
|
|
|
|
*/
|
|
|
|
int
|
|
|
|
set_table_boolean(const char *key, int value)
|
|
|
|
{
|
|
|
|
|
|
|
|
lua_pushstring(lua, key);
|
|
|
|
lua_pushboolean(lua, value);
|
|
|
|
lua_settable(lua, -3);
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Set a table's element value to the specified number.
|
|
|
|
*/
|
|
|
|
int
|
|
|
|
set_table_number(const char *key, lua_Number value)
|
|
|
|
{
|
|
|
|
|
|
|
|
lua_pushstring(lua, key);
|
|
|
|
lua_pushnumber(lua, value);
|
|
|
|
lua_settable(lua, -3);
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
2012-02-26 19:17:02 -05:00
|
|
|
|
|
|
|
/*
|
|
|
|
* Set a table's element value to the specified string.
|
|
|
|
*/
|
|
|
|
int
|
|
|
|
set_table_string(const char *key, const char *value)
|
|
|
|
{
|
|
|
|
|
|
|
|
lua_pushstring(lua, key);
|
|
|
|
lua_pushstring(lua, value);
|
|
|
|
lua_settable(lua, -3);
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
|