From 7435dc6d1d37bf65e146b27d669f71b3fc5efa69 Mon Sep 17 00:00:00 2001 From: Lefteris Chatzimparmpas Date: Mon, 27 Feb 2012 01:17:02 +0100 Subject: [PATCH] Add support to recover when BYE is received Previously only network errors could cause a restoration of a session, but now a BYE response sent by the server can also trigger it. An option has been also added to control if and when the recover function will be called. --- doc/imapfilter_config.5 | 15 ++++++++++++++- src/imapfilter.h | 2 +- src/lua.c | 20 ++++++++++++++++++++ src/request.c | 30 +++++++++++++++++------------- 4 files changed, 52 insertions(+), 15 deletions(-) diff --git a/doc/imapfilter_config.5 b/doc/imapfilter_config.5 index 26055fb..00460db 100644 --- a/doc/imapfilter_config.5 +++ b/doc/imapfilter_config.5 @@ -1,4 +1,4 @@ -.Dd February 19, 2012 +.Dd February 26, 2012 .Dt IMAPFILTER_CONFIG 5 .Os .Sh NAME @@ -155,6 +155,19 @@ personal namespace mailboxes). This variable takes .Vt boolean as a value. Default is .Dq true . +.It Va recover +With this option it is possible to control the recovery functionality, which +restores a session (the connection to the server and state at the time), after +some unexpected event took place. Currently there are two type of events that +can cause a session to be terminated: network errors and the IMAP BYE response +that the server can send anytime. When this option is set to +.Dq all , +both types of events trigger the recovery function, when it is set to +.Dq errors , +only network errors trigger it, and when it is set to +.Dq none , +it is never triggered. Default is +.Dq all . .It Va starttls When this option is enabled and the server supports the IMAP STARTTLS extension, a TLS connection will be negotiated with the mail server in the diff --git a/src/imapfilter.h b/src/imapfilter.h index 9b964e7..18d3f45 100644 --- a/src/imapfilter.h +++ b/src/imapfilter.h @@ -117,7 +117,7 @@ const char *get_option_string(const char *opt); int set_table_boolean(const char *key, int value); int set_table_number(const char *key, lua_Number value); -int set_table_lightuserdata(const char *key, void *value); +int set_table_string(const char *key, const char *value); /* memory.c */ void *xmalloc(size_t size); diff --git a/src/lua.c b/src/lua.c index bbef83a..706f4fc 100644 --- a/src/lua.c +++ b/src/lua.c @@ -113,6 +113,7 @@ init_options(void) set_table_boolean("expunge", 1); set_table_number("keepalive", 29); set_table_boolean("namespace", 1); + set_table_string("recover", "all"); set_table_boolean("starttls", 1); set_table_boolean("subscribe", 0); set_table_number("timeout", 60); @@ -194,6 +195,9 @@ get_option_string(const char *opt) s = lua_tostring(lua, -1); lua_pop(lua, 2); + if (!s) + return ""; + return s; } @@ -226,3 +230,19 @@ set_table_number(const char *key, lua_Number value) return 0; } + +/* + * 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; +} + + diff --git a/src/request.c b/src/request.c index 6c6fc2c..288c4f7 100644 --- a/src/request.c +++ b/src/request.c @@ -21,19 +21,23 @@ int send_request(session *ssn, const char *fmt,...); int send_continuation(session *ssn, const char *data, size_t len); -#define TRY(F) \ - switch ((F)) { \ - case -1: \ - if (request_login(&ssn, NULL, NULL, NULL, NULL, NULL) != -1) \ - return STATUS_NONE; \ - else \ - return -1; \ - break; \ - case STATUS_BYE: \ - close_connection(ssn); \ - session_destroy(ssn); \ - return -1; \ - break; \ +#define TRY(F) \ + switch ((F)) { \ + case -1: \ + if ((!strcasecmp(get_option_string("recover"), "all") || \ + !strcasecmp(get_option_string("recover"), "errors")) && \ + request_login(&ssn, NULL, NULL, NULL, NULL, NULL) != -1) \ + return STATUS_NONE; \ + return -1; \ + case STATUS_BYE: \ + close_connection(ssn); \ + if (!strcasecmp(get_option_string("recover"), "all")) { \ + if (request_login(&ssn, NULL, NULL, NULL, NULL, \ + NULL) != -1) \ + return STATUS_NONE; \ + } else \ + session_destroy(ssn); \ + return -1; \ }