diff options
Diffstat (limited to 'src/lib-storage/mail-lua.c')
-rw-r--r-- | src/lib-storage/mail-lua.c | 143 |
1 files changed, 143 insertions, 0 deletions
diff --git a/src/lib-storage/mail-lua.c b/src/lib-storage/mail-lua.c new file mode 100644 index 0000000..a559f98 --- /dev/null +++ b/src/lib-storage/mail-lua.c @@ -0,0 +1,143 @@ +/* Copyright (c) 2018 Dovecot authors, see the included COPYING file */ + +#include "lib.h" +#include "str.h" +#include "istream.h" +#include "array.h" +#include "var-expand.h" +#include "dlua-script.h" +#include "dlua-script-private.h" +#include "mail-storage.h" +#include "mailbox-attribute.h" +#include "mail-storage-lua.h" +#include "mail-storage-lua-private.h" +#include "mail-user.h" + +#define LUA_STORAGE_MAIL "struct mail" + +void dlua_push_mail(lua_State *L, struct mail *mail) +{ + luaL_checkstack(L, 20, "out of memory"); + /* create a table for holding few things */ + lua_createtable(L, 0, 20); + luaL_setmetatable(L, LUA_STORAGE_MAIL); + + lua_pushlightuserdata(L, mail); + lua_setfield(L, -2, "item"); + +#undef LUA_TABLE_SET_NUMBER +#define LUA_TABLE_SET_NUMBER(field) \ + lua_pushnumber(L, mail->field); \ + lua_setfield(L, -2, #field); +#undef LUA_TABLE_SET_BOOL +#define LUA_TABLE_SET_BOOL(field) \ + lua_pushboolean(L, mail->field); \ + lua_setfield(L, -2, #field); + + LUA_TABLE_SET_NUMBER(seq); + LUA_TABLE_SET_NUMBER(uid); + LUA_TABLE_SET_BOOL(expunged); + + dlua_push_mailbox(L, mail->box); + lua_setfield(L, -2, "mailbox"); + +} + +static struct mail * +lua_check_storage_mail(lua_State *L, int arg) +{ + if (!lua_istable(L, arg)) { + (void)luaL_error(L, "Bad argument #%d, expected %s got %s", + arg, LUA_STORAGE_MAIL, + lua_typename(L, lua_type(L, arg))); + } + lua_pushliteral(L, "item"); + lua_rawget(L, arg); + void *bp = (void*)lua_touserdata(L, -1); + lua_pop(L, 1); + return (struct mail*)bp; +} + +static int lua_storage_mail_tostring(lua_State *L) +{ + DLUA_REQUIRE_ARGS(L, 1); + struct mail *mail = lua_check_storage_mail(L, 1); + + const char *str = + t_strdup_printf("<%s:UID %u>", mailbox_get_vname(mail->box), + mail->uid); + lua_pushstring(L, str); + return 1; +} + +static int lua_storage_mail_eq(lua_State *L) +{ + DLUA_REQUIRE_ARGS(L, 2); + struct mail *mail = lua_check_storage_mail(L, 1); + struct mail *mail2 = lua_check_storage_mail(L, 2); + + if (!DLUA_MAILBOX_EQUALS(mail->box, mail2->box)) + lua_pushboolean(L, FALSE); + else + lua_pushboolean(L, mail->uid != mail2->uid); + return 1; +} + +static int lua_storage_mail_lt(lua_State *L) +{ + DLUA_REQUIRE_ARGS(L, 2); + struct mail *mail = lua_check_storage_mail(L, 1); + struct mail *mail2 = lua_check_storage_mail(L, 2); + + if (!DLUA_MAILBOX_EQUALS(mail->box, mail2->box)) + return luaL_error(L, + "For lt, Mail can only be compared within same mailbox"); + else + lua_pushboolean(L, mail->uid < mail2->uid); + return 1; +} + +static int lua_storage_mail_le(lua_State *L) +{ + DLUA_REQUIRE_ARGS(L, 2); + struct mail *mail = lua_check_storage_mail(L, 1); + struct mail *mail2 = lua_check_storage_mail(L, 2); + + if (!DLUA_MAILBOX_EQUALS(mail->box, mail2->box)) + return luaL_error(L, + "For le, mails can only be within same mailbox"); + else + lua_pushboolean(L, mail->uid <= mail2->uid); + + return 1; +} + +static int lua_storage_mail_gc(lua_State *L) +{ + (void)lua_check_storage_mail(L, 1); + + /* reset value to NULL */ + lua_pushliteral(L, "item"); + lua_pushnil(L); + lua_rawset(L, 1); + + return 0; +} + +static luaL_Reg lua_storage_mail_methods[] = { + { "__tostring", lua_storage_mail_tostring }, + { "__eq", lua_storage_mail_eq }, + { "__lt", lua_storage_mail_lt }, + { "__le", lua_storage_mail_le }, + { "__gc", lua_storage_mail_gc }, + { NULL, NULL } +}; + +void lua_storage_mail_register(struct dlua_script *script) +{ + luaL_newmetatable(script->L, LUA_STORAGE_MAIL); + lua_pushvalue(script->L, -1); + lua_setfield(script->L, -2, "__index"); + luaL_setfuncs(script->L, lua_storage_mail_methods, 0); + lua_pop(script->L, 1); +} |