403 lines
9.0 KiB
C
403 lines
9.0 KiB
C
|
#include "lua.h"
|
||
|
#include "lauxlib.h"
|
||
|
#include "lualib.h"
|
||
|
|
||
|
|
||
|
#include "c-client.h"
|
||
|
#include "imap4r1.h"
|
||
|
#include <stdio.h>
|
||
|
#include <errno.h>
|
||
|
extern int errno; /* just in case */
|
||
|
|
||
|
#define M_LOG(a,...) syslog (LOG_NOTICE,"limap@[%s: %d]: " a "\n", __FILE__, \
|
||
|
__LINE__, ##__VA_ARGS__)
|
||
|
#define M_WARN(a,...) syslog (LOG_WARNING, "limap@[%s: %d]: " a "\n", __FILE__, \
|
||
|
__LINE__, ##__VA_ARGS__)
|
||
|
#define M_ERROR(a,...) syslog (LOG_ERR, "limap@[%s: %d]: " a "\n", __FILE__, \
|
||
|
__LINE__, ##__VA_ARGS__)
|
||
|
|
||
|
/* Co-routines from MAIL library */
|
||
|
|
||
|
|
||
|
/* Message matches a search
|
||
|
* Accepts: MAIL stream
|
||
|
* message number
|
||
|
*/
|
||
|
|
||
|
void mm_searched (MAILSTREAM *stream,unsigned long msgno)
|
||
|
{
|
||
|
/* dummy routine */
|
||
|
}
|
||
|
|
||
|
|
||
|
/* Message exists (i.e. there are that many messages in the mailbox)
|
||
|
* Accepts: MAIL stream
|
||
|
* message number
|
||
|
*/
|
||
|
|
||
|
void mm_exists (MAILSTREAM *stream,unsigned long number)
|
||
|
{
|
||
|
M_LOG("New emails found in %s: %d", stream->mailbox, number);
|
||
|
int * n = stream->sparep;
|
||
|
if(!n) return;
|
||
|
*n = number;
|
||
|
}
|
||
|
|
||
|
|
||
|
/* Message expunged
|
||
|
* Accepts: MAIL stream
|
||
|
* message number
|
||
|
*/
|
||
|
|
||
|
void mm_expunged (MAILSTREAM *stream,unsigned long number)
|
||
|
{
|
||
|
/* dummy routine */
|
||
|
}
|
||
|
|
||
|
|
||
|
/* Message flags update seen
|
||
|
* Accepts: MAIL stream
|
||
|
* message number
|
||
|
*/
|
||
|
|
||
|
void mm_flags (MAILSTREAM *stream,unsigned long number)
|
||
|
{
|
||
|
/* dummy routine */
|
||
|
}
|
||
|
/* Mailbox found
|
||
|
* Accepts: MAIL stream
|
||
|
* hierarchy delimiter
|
||
|
* mailbox name
|
||
|
* mailbox attributes
|
||
|
*/
|
||
|
|
||
|
void mm_list (MAILSTREAM *stream,int delimiter,char *name,long attributes)
|
||
|
{
|
||
|
lua_State *L = stream->sparep;
|
||
|
if(!L)
|
||
|
return;
|
||
|
if(attributes & LATT_NOSELECT)
|
||
|
{
|
||
|
return;
|
||
|
}
|
||
|
size_t cnt = lua_rawlen(L,-1) + 1;
|
||
|
lua_pushnumber(L,cnt);
|
||
|
lua_newtable(L);
|
||
|
char delim[2];
|
||
|
delim[0] = (char) delimiter;
|
||
|
delim[1] = '\0';
|
||
|
if(!name)
|
||
|
return;
|
||
|
lua_pushstring(L, "delimiter");
|
||
|
lua_pushstring(L, delim);
|
||
|
lua_settable(L, -3);
|
||
|
|
||
|
lua_pushstring(L, "name");
|
||
|
lua_pushstring(L, name);
|
||
|
lua_settable(L, -3);
|
||
|
|
||
|
lua_pushstring(L, "LATT_NOINFERIORS");
|
||
|
lua_pushboolean(L, attributes & LATT_NOINFERIORS);
|
||
|
lua_settable(L, -3);
|
||
|
|
||
|
lua_pushstring(L, "LATT_NOSELECT");
|
||
|
lua_pushboolean(L, attributes & LATT_NOSELECT);
|
||
|
lua_settable(L, -3);
|
||
|
|
||
|
lua_pushstring(L, "LATT_MARKED");
|
||
|
lua_pushboolean(L, attributes & LATT_MARKED);
|
||
|
lua_settable(L, -3);
|
||
|
|
||
|
lua_pushstring(L, "LATT_UNMARKED");
|
||
|
lua_pushboolean(L, attributes & LATT_UNMARKED);
|
||
|
lua_settable(L, -3);
|
||
|
lua_settable(L, -3);
|
||
|
}
|
||
|
|
||
|
|
||
|
/* Subscribe mailbox found
|
||
|
* Accepts: MAIL stream
|
||
|
* hierarchy delimiter
|
||
|
* mailbox name
|
||
|
* mailbox attributes
|
||
|
*/
|
||
|
|
||
|
void mm_lsub (MAILSTREAM *stream,int delimiter,char *name,long attributes)
|
||
|
{
|
||
|
/* dummy routine */
|
||
|
}
|
||
|
|
||
|
|
||
|
/* Mailbox status
|
||
|
* Accepts: MAIL stream
|
||
|
* mailbox name
|
||
|
* mailbox status
|
||
|
*/
|
||
|
|
||
|
void mm_status (MAILSTREAM *stream,char *mailbox,MAILSTATUS *status)
|
||
|
{
|
||
|
if (status->recent || status->unseen)
|
||
|
printf ("%lu new message(s) (%lu unseen),",status->recent,status->unseen);
|
||
|
else fputs ("No new messages,",stdout);
|
||
|
printf (" %lu total in %s\n",status->messages,mailbox);
|
||
|
}
|
||
|
/* Notification event
|
||
|
* Accepts: MAIL stream
|
||
|
* string to log
|
||
|
* error flag
|
||
|
*/
|
||
|
|
||
|
void mm_notify (MAILSTREAM *stream,char *string,long errflg)
|
||
|
{
|
||
|
if (!errflg && (string[0] == '[') &&
|
||
|
((string[1] == 'T') || (string[1] == 't')) &&
|
||
|
((string[2] == 'R') || (string[2] == 'r')) &&
|
||
|
((string[3] == 'Y') || (string[3] == 'y')) &&
|
||
|
((string[4] == 'C') || (string[4] == 'c')) &&
|
||
|
((string[5] == 'R') || (string[5] == 'r')) &&
|
||
|
((string[6] == 'E') || (string[6] == 'e')) &&
|
||
|
((string[7] == 'A') || (string[7] == 'a')) &&
|
||
|
((string[8] == 'T') || (string[8] == 't')) &&
|
||
|
((string[9] == 'E') || (string[9] == 'e')) &&
|
||
|
(string[10] == ']'))
|
||
|
mm_log (string,errflg); /* just do mm_log action */
|
||
|
}
|
||
|
|
||
|
/* Log an event for the user to see
|
||
|
* Accepts: string to log
|
||
|
* error flag
|
||
|
*/
|
||
|
|
||
|
void mm_log (char *string,long errflg)
|
||
|
{
|
||
|
switch (errflg) {
|
||
|
case BYE:
|
||
|
case NIL: /* no error */
|
||
|
M_LOG ("[%s]",string);
|
||
|
break;
|
||
|
case PARSE: /* parsing problem */
|
||
|
case WARN: /* warning */
|
||
|
M_WARN("warning: %s",string);
|
||
|
break;
|
||
|
case ERROR: /* error */
|
||
|
default:
|
||
|
M_ERROR ("%s",string);
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
|
||
|
/* Log an event to debugging telemetry
|
||
|
* Accepts: string to log
|
||
|
*/
|
||
|
|
||
|
void mm_dlog (char *string)
|
||
|
{
|
||
|
M_LOG ("%s",string);
|
||
|
}
|
||
|
/* Get user name and password for this host
|
||
|
* Accepts: parse of network mailbox name
|
||
|
* where to return user name
|
||
|
* where to return password
|
||
|
* trial count
|
||
|
*/
|
||
|
|
||
|
void mm_login (NETMBX *mb,char *username,char *password,long trial)
|
||
|
{
|
||
|
if(mb->user)
|
||
|
{
|
||
|
char * tmp = mb->user;
|
||
|
(void)strsep(&tmp, ";");
|
||
|
strncpy(username, mb->user, NETMAXUSER);
|
||
|
if(tmp)
|
||
|
{
|
||
|
strncpy (password,tmp,MAILTMPLEN);
|
||
|
}
|
||
|
M_LOG("host: %s", mb->host);
|
||
|
M_LOG("orighost: %s", mb->orighost);
|
||
|
M_LOG("user: %s", mb->user);
|
||
|
M_LOG("mailbox: %s", mb->mailbox);
|
||
|
M_LOG("service: %s", mb->service);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
|
||
|
/* About to enter critical code
|
||
|
* Accepts: stream
|
||
|
*/
|
||
|
|
||
|
void mm_critical (MAILSTREAM *stream)
|
||
|
{
|
||
|
/* note in critical code */
|
||
|
}
|
||
|
|
||
|
|
||
|
/* About to exit critical code
|
||
|
* Accepts: stream
|
||
|
*/
|
||
|
|
||
|
void mm_nocritical (MAILSTREAM *stream)
|
||
|
{
|
||
|
/* note not in critical code */
|
||
|
}
|
||
|
|
||
|
|
||
|
/* Disk error found
|
||
|
* Accepts: stream
|
||
|
* system error code
|
||
|
* flag indicating that mailbox may be clobbered
|
||
|
* Returns: T if user wants to abort
|
||
|
*/
|
||
|
|
||
|
long mm_diskerror (MAILSTREAM *stream,long errcode,long serious)
|
||
|
{
|
||
|
return T;
|
||
|
}
|
||
|
|
||
|
|
||
|
/* Log a fatal error event
|
||
|
* Accepts: string to log
|
||
|
*/
|
||
|
|
||
|
void mm_fatal (char *string)
|
||
|
{
|
||
|
M_ERROR ("FATAL: %s",string);
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
static int l_mail_open(lua_State *L)
|
||
|
{
|
||
|
const char* mailbox = luaL_checkstring(L,1);
|
||
|
long flag = 0;
|
||
|
if( lua_isnumber(L,2))
|
||
|
{
|
||
|
flag = flag | (long)luaL_checknumber(L,2);
|
||
|
}
|
||
|
MAILSTREAM *stream = mail_open (NIL,(char*)mailbox,flag);
|
||
|
if(!stream)
|
||
|
{
|
||
|
lua_pushnil(L);
|
||
|
return 1;
|
||
|
}
|
||
|
//strncpy(stream->original_mailbox, stream->mailbox, strlen(stream->mailbox));
|
||
|
if(stream->original_mailbox)
|
||
|
{
|
||
|
free(stream->original_mailbox);
|
||
|
}
|
||
|
stream->original_mailbox = strdup(stream->mailbox);
|
||
|
M_LOG("mailbox: %s", stream->mailbox);
|
||
|
M_LOG("original_mailbox: %s", stream->original_mailbox);
|
||
|
lua_pushlightuserdata(L, stream);
|
||
|
lua_pushstring(L,stream->mailbox);
|
||
|
return 2;
|
||
|
}
|
||
|
|
||
|
static int l_mail_close(lua_State *L)
|
||
|
{
|
||
|
MAILSTREAM *stream = (MAILSTREAM *) lua_touserdata(L, 1);
|
||
|
if(!stream)
|
||
|
{
|
||
|
lua_pushboolean(L,0);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
(void) mail_close(stream);
|
||
|
lua_pushboolean(L,1);
|
||
|
}
|
||
|
return 1;
|
||
|
}
|
||
|
|
||
|
static int l_get_mailboxes(lua_State *L)
|
||
|
{
|
||
|
MAILSTREAM *stream = (MAILSTREAM *) lua_touserdata(L, 1);
|
||
|
const char* reference = luaL_checkstring(L,2);
|
||
|
const char* pattern = luaL_checkstring(L,3);
|
||
|
if(!stream)
|
||
|
{
|
||
|
lua_pushboolean(L,0);
|
||
|
return 1;
|
||
|
}
|
||
|
stream->sparep = (void*)L;
|
||
|
lua_newtable(L);
|
||
|
mail_list(stream,(char*)reference, (char*)pattern);
|
||
|
return 1;
|
||
|
}
|
||
|
|
||
|
static int l_mail_ping(lua_State *L)
|
||
|
{
|
||
|
MAILSTREAM *stream = (MAILSTREAM *) lua_touserdata(L, 1);
|
||
|
int new_mail = 0;
|
||
|
stream->sparep = (void*)&new_mail;
|
||
|
if(!stream || mail_ping(stream) == NIL)
|
||
|
{
|
||
|
lua_pushboolean(L,0);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
lua_pushboolean(L,1);
|
||
|
}
|
||
|
lua_pushnumber(L, new_mail);
|
||
|
return 2;
|
||
|
}
|
||
|
|
||
|
static int l_mail_check(lua_State *L)
|
||
|
{
|
||
|
MAILSTREAM *stream = (MAILSTREAM *) lua_touserdata(L, 1);
|
||
|
if(!stream)
|
||
|
{
|
||
|
return 0;
|
||
|
}
|
||
|
mail_check(stream);
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
static int l_reopen(lua_State *L)
|
||
|
{
|
||
|
MAILSTREAM *stream = (MAILSTREAM *) lua_touserdata(L, 1);
|
||
|
const char* mailbox = luaL_checkstring(L,2);
|
||
|
long flag = 0;
|
||
|
if( lua_isnumber(L,3))
|
||
|
{
|
||
|
flag = flag | (long)luaL_checknumber(L,3);
|
||
|
}
|
||
|
if(!stream)
|
||
|
{
|
||
|
lua_pushboolean(L,0);
|
||
|
return 1;
|
||
|
}
|
||
|
stream = mail_open (stream,(char*)mailbox,flag);
|
||
|
if(!stream)
|
||
|
{
|
||
|
lua_pushboolean(L,0);
|
||
|
return 1;
|
||
|
}
|
||
|
if(stream->original_mailbox)
|
||
|
{
|
||
|
free(stream->original_mailbox);
|
||
|
}
|
||
|
stream->original_mailbox = strdup(stream->mailbox);
|
||
|
M_LOG("mailbox: %s", stream->mailbox);
|
||
|
M_LOG("original_mailbox: %s", stream->original_mailbox);
|
||
|
lua_pushboolean(L,1);
|
||
|
lua_pushstring(L,stream->mailbox);
|
||
|
return 2;
|
||
|
}
|
||
|
|
||
|
|
||
|
static const struct luaL_Reg _lib [] = {
|
||
|
{"open", l_mail_open},
|
||
|
{"close", l_mail_close},
|
||
|
{"get_mail_boxes", l_get_mailboxes},
|
||
|
{"reopen", l_reopen},
|
||
|
{"ping", l_mail_ping},
|
||
|
{"check", l_mail_check},
|
||
|
{NULL,NULL}
|
||
|
};
|
||
|
|
||
|
int luaopen_limap(lua_State *L)
|
||
|
{
|
||
|
#include "linkage.c"
|
||
|
luaL_newlib(L, _lib);
|
||
|
return 1;
|
||
|
}
|