2005-06-02 [colin] 1.9.11cvs32
authorColin Leroy <colin@colino.net>
Thu, 2 Jun 2005 03:06:27 +0000 (03:06 +0000)
committerColin Leroy <colin@colino.net>
Thu, 2 Jun 2005 03:06:27 +0000 (03:06 +0000)
* src/imap.c
Try to fix IMAP shortcomings:
o Multithread imap_open()
o allow offline-mode overriding instead of
  just returning NULL
* src/imap_gtk.c
* src/imap_gtk.h
Add a function to ask whether we want to
override offline-mode for 10 minutes (one-shot
asking was painful)
* src/procheader.c
Fix segfault when imap parser isn't happy about
a missing {

ChangeLog-gtk2.claws
PATCHSETS
configure.ac
src/imap.c
src/imap_gtk.c
src/imap_gtk.h
src/procheader.c

index 2e02db9..cfec3f0 100644 (file)
@@ -1,3 +1,19 @@
+2005-06-02 [colin]     1.9.11cvs32
+
+       * src/imap.c
+               Try to fix IMAP shortcomings: 
+               o Multithread imap_open()
+               o allow offline-mode overriding instead of
+                 just returning NULL
+       * src/imap_gtk.c
+       * src/imap_gtk.h
+               Add a function to ask whether we want to
+               override offline-mode for 10 minutes (one-shot
+               asking was painful)
+       * src/procheader.c
+               Fix segfault when imap parser isn't happy about
+               a missing {
+
 2005-06-01 [colin]     1.9.11cvs31
 
        * src/addrharvest.c
index 6fa48eb..70310be 100644 (file)
--- a/PATCHSETS
+++ b/PATCHSETS
 ( cvs diff -u -r 1.49.2.43 -r 1.49.2.44 src/procmime.c;  ) > 1.9.11cvs29.patchset
 ( cvs diff -u -r 1.1.2.2 -r 1.1.2.3 po/fi.po;  cvs diff -u -r 1.49.2.44 -r 1.49.2.45 src/procmime.c;  ) > 1.9.11cvs30.patchset
 ( cvs diff -u -r 1.6.10.5 -r 1.6.10.6 src/addrharvest.c;  cvs diff -u -r 1.382.2.125 -r 1.382.2.126 src/compose.c;  cvs diff -u -r 1.28.2.4 -r 1.28.2.5 src/mbox.c;  cvs diff -u -r 1.3.2.3 -r 1.3.2.4 src/mbox.h;  cvs diff -u -r 1.79.2.10 -r 1.79.2.11 src/mh.c;  cvs diff -u -r 1.16.2.18 -r 1.16.2.19 src/msgcache.c;  cvs diff -u -r 1.1.2.2 -r 1.1.2.3 src/prefs_compose_writing.c;  cvs diff -u -r 1.1.2.1 -r 1.1.2.2 src/prefs_compose_writing.h;  cvs diff -u -r 1.1.2.1 -r 1.1.2.2 src/prefs_message.c;  cvs diff -u -r 1.1.2.1 -r 1.1.2.2 src/prefs_message.h;  cvs diff -u -r 1.1.2.1 -r 1.1.2.2 src/prefs_other.c;  cvs diff -u -r 1.1.2.1 -r 1.1.2.2 src/prefs_other.h;  cvs diff -u -r 1.1.2.2 -r 1.1.2.3 src/prefs_quote.c;  cvs diff -u -r 1.1.2.1 -r 1.1.2.2 src/prefs_quote.h;  cvs diff -u -r 1.1.2.1 -r 1.1.2.2 src/prefs_receive.c;  cvs diff -u -r 1.1.2.1 -r 1.1.2.2 src/prefs_receive.h;  cvs diff -u -r 1.1.2.1 -r 1.1.2.2 src/prefs_send.c;  cvs diff -u -r 1.1.2.1 -r 1.1.2.2 src/prefs_send.h;  cvs diff -u -r 1.1.2.3 -r 1.1.2.4 src/prefs_summaries.c;  cvs diff -u -r 1.1.2.1 -r 1.1.2.2 src/prefs_summaries.h;  cvs diff -u -r 1.17.2.11 -r 1.17.2.12 src/send_message.c;  cvs diff -u -r 1.5.2.6 -r 1.5.2.7 src/setup.c;  cvs diff -u -r 1.395.2.72 -r 1.395.2.73 src/summaryview.c;  cvs diff -u -r 1.13.2.2 -r 1.13.2.3 src/undo.c;  cvs diff -u -r 1.24.2.6 -r 1.24.2.7 src/common/Makefile.am;  cvs diff -u -r 1.10 -r 1.11 src/common/hooks.c;  cvs diff -u -r 1.5 -r 1.6 src/common/prefs.c;  cvs diff -u -r 1.2.4.7 -r 1.2.4.8 src/common/template.c;  diff -u /dev/null src/common/timing.h;  cvs diff -u -r 1.36.2.31 -r 1.36.2.32 src/common/utils.c;  cvs diff -u -r 1.5.2.12 -r 1.5.2.13 src/gtk/gtkutils.c;  cvs diff -u -r 1.2.2.7 -r 1.2.2.8 src/gtk/inputdialog.c;  cvs diff -u -r 1.5.2.14 -r 1.5.2.15 src/gtk/menu.c;  cvs diff -u -r 1.5.2.14 -r 1.5.2.15 src/gtk/pluginwindow.c;  cvs diff -u -r 1.12.2.19 -r 1.12.2.20 src/gtk/prefswindow.c;  cvs diff -u -r 1.1.2.7 -r 1.1.2.8 src/plugins/pgpmime/passphrase.c;  cvs diff -u -r 1.1.2.7 -r 1.1.2.8 src/plugins/pgpmime/prefs_gpg.c;  ) > 1.9.11cvs31.patchset
+( cvs diff -u -r 1.179.2.17 -r 1.179.2.18 src/imap.c;  cvs diff -u -r 1.1.2.7 -r 1.1.2.8 src/imap_gtk.c;  cvs diff -u -r 1.1.2.1 -r 1.1.2.2 src/imap_gtk.h;  cvs diff -u -r 1.47.2.19 -r 1.47.2.20 src/procheader.c;  ) > 1.9.11cvs32.patchset
index 2cc9d6f..805d256 100644 (file)
@@ -11,7 +11,7 @@ MINOR_VERSION=9
 MICRO_VERSION=11
 INTERFACE_AGE=0
 BINARY_AGE=0
-EXTRA_VERSION=31
+EXTRA_VERSION=32
 EXTRA_RELEASE=
 EXTRA_GTK2_VERSION=
 
index dcd06ce..cb560e4 100644 (file)
@@ -43,6 +43,7 @@
 #include "session.h"
 #include "procmsg.h"
 #include "imap.h"
+#include "imap_gtk.h"
 #include "socket.h"
 #include "ssl.h"
 #include "recv.h"
 #include "log.h"
 #include "remotefolder.h"
 #include "alertpanel.h"
+#include "sylpheed.h"
+#include "statusbar.h"
+#ifdef USE_PTHREAD
+#include <pthread.h>
+#endif
+
+#ifdef USE_PTHREAD
+typedef struct _thread_data {
+       gchar *server;
+       gushort port;
+       gboolean done;
+#ifdef USE_OPENSSL
+       SSLType ssl_type;
+#endif
+} thread_data;
+#endif
+
 
 typedef struct _IMAPFolder     IMAPFolder;
 typedef struct _IMAPSession    IMAPSession;
@@ -619,8 +637,8 @@ static IMAPSession *imap_session_get(Folder *folder)
        g_return_val_if_fail(FOLDER_CLASS(folder) == &imap_class, NULL);
        g_return_val_if_fail(folder->account != NULL, NULL);
        
-       if (prefs_common.work_offline)
-               return NULL;
+       if (prefs_common.work_offline && !imap_gtk_should_override())
+                       return NULL;
 
        /* Make sure we have a session */
        if (rfolder->session != NULL) {
@@ -674,6 +692,9 @@ static IMAPSession *imap_session_get(Folder *folder)
                                log_warning(_("IMAP4 connection to %s has been"
                                            " disconnected. Reconnecting...\n"),
                                            folder->account->recv_server);
+                               statusbar_print_all(_("IMAP4 connection to %s has been"
+                                           " disconnected. Reconnecting...\n"),
+                                           folder->account->recv_server);
                                session_destroy(SESSION(session));
                                /* Clear folders session to make imap_session_get create
                                   a new session, because of rfolder->session == NULL
@@ -681,6 +702,7 @@ static IMAPSession *imap_session_get(Folder *folder)
                                   endless loop */
                                rfolder->session = NULL;
                                session = imap_session_get(folder);
+                               statusbar_pop_all();
                        }
                }
        }
@@ -1951,15 +1973,41 @@ static SockInfo *imap_open_tunnel(const gchar *server,
 }
 
 
+#ifdef USE_PTHREAD
+void *imap_open_thread(void *data)
+{
+       SockInfo *sock = NULL;
+       thread_data *td = (thread_data *)data;
+       if ((sock = sock_connect(td->server, td->port)) == NULL) {
+               log_warning(_("Can't connect to IMAP4 server: %s:%d\n"),
+                           td->server, td->port);
+               td->done = TRUE;
+               return NULL;
+       }
+
 #if USE_OPENSSL
-static SockInfo *imap_open(const gchar *server, gushort port,
+       if (td->ssl_type == SSL_TUNNEL && !ssl_init_socket(sock)) {
+               log_warning(_("Can't establish IMAP4 session with: %s:%d\n"),
+                           td->server, td->port);
+               sock_close(sock);
+               sock = NULL;
+               td->done = TRUE;
+               return NULL;
+       }
+#endif
+       td->done = TRUE;
+       return sock;
+}
+#endif
+
+#if USE_OPENSSL
+static SockInfo *imap_open_blocking(const gchar *server, gushort port,
                           SSLType ssl_type)
 #else
-static SockInfo *imap_open(const gchar *server, gushort port)
+static SockInfo *imap_open_blocking(const gchar *server, gushort port)
 #endif
 {
        SockInfo *sock;
-
        if ((sock = sock_connect(server, port)) == NULL) {
                log_warning(_("Can't connect to IMAP4 server: %s:%d\n"),
                            server, port);
@@ -1971,12 +2019,69 @@ static SockInfo *imap_open(const gchar *server, gushort port)
                log_warning(_("Can't establish IMAP4 session with: %s:%d\n"),
                            server, port);
                sock_close(sock);
+               sock = NULL;
                return NULL;
        }
 #endif
        return sock;
 }
 
+#if USE_OPENSSL
+static SockInfo *imap_open(const gchar *server, gushort port,
+                          SSLType ssl_type)
+#else
+static SockInfo *imap_open(const gchar *server, gushort port)
+#endif
+{
+#if (defined USE_PTHREAD && defined __GLIBC__ && (__GLIBC__ > 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 3)))
+       /* non blocking stuff */
+       thread_data *td = g_new0(thread_data, 1);
+       pthread_t pt;
+       SockInfo *sock = NULL;
+       
+#if USE_OPENSSL
+       td->ssl_type = ssl_type;
+#endif
+       td->server = g_strdup(server);
+       td->port = port;
+       td->done = FALSE;
+
+       statusbar_print_all(_("Connecting to IMAP4 server: %s..."), server);
+
+       debug_print("creating imap_open_thread...\n");
+       if (pthread_create(&pt, PTHREAD_CREATE_JOINABLE,
+                       imap_open_thread, td) != 0) {
+               statusbar_pop_all();
+#if USE_OPENSSL
+               return imap_open_blocking(server, port, ssl_type);
+#else
+               return imap_open_blocking(server, port);
+#endif
+       }
+       
+       debug_print("waiting for imap_open_thread...\n");
+       while(!td->done) {
+               /* don't let the interface freeze while waiting */
+               sylpheed_do_idle();
+       }
+
+       /* get the thread's return value and clean its resources */
+       pthread_join(pt, (void *)&sock);
+       g_free(td->server);
+       g_free(td);
+
+       debug_print("imap_open_thread returned %p\n", sock);
+       statusbar_pop_all();
+       return sock;
+#else
+#if USE_OPENSSL
+       return imap_open_blocking(server, port, ssl_type);
+#else
+       return imap_open_blocking(server, port);
+#endif
+#endif
+}
+
 #if USE_OPENSSL
 static SockInfo *imap_init_sock(SockInfo *sock, SSLType ssl_type)
 #else
index 9bc761c..00fdf7c 100644 (file)
@@ -27,6 +27,7 @@
 #include <glib/gi18n.h>
 
 #include <gtk/gtk.h>
+#include <time.h>
 
 #include "utils.h"
 #include "folder.h"
@@ -38,6 +39,7 @@
 #include "inputdialog.h"
 #include "imap.h"
 #include "inc.h"
+#include "prefs_common.h"
 
 static void new_folder_cb(FolderView *folderview, guint action, GtkWidget *widget);
 static void rename_folder_cb(FolderView *folderview, guint action, GtkWidget *widget);
@@ -371,16 +373,7 @@ static void download_cb(FolderView *folderview, guint action,
        item = gtk_ctree_node_get_row_data(ctree, folderview->selected);
        g_return_if_fail(item != NULL);
        g_return_if_fail(item->folder != NULL);
-#if 0
-       if (!prefs_common.online_mode) {
-               if (alertpanel(_("Offline"),
-                              _("You are offline. Go online?"),
-                              _("Yes"), _("No"), NULL) == G_ALERTDEFAULT)
-                       main_window_toggle_online(folderview->mainwin, TRUE);
-               else
-                       return;
-       }
-#endif
+
        main_window_cursor_wait(mainwin);
        inc_lock();
        main_window_lock(mainwin);
@@ -401,3 +394,20 @@ static void download_cb(FolderView *folderview, guint action,
        inc_unlock();
        main_window_cursor_normal(mainwin);
 }
+
+gboolean imap_gtk_should_override(void)
+{
+       static time_t overridden = NULL;
+       if (prefs_common.work_offline) {
+               if (time(NULL) - overridden < 600)
+                        return TRUE;
+               else if (alertpanel(_("Offline warning"), 
+                              _("You're working offline. Override during 10 minutes?"),
+                              _("Yes"), _("No"), NULL) != G_ALERTDEFAULT)
+                       return FALSE;
+
+               overridden = time(NULL);
+       }
+       return TRUE;
+       
+}
index 957714b..81b0030 100644 (file)
@@ -20,6 +20,9 @@
 #ifndef IMAP_GTK_H
 #define IMAP_GTK_H
 
+#include <glib.h>
+
 void imap_gtk_init(void);
+gboolean imap_gtk_should_override(void);
 
 #endif /* IMAP_GTK_H */
index 19883d2..de0008c 100644 (file)
@@ -76,7 +76,7 @@ static gint string_get_one_field(gchar *buf, size_t len, char **str,
 
 static char *string_getline(char *buf, size_t len, char **str)
 {
-       if (!**str)
+       if (!*str || !**str)
                return NULL;
 
        for (; **str && len > 1; --len)