Created
December 20, 2012 13:24
-
-
Save mrvdb/4345314 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Index: src/compose.c | |
=================================================================== | |
RCS file: /home/claws-mail/claws/src/compose.c,v | |
retrieving revision 1.382.2.560 | |
diff -u -r1.382.2.560 compose.c | |
--- src/compose.c 20 Sep 2010 14:05:40 -0000 1.382.2.560 | |
+++ src/compose.c 19 Nov 2010 21:34:00 -0000 | |
@@ -5034,6 +5034,16 @@ | |
inc_unlock(); | |
toolbar_main_set_sensitive(mainwin); | |
main_window_set_menu_sensitive(mainwin); | |
+ /* | |
+ * IMAP IDLE loose ability to receive status messages from server | |
+ * therefore we do a folderview_check_new if folder is an IMAP | |
+ * folder and IMAP IDLE is active since calling folderview_check_new | |
+ * reenables the ability to receive status messages from server again | |
+ */ | |
+ if (FOLDER_TYPE(folder->folder) == F_IMAP && | |
+ folder->folder->account->use_imap_idle) | |
+ folderview_check_new(folder->folder); | |
+ | |
return 0; | |
bail: | |
Index: src/folder.c | |
=================================================================== | |
RCS file: /home/claws-mail/claws/src/folder.c,v | |
retrieving revision 1.213.2.197 | |
diff -u -r1.213.2.197 folder.c | |
--- src/folder.c 3 Oct 2010 11:46:24 -0000 1.213.2.197 | |
+++ src/folder.c 19 Nov 2010 21:34:00 -0000 | |
@@ -205,6 +205,12 @@ | |
folder->draft = NULL; | |
folder->queue = NULL; | |
folder->trash = NULL; | |
+ /* imap idle */ | |
+ folder->idle_active = FALSE; | |
+ folder->cb_active = FALSE; | |
+ folder->ioc = NULL; | |
+ folder->ioc_id = 0; | |
+ folder->timer_id = 0; | |
} | |
static void reset_parent_type(FolderItem *item, gpointer data) { | |
Index: src/folder.h | |
=================================================================== | |
RCS file: /home/claws-mail/claws/src/folder.h,v | |
retrieving revision 1.87.2.62 | |
diff -u -r1.87.2.62 folder.h | |
--- src/folder.h 3 Oct 2010 11:46:24 -0000 1.87.2.62 | |
+++ src/folder.h 19 Nov 2010 21:34:01 -0000 | |
@@ -158,6 +158,13 @@ | |
gpointer data; | |
GHashTable *newsart; | |
+ | |
+ /* imap idle */ | |
+ gboolean idle_active; | |
+ gboolean cb_active; | |
+ GIOChannel* ioc; | |
+ guint ioc_id; | |
+ guint timer_id; | |
}; | |
struct _FolderClass | |
Index: src/imap.c | |
=================================================================== | |
RCS file: /home/claws-mail/claws/src/imap.c,v | |
retrieving revision 1.179.2.252 | |
diff -u -r1.179.2.252 imap.c | |
--- src/imap.c 3 Oct 2010 11:46:24 -0000 1.179.2.252 | |
+++ src/imap.c 19 Nov 2010 21:34:01 -0000 | |
@@ -5888,3 +5888,17 @@ | |
*dst = '\0'; | |
return res; | |
} | |
+ | |
+gboolean imap_idle_cb(Folder* folder) | |
+{ | |
+ guint new_msgs = 0; | |
+ | |
+ g_return_val_if_fail(folder != NULL, FALSE); | |
+ | |
+ debug_print("%s: Updating folder message cache\n", folder->name); | |
+ | |
+ new_msgs = folderview_check_new(folder); | |
+ debug_print("%s: RECENT [%d]\n", folder->name, new_msgs); | |
+ | |
+ return TRUE; | |
+} | |
Index: src/imap.h | |
=================================================================== | |
RCS file: /home/claws-mail/claws/src/imap.h,v | |
retrieving revision 1.34.2.22 | |
diff -u -r1.34.2.22 imap.h | |
--- src/imap.h 20 Feb 2010 18:16:44 -0000 1.34.2.22 | |
+++ src/imap.h 19 Nov 2010 21:34:01 -0000 | |
@@ -47,4 +47,6 @@ | |
char* imap_modified_utf7_to_utf8(const char *mbox, gboolean change_spaces); | |
char* imap_utf8_to_modified_utf7(const char *src, gboolean change_spaces); | |
+gboolean imap_idle_cb(Folder* folder); | |
+ | |
#endif /* __IMAP_H__ */ | |
Index: src/prefs_account.c | |
=================================================================== | |
RCS file: /home/claws-mail/claws/src/prefs_account.c,v | |
retrieving revision 1.105.2.161 | |
diff -u -r1.105.2.161 prefs_account.c | |
--- src/prefs_account.c 30 Sep 2010 07:27:00 -0000 1.105.2.161 | |
+++ src/prefs_account.c 19 Nov 2010 21:34:01 -0000 | |
@@ -154,6 +154,7 @@ | |
GtkWidget *maxarticle_label; | |
GtkWidget *maxarticle_spinbtn; | |
GtkObject *maxarticle_spinbtn_adj; | |
+ GtkWidget *imap_idle_checkbtn; | |
} ReceivePage; | |
typedef struct SendPage | |
@@ -496,6 +497,10 @@ | |
&receive_page.imap_use_trash_checkbtn, | |
prefs_set_data_from_toggle, prefs_set_toggle}, | |
+ {"use_imap_idle", "TRUE", &tmp_ac_prefs.use_imap_idle, P_BOOL, | |
+ &receive_page.imap_idle_checkbtn, | |
+ prefs_set_data_from_toggle, prefs_set_toggle}, | |
+ | |
{NULL, NULL, NULL, P_OTHER, NULL, NULL, NULL} | |
}; | |
@@ -1361,6 +1366,7 @@ | |
GtkWidget *local_inbox_label; | |
GtkWidget *local_inbox_entry; | |
GtkWidget *local_inbox_btn; | |
+ GtkWidget *imap_idle_checkbtn; | |
GtkWidget *optmenu; | |
GtkListStore *menu; | |
@@ -1583,6 +1589,17 @@ | |
CLAWS_SET_TIP(imap_use_trash_checkbtn, | |
_("Moves deleted mails to trash instead of using the \\Deleted flag without expunging.")); | |
+ hbox1 = gtk_hbox_new (FALSE, 8); | |
+ gtk_widget_show (hbox1); | |
+ gtk_box_pack_start (GTK_BOX (vbox2), hbox1, FALSE, FALSE, 4); | |
+ | |
+ PACK_CHECK_BUTTON | |
+ (hbox1, imap_idle_checkbtn, (_("Use IMAP IDLE (Push Mail)"))); | |
+ CLAWS_SET_TIP(imap_idle_checkbtn, | |
+ _("If the server supports IMAP IDLE use this instead of polling the server. " | |
+ "A timer will periodically renew the connection to avoid the server closing down " | |
+ "in case of no activity.")); | |
+ | |
PACK_CHECK_BUTTON (vbox1, filter_on_recv_checkbtn, | |
_("Filter messages on receiving")); | |
@@ -1623,7 +1640,8 @@ | |
page->local_inbox_entry = local_inbox_entry; | |
page->local_inbox_btn = local_inbox_btn; | |
- page->recvatgetall_checkbtn = recvatgetall_checkbtn; | |
+ page->recvatgetall_checkbtn = recvatgetall_checkbtn; | |
+ page->imap_idle_checkbtn = imap_idle_checkbtn; | |
page->frame_maxarticle = frame2; | |
page->maxarticle_spinbtn = maxarticle_spinbtn; | |
@@ -4148,6 +4166,7 @@ | |
gtk_widget_hide(receive_page.subsonly_checkbtn); | |
gtk_widget_hide(receive_page.low_bandwidth_checkbtn); | |
gtk_widget_hide(receive_page.imap_use_trash_checkbtn); | |
+ gtk_widget_hide(receive_page.imap_idle_checkbtn); | |
break; | |
case A_LOCAL: | |
gtk_widget_show(send_page.msgid_checkbtn); | |
@@ -4243,6 +4262,7 @@ | |
gtk_widget_hide(receive_page.subsonly_checkbtn); | |
gtk_widget_hide(receive_page.low_bandwidth_checkbtn); | |
gtk_widget_hide(receive_page.imap_use_trash_checkbtn); | |
+ gtk_widget_hide(receive_page.imap_idle_checkbtn); | |
break; | |
case A_IMAP4: | |
#ifndef HAVE_LIBETPAN | |
@@ -4306,6 +4326,7 @@ | |
prefs_account_filter_on_recv_toggled | |
(GTK_TOGGLE_BUTTON(receive_page.filter_on_recv_checkbtn), NULL); | |
gtk_widget_set_sensitive(receive_page.recvatgetall_checkbtn, TRUE); | |
+ gtk_widget_set_sensitive(receive_page.imap_idle_checkbtn, TRUE); | |
gtk_widget_set_sensitive(basic_page.smtpserv_entry, TRUE); | |
gtk_widget_set_sensitive(basic_page.smtpserv_label, TRUE); | |
@@ -4347,6 +4368,7 @@ | |
gtk_widget_show(receive_page.subsonly_checkbtn); | |
gtk_widget_show(receive_page.low_bandwidth_checkbtn); | |
gtk_widget_show(receive_page.imap_use_trash_checkbtn); | |
+ gtk_widget_show(receive_page.imap_idle_checkbtn); | |
break; | |
case A_NONE: | |
gtk_widget_show(send_page.msgid_checkbtn); | |
@@ -4440,6 +4462,7 @@ | |
gtk_widget_hide(receive_page.subsonly_checkbtn); | |
gtk_widget_hide(receive_page.low_bandwidth_checkbtn); | |
gtk_widget_hide(receive_page.imap_use_trash_checkbtn); | |
+ gtk_widget_hide(receive_page.imap_idle_checkbtn); | |
break; | |
case A_POP3: | |
default: | |
@@ -4539,6 +4562,7 @@ | |
gtk_widget_hide(receive_page.subsonly_checkbtn); | |
gtk_widget_hide(receive_page.low_bandwidth_checkbtn); | |
gtk_widget_hide(receive_page.imap_use_trash_checkbtn); | |
+ gtk_widget_hide(receive_page.imap_idle_checkbtn); | |
break; | |
} | |
Index: src/prefs_account.h | |
=================================================================== | |
RCS file: /home/claws-mail/claws/src/prefs_account.h,v | |
retrieving revision 1.49.2.44 | |
diff -u -r1.49.2.44 prefs_account.h | |
--- src/prefs_account.h 12 Jun 2009 10:02:10 -0000 1.49.2.44 | |
+++ src/prefs_account.h 19 Nov 2010 21:34:01 -0000 | |
@@ -86,7 +86,7 @@ | |
gchar *in_ssl_client_cert_pass; | |
gboolean use_nonblocking_ssl; | |
- | |
+ | |
/* Receive */ | |
gboolean use_apop_auth; | |
gboolean rmmail; | |
@@ -104,6 +104,8 @@ | |
gint imap_auth_type; | |
+ gboolean use_imap_idle; | |
+ | |
/* Send */ | |
gboolean gen_msgid; | |
gboolean add_customhdr; | |
Index: src/summaryview.c | |
=================================================================== | |
RCS file: /home/claws-mail/claws/src/summaryview.c,v | |
retrieving revision 1.395.2.425 | |
diff -u -r1.395.2.425 summaryview.c | |
--- src/summaryview.c 2 Oct 2010 15:02:52 -0000 1.395.2.425 | |
+++ src/summaryview.c 19 Nov 2010 21:34:02 -0000 | |
@@ -4300,6 +4300,15 @@ | |
summary_delete(summaryview); | |
else | |
summary_move_selected_to(summaryview, to_folder); | |
+ /* | |
+ * IMAP IDLE loose ability to receive status messages from server | |
+ * therefore we do a folderview_check_new if folder is an IMAP | |
+ * folder and IMAP IDLE is active since calling folderview_check_new | |
+ * reenables the ability to receive status messages from server again | |
+ */ | |
+ if (FOLDER_TYPE(summaryview->folder_item->folder) == F_IMAP && | |
+ summaryview->folder_item->folder->account->use_imap_idle) | |
+ folderview_check_new(summaryview->folder_item->folder); | |
} | |
Index: src/etpan/imap-thread.c | |
=================================================================== | |
RCS file: /home/claws-mail/claws/src/etpan/Attic/imap-thread.c,v | |
retrieving revision 1.1.4.112 | |
diff -u -r1.1.4.112 imap-thread.c | |
--- src/etpan/imap-thread.c 2 Oct 2010 15:02:53 -0000 1.1.4.112 | |
+++ src/etpan/imap-thread.c 19 Nov 2010 21:34:02 -0000 | |
@@ -35,6 +35,7 @@ | |
#include <sys/mman.h> | |
#include <sys/wait.h> | |
#endif | |
+#include <glib.h> | |
#include <gtk/gtk.h> | |
#include <log.h> | |
#include "etpan-thread-manager.h" | |
@@ -44,8 +45,13 @@ | |
#include "ssl_certificate.h" | |
#include "socket.h" | |
#include "remotefolder.h" | |
+#include "imap.h" | |
#define DISABLE_LOG_DURING_LOGIN | |
+#define INTERVAL 120 /* interval in seconds between IMAP IDLE renewal */ | |
+ | |
+static void imap_threaded_idle_disable(Folder* folder); | |
+static void imap_threaded_idle_enable(Folder* folder); | |
static struct etpan_thread_manager * thread_manager = NULL; | |
static chash * courier_workaround_hash = NULL; | |
@@ -59,6 +65,9 @@ | |
chashdatum key; | |
chashdatum value; | |
+ /* Terminate IMAP IDLE */ | |
+ imap_threaded_idle_disable(folder); | |
+ | |
key.data = &folder; | |
key.len = sizeof(folder); | |
value.data = imap; | |
@@ -385,9 +394,231 @@ | |
imap = value.data; | |
debug_print("found imap %p\n", imap); | |
+ | |
return imap; | |
} | |
+/* to be removed when Hoa releases the new version of libetpan */ | |
+static long | |
+get_idle_delay(mailimap * session) | |
+{ | |
+ time_t current_time; | |
+ time_t next_date; | |
+ | |
+ current_time = time(NULL); | |
+ next_date = session->imap_idle_timestamp + session->imap_idle_maxdelay; | |
+ | |
+ if (current_time >= next_date) | |
+ return 0; | |
+ | |
+ return next_date - current_time; | |
+} | |
+ | |
+static void imap_threaded_idle_destroy_cb(gpointer data) | |
+{ | |
+ Folder* folder = (Folder *) data; | |
+ mailimap* imap; | |
+ | |
+ g_return_if_fail(folder != NULL); | |
+ | |
+ debug_print("%s: Calling mailimap_idle_done\n", folder->name); | |
+ | |
+ imap = get_imap(folder); | |
+ g_return_if_fail(imap != NULL); | |
+ | |
+ if (folder->idle_active && ! folder->cb_active) { | |
+ debug_print("%s: mailimap_idle_done [%p]\n", folder->name, imap); | |
+ mailimap_idle_done(imap); | |
+ folder->idle_active = FALSE; | |
+ } | |
+ folder->cb_active = FALSE; | |
+} | |
+ | |
+static gboolean imap_threaded_idle_cb(GIOChannel* gio, | |
+ GIOCondition condition, | |
+ gpointer data) | |
+{ | |
+ GIOStatus ret; | |
+ GError* err = NULL; | |
+ gchar* msg = NULL; | |
+ gsize len; | |
+ gboolean keep_going = FALSE; | |
+ | |
+ Folder* folder = (Folder *) data; | |
+ g_return_val_if_fail(folder != NULL, FALSE); | |
+ | |
+ if (condition & G_IO_HUP || condition & G_IO_ERR || condition & G_IO_NVAL) { | |
+ debug_print("%s: Error in channel\n", folder->name); | |
+ return FALSE; | |
+ } | |
+ | |
+ mailimap* imap = get_imap(folder); | |
+ g_return_val_if_fail(imap != NULL, FALSE); | |
+ | |
+ ret = g_io_channel_read_line(gio, &msg, &len, NULL, &err); | |
+ if (ret == G_IO_STATUS_ERROR) { | |
+ debug_print("%s -> Error reading: %s\n", folder->name, err->message); | |
+ g_error_free(err); | |
+ err = NULL; | |
+ keep_going = FALSE; | |
+ } | |
+ else if (ret == G_IO_STATUS_EOF) { | |
+ debug_print("%s: EOF on channel detected\n", folder->name); | |
+ keep_going = FALSE; | |
+ } | |
+ else { | |
+ debug_print("%s: IMAP4< %s\n", folder->name, msg); | |
+ keep_going = imap_idle_cb(folder); | |
+ if (keep_going) | |
+ folder->cb_active = TRUE; | |
+ else | |
+ folder->cb_active = FALSE; | |
+ } | |
+ | |
+ debug_print("%s: Response: %s\n", folder->name, (keep_going) ? "TRUE" : "FALSE"); | |
+ return keep_going; | |
+} | |
+ | |
+static gboolean imap_threaded_handle_imap_idle(Folder* folder, mailimap* imap) | |
+{ | |
+ int result; | |
+ gboolean response = FALSE; | |
+ int sock; | |
+ long delay = 60L * IDLE_DELAY; | |
+ | |
+ g_return_val_if_fail(folder != NULL, FALSE); | |
+ | |
+ sock = mailimap_idle_get_fd(imap); | |
+ if (sock < 1) { | |
+ debug_print("%s: no socket\n", folder->name); | |
+ return FALSE; | |
+ } | |
+ | |
+ folder->ioc = g_io_channel_unix_new(sock); | |
+ if (folder->ioc) { | |
+ g_io_channel_set_encoding(folder->ioc, NULL, NULL); | |
+ g_io_channel_set_flags(folder->ioc, G_IO_FLAG_NONBLOCK, NULL); | |
+ g_io_channel_set_close_on_unref(folder->ioc, FALSE); | |
+ result = mailimap_idle(imap); | |
+ debug_print("%s->%s\n", folder->name, imap->imap_response); | |
+ if (result != MAILIMAP_NO_ERROR) { | |
+ if (imap->imap_response) { | |
+ debug_print("%s->%s\n", folder->name, imap->imap_response); | |
+ } | |
+ if (folder->ioc->ref_count > 1) | |
+ g_io_channel_unref(folder->ioc); | |
+ response = FALSE; | |
+ debug_print("%s: Switching to IDLE failed\n", folder->name); | |
+ } | |
+ else { | |
+ mailimap_idle_set_delay(imap, delay); | |
+ folder->ioc_id = g_io_add_watch_full(folder->ioc, G_PRIORITY_LOW, | |
+ G_IO_IN | G_IO_HUP, imap_threaded_idle_cb, folder, | |
+ imap_threaded_idle_destroy_cb); | |
+ response = TRUE; | |
+ } | |
+ g_io_channel_unref(folder->ioc); | |
+ } | |
+ debug_print("%s: Response: %s\n", folder->name, (response) ? "TRUE" : "FALSE"); | |
+ return response; | |
+} | |
+ | |
+static gboolean imap_threaded_idle_update_status(gpointer data) | |
+{ | |
+ Folder* folder = (Folder *) data; | |
+ g_return_val_if_fail(folder != NULL, FALSE); | |
+ | |
+ mailimap* imap = get_imap(folder); | |
+ g_return_val_if_fail(imap != NULL, FALSE); | |
+ | |
+ debug_print("Update status for IMAP IDLE connections\n"); | |
+ /* Is it time to refresh IDLE */ | |
+ if (get_idle_delay(imap) + 10 < INTERVAL) { | |
+ debug_print("%s: Refreshing IDLE [%p]\n", folder->name, imap); | |
+ mailimap_idle_done(imap); | |
+ mailimap_idle(imap); | |
+ } | |
+ | |
+ return TRUE; | |
+} | |
+ | |
+static void imap_threaded_idle_disable(Folder* folder) | |
+{ | |
+ mailimap* imap; | |
+ | |
+ g_return_if_fail(folder != NULL); | |
+ | |
+ if ((! folder->idle_active || folder->ioc_id == 0 ) && ! folder->ioc) | |
+ return; | |
+ | |
+ imap = get_imap(folder); | |
+ | |
+ if (! imap) | |
+ return; | |
+ | |
+ debug_print("%s: Disable IMAP IDLE\n", folder->name); | |
+ | |
+ if (folder->ioc_id > 0 ) { | |
+ debug_print("%s: Calling g_source_remove: %d\n", folder->name, folder->ioc_id); | |
+ g_source_remove(folder->ioc_id); | |
+ folder->cb_active = FALSE; | |
+ folder->ioc_id = 0; | |
+ } | |
+ folder->idle_active = FALSE; | |
+ if (folder->timer_id > 0) { | |
+ debug_print("%s: Destroying timer\n", folder->name); | |
+ g_source_remove(folder->timer_id); | |
+ folder->timer_id = 0; | |
+ } | |
+} | |
+ | |
+static void imap_threaded_idle_enable(Folder* folder) | |
+{ | |
+ mailimap * imap; | |
+ | |
+ g_return_if_fail(folder != NULL); | |
+ | |
+ if (folder->idle_active) { | |
+ g_warning("%s: idle already active!!!", folder->name); | |
+ return; | |
+ } | |
+ | |
+ imap = get_imap(folder); | |
+ | |
+ if (! imap) | |
+ return; | |
+ | |
+ if (! mailimap_has_idle(imap) || ! folder->account->use_imap_idle) | |
+ return; | |
+ | |
+ /* IDLE only allowed while in SELECT or LOGIN state */ | |
+ if (imap->imap_state < MAILIMAP_STATE_AUTHENTICATED || | |
+ imap->imap_state > MAILIMAP_STATE_SELECTED) | |
+ return; | |
+ | |
+ debug_print("%s: Enable IMAP IDLE\n", folder->name); | |
+ | |
+ gboolean r = imap_threaded_handle_imap_idle(folder, imap); | |
+ if (r) { | |
+ folder->idle_active = TRUE; | |
+ } | |
+ else { | |
+ debug_print("%s: Enable IMAP IDLE failed\n", folder->name); | |
+ folder->idle_active = FALSE; | |
+ folder->ioc_id = 0; | |
+ } | |
+ | |
+ if (folder->idle_active) { | |
+#if GLIB_CHECK_VERSION(2,14,0) | |
+ folder->timer_id = g_timeout_add_seconds( | |
+ INTERVAL, imap_threaded_idle_update_status, folder); | |
+#else | |
+ folder->timer_id = g_timeout_add( | |
+ INTERVAL * 1000, imap_threaded_idle_update_status, folder); | |
+#endif | |
+ } | |
+} | |
+ | |
static gboolean cb_show_error(gpointer data) | |
{ | |
mainwindow_show_error(); | |
@@ -418,6 +649,8 @@ | |
imap_folder_ref(folder); | |
+ imap_threaded_idle_disable(folder); | |
+ | |
op = etpan_thread_op_new(); | |
op->imap = get_imap(folder); | |
@@ -441,6 +674,8 @@ | |
etpan_thread_op_free(op); | |
+ imap_threaded_idle_enable(folder); | |
+ | |
imap_folder_unref(folder); | |
} | |
@@ -681,6 +916,7 @@ | |
if (certificate) | |
free(certificate); | |
} | |
+ | |
debug_print("connect %d with imap %p\n", result.error, imap); | |
return result.error; | |
@@ -3387,7 +3623,9 @@ | |
void imap_threaded_cancel(Folder * folder) | |
{ | |
mailimap * imap; | |
- | |
+ | |
+ debug_print("%s: cancel called\n", folder->name); | |
+ | |
imap = get_imap(folder); | |
if (imap->imap_stream != NULL) | |
mailstream_cancel(imap->imap_stream); | |
Index: src/etpan/imap-thread.h | |
=================================================================== | |
RCS file: /home/claws-mail/claws/src/etpan/Attic/imap-thread.h,v | |
retrieving revision 1.1.4.27 | |
diff -u -r1.1.4.27 imap-thread.h | |
--- src/etpan/imap-thread.h 20 Feb 2010 18:16:45 -0000 1.1.4.27 | |
+++ src/etpan/imap-thread.h 19 Nov 2010 21:34:02 -0000 | |
@@ -25,6 +25,7 @@ | |
#include "folder.h" | |
#define IMAP_SET_MAX_COUNT 500 | |
+#define IDLE_DELAY 29 /* delay in minuts */ | |
typedef enum | |
{ |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment