[balsa] NetworkManager-glib support.
- From: Pawel Salek <pawels src gnome org>
- To: svn-commits-list gnome org
- Cc:
- Subject: [balsa] NetworkManager-glib support.
- Date: Wed, 11 Nov 2009 12:08:06 +0000 (UTC)
commit 7c3d2338aaee4c64bc24c8a808ac6a16e7f3d1f1
Author: Pawel Salek <pawsa damage localdomain>
Date: Wed Nov 11 13:06:59 2009 +0100
NetworkManager-glib support.
* configure.in: add NetworkManager-glib support.
* libbalsa/imap-server.c: Disconnect quickly if asked to.
* libbalsa/imap/imap-commands.c: add private unlocked select command.
* libbalsa/imap/imap-handle.c: locking changes.
* libbalsa/imap/imap-handle.h: add ..force_disconnect() prototype.
* libbalsa/imap/imap_private.h: add select_unlocked() prototype.
* libbalsa/mailbox.c: stop-gap performance fix.
* libbalsa/mailbox_imap.[hc]: Add force_disconnect(),reconnect(),is_connected()
* src/main-window.c: listen to libnm events.
ChangeLog | 13 +++
configure.in | 179 ++++++++++++++++++++---------------------
libbalsa/imap-server.c | 4 +-
libbalsa/imap/imap-commands.c | 23 ++++--
libbalsa/imap/imap-handle.c | 55 +++++++------
libbalsa/imap/imap-handle.h | 2 +
libbalsa/imap/imap_private.h | 5 +-
libbalsa/mailbox.c | 10 +++
libbalsa/mailbox_imap.c | 39 +++++++++
libbalsa/mailbox_imap.h | 3 +
src/main-window.c | 110 +++++++++++++++++++++++++
11 files changed, 317 insertions(+), 126 deletions(-)
---
diff --git a/ChangeLog b/ChangeLog
index 5df0281..bb4bb5a 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,16 @@
+2009-11-11 Pawel Salek
+
+ * configure.in: add NetworkManager-glib support.
+ * libbalsa/imap-server.c: Disconnect quickly if asked to.
+ * libbalsa/imap/imap-commands.c: add private unlocked select command.
+ * libbalsa/imap/imap-handle.c: locking changes.
+ * libbalsa/imap/imap-handle.h: add ..force_disconnect() prototype.
+ * libbalsa/imap/imap_private.h: add select_unlocked() prototype.
+ * libbalsa/mailbox.c: stop-gap performance fix.
+ * libbalsa/mailbox_imap.[hc]: Add force_disconnect(), reconnect(),
+ is_connected().
+ * src/main-window.c: listen to libnm events.
+
2009-11-08 Peter Bloomfield
* libbalsa/imap/imap-tls.c (imap_check_server_identity): openssl
diff --git a/configure.in b/configure.in
index b2e7bed..b3a2f06 100644
--- a/configure.in
+++ b/configure.in
@@ -40,13 +40,6 @@ AC_DEFINE_UNQUOTED(BALSA_VERSION, "$BALSA_VERSION",
dnl #####################################################################
dnl 2. Options
dnl #####################################################################
-AC_ARG_WITH(iconv,
- AC_HELP_STRING([--with-iconv=DIR],
- [Where libiconv is installed]),
- [if test "$with_iconv" != yes -a "$with_iconv" != no ; then
- CPPFLAGS="-I${with_iconv}/include $CPPFLAGS"
- LDFLAGS="-liconv -L${with_iconv}/lib $LDFLAGS"
- fi])
AC_ARG_WITH([gnome],
AC_HELP_STRING([--with-gnome],
[Use GNOME libraries (default=yes)]),[
@@ -89,13 +82,6 @@ if test x"$use_threads" = xyes; then
AC_DEFINE(BALSA_USE_THREADS, 1,[Defined when balsa is to use threads.])
fi
-AC_ARG_WITH([ldap],
- AC_HELP_STRING([--with-ldap=DIR],
- [Use OpenLDAP if available (default=no)]),[
- with_ldap=$withval
-],[
- with_ldap=no
-])
AC_ARG_WITH([gpgme],
AC_HELP_STRING([--with-gpgme=gpgme-config],
@@ -110,69 +96,75 @@ AC_ARG_WITH([gpg-app],
[use PATH as GnuPG application (default=gpg2 if >= 2.0.4, otherwise gpg 1.x)]),
[ gpgapp=$withval ], [ gpgapp=no ])
-AC_ARG_WITH([webkit],
- AC_HELP_STRING([--with-webkit],
- [Use WebKit if available (default=no)]),[
- use_webkit=$withval
-],[
- use_webkit=no
-])
-AC_ARG_WITH([macosx-desktop],
- AC_HELP_STRING([--with-macosx-desktop],
- [Use Mac OS X Desktop Integration (default=no, extremely experimental)]),[
- use_igemacint=$withval
-],[
- use_igemacint=no
-])
+
+AC_ARG_WITH(canberra,
+ AC_HELP_STRING([--with-canberra],
+ [Use libcanberra-gtk2 for filter sounds (default=no)]),
+ [with_canberra=$withval],[with_canberra=no])
+
+AC_ARG_WITH(compface,
+ AC_HELP_STRING([--with-compface],
+ [Enable Compface (default=no)]),
+ [with_compface=$withval],[with_compface=no])
+
+AC_ARG_WITH(esmtp,
+ AC_HELP_STRING([--with-esmtp=DIR],
+ [Enable libESMTP (default=yes)]),
+ [ with_esmtp=$withval ],[ with_esmtp=yes ])
+
+AC_ARG_ENABLE([gregex],
+ AC_HELP_STRING([--enable-gregex],
+ [Use GRegex regular expressions if available (default=no)]),
+ [ check_gregex=$enableval],[ check_gregex=no ])
+
+AC_ARG_WITH(gss,
+ AC_HELP_STRING([--with-gss],
+ [Enable GSS (default=no)]),
+ [with_gss=$withval],[with_gss=no])
AC_ARG_WITH([gtkhtml],
- AC_HELP_STRING([--with-gtkhtml],
- [Preferred GtkHTML version, 2 or 3 (default=3)]),[
- use_gtkhtml=$withval
-],[
- use_gtkhtml=3
-])
+ AC_HELP_STRING([--with-gtkhtml],
+ [Preferred GtkHTML version, 2 or 3 (default=3)]),
+ [use_gtkhtml=$withval],[use_gtkhtml=3])
+
+AC_ARG_WITH([gtksourceview],
+ AC_HELP_STRING([--with-gtksourceview],
+ [Use GtkSourceView if available (default=no, specify version 1 or 2, yes=2)]),
+ [with_gtksourceview=$withval],[with_gtksourceview=no])
AC_ARG_WITH([gtkspell],
- AC_HELP_STRING([--with-gtkspell],
- [Use GtkSpell if available (default=no)]),[
- with_gtkspell=$withval
-],[
- with_gtkspell=no
-])
+ AC_HELP_STRING([--with-gtkspell],
+ [Use GtkSpell if available (default=no)]),
+ [with_gtkspell=$withval],[with_gtkspell=no])
-AC_ARG_WITH([libnotify],
- AC_HELP_STRING([--with-libnotify],
- [Use libnotify if available (default=yes)]),[
- with_libnotify=$withval
-],[
- with_libnotify=yes
-])
+AC_ARG_WITH(iconv,
+ AC_HELP_STRING([--with-iconv=DIR],
+ [Where libiconv is installed]),
+ [if test "$with_iconv" != yes -a "$with_iconv" != no ; then
+ CPPFLAGS="-I${with_iconv}/include $CPPFLAGS"
+ LDFLAGS="-liconv -L${with_iconv}/lib $LDFLAGS"
+ fi])
-AC_ARG_WITH([gtksourceview],
- AC_HELP_STRING([--with-gtksourceview],
- [Use GtkSourceView if available (default=no, specify version 1 or 2, yes=2)]),[
- with_gtksourceview=$withval
-],[
- with_gtksourceview=no
-])
+AC_ARG_WITH([ldap],
+ AC_HELP_STRING([--with-ldap=DIR],
+ [Use OpenLDAP if available (default=no)]),
+ [with_ldap=$withval],[with_ldap=no])
-AC_ARG_WITH([sqlite],
- AC_HELP_STRING([--with-sqlite=DIR],
- [Use SQLite for GPE address books (default=no)]),[
- with_sqlite=$withval
-],[
- with_sqlite=no
-])
+AC_ARG_WITH([libnotify],
+ AC_HELP_STRING([--with-libnotify],
+ [Use libnotify if available (default=yes)]),
+ [with_libnotify=$withval],[with_libnotify=yes])
-AC_ARG_WITH([rubrica],
- AC_HELP_STRING([--with-rubrica],
- [add Rubrica2 address book support (needs libxml2, default=no)]),[
- with_rubrica=$withval
-],[
- with_rubrica=no
-])
+AC_ARG_WITH([macosx-desktop],
+ AC_HELP_STRING([--with-macosx-desktop],
+ [Use Mac OS X Desktop Integration (default=no, extremely experimental)]),
+ [use_igemacint=$withval],[use_igemacint=no])
+
+AC_ARG_WITH(nm,
+ AC_HELP_STRING([--with-nm],
+ [Enable NetworkManager (default=yes)]),
+ [with_nm=$withval],[with_nm=yes])
AC_ARG_ENABLE([pcre],
AC_HELP_STRING([--enable-pcre],
@@ -180,47 +172,38 @@ AC_ARG_ENABLE([pcre],
[ check_pcre=$enableval],[ check_pcre=no ])
-AC_ARG_ENABLE([gregex],
- AC_HELP_STRING([--enable-gregex],
- [Use GRegex regular expressions if available (default=no)]),
- [ check_gregex=$enableval],[ check_gregex=no ])
-
+AC_ARG_WITH([rubrica],
+ AC_HELP_STRING([--with-rubrica],
+ [add Rubrica2 address book support (needs libxml2, default=no)]),
+ [with_rubrica=$withval],[with_rubrica=no])
-AC_ARG_WITH(esmtp,
- AC_HELP_STRING([--with-esmtp=DIR],
- [Enable libESMTP (default=yes)]),
- [ with_esmtp=$withval ],[ with_esmtp=yes ])
+AC_ARG_WITH([sqlite],
+ AC_HELP_STRING([--with-sqlite=DIR],
+ [Use SQLite for GPE address books (default=no)]),
+ [with_sqlite=$withval],[with_sqlite=no])
AC_ARG_WITH(ssl,
AC_HELP_STRING([--with-ssl],
[Enable SSL (default=no)]),
[ with_ssl=$withval ],[ with_ssl=no ])
-AC_ARG_WITH(gss,
- AC_HELP_STRING([--with-gss],
- [Enable GSS (default=no)]),
- [with_gss=$withval],[with_gss=no])
-
-AC_ARG_WITH(compface,
- AC_HELP_STRING([--with-compface],
- [Enable Compface (default=no)]),
- [with_compface=$withval],[with_compface=no])
-
AC_ARG_WITH(unique,
AC_HELP_STRING([--with-unique],
[Use libUnique instead of BonoboActivation (default=no)]),
[with_unique=$withval],[with_unique=no])
-AC_ARG_WITH(canberra,
- AC_HELP_STRING([--with-canberra],
- [Use libcanberra-gtk2 for filter sounds (default=no)]),
- [with_canberra=$withval],[with_canberra=no])
+AC_ARG_WITH([webkit],
+ AC_HELP_STRING([--with-webkit],
+ [Use WebKit if available (default=no)]),
+ [use_webkit=$withval],[use_webkit=no])
+
AC_ARG_ENABLE(more-warnings,
AC_HELP_STRING([--enable-more-warnings],
[Enable maximum compiler warnings (default=yes)]),
[set_more_warnings="$enableval"], [set_more_warnings=yes])
+
dnl ##########################################################################
dnl Enable touchscreen optimized UI?
dnl ##########################################################################
@@ -743,6 +726,19 @@ if test x$with_libnotify != xno; then
BALSA_AB_LIBS="$BALSA_AB_LIBS -lnotify"
fi
+# NetworkManager
+AC_MSG_CHECKING([NetworkManager-glib-devel])
+echo withnm "'$with_nm'"
+if test "$with_nm" != no ; then
+ PKG_CHECK_MODULES(LIBNM_GLIB, [ libnm_glib ])
+ AC_DEFINE(HAVE_LIBNM_GLIB,1,[ Defined if NetworkManager-glib-devel is found.])
+ CFLAGS="$CFLAGS $LIBNM_GLIB_CFLAGS"
+ LIBS="$LIBS $LIBNM_GLIB_LIBS"
+ AC_MSG_RESULT([yes])
+else
+ AC_MSG_RESULT([no])
+fi
+
# Compface configuration
#
AC_MSG_CHECKING([whether to build Compface support])
@@ -1010,6 +1006,7 @@ echo " Use LDAP: $with_ldap"
echo " Use GSS: $with_gss"
echo " Use SQLite: $with_sqlite"
echo " Use SSL: $with_ssl"
+echo " Use NetworkManager: $with_nm"
echo " Use GtkSpell: $with_gtkspell"
echo " Use Libnotify: $with_libnotify"
echo " Use GtkSourceView: $with_gtksourceview"
diff --git a/libbalsa/imap-server.c b/libbalsa/imap-server.c
index 4fc78e8..d43b954 100644
--- a/libbalsa/imap-server.c
+++ b/libbalsa/imap-server.c
@@ -362,6 +362,7 @@ lb_imap_server_info_new(LibBalsaServer *server)
static void
lb_imap_server_info_free(struct handle_info *info)
{
+ imap_handle_force_disconnect(info->handle);
g_object_unref(info->handle);
g_free(info);
}
@@ -862,7 +863,8 @@ libbalsa_imap_server_has_persistent_cache(LibBalsaImapServer *srv)
*
* Forces a logout on all connections, used when cleaning up.
**/
-void libbalsa_imap_server_force_disconnect(LibBalsaImapServer *imap_server)
+void
+libbalsa_imap_server_force_disconnect(LibBalsaImapServer *imap_server)
{
LOCK_SERVER(imap_server);
g_list_foreach(imap_server->used_handles,
diff --git a/libbalsa/imap/imap-commands.c b/libbalsa/imap/imap-commands.c
index 4712288..16591f6 100644
--- a/libbalsa/imap/imap-commands.c
+++ b/libbalsa/imap/imap-commands.c
@@ -181,19 +181,18 @@ imap_mbox_handle_noop(ImapMboxHandle *handle)
/* 6.3.1 SELECT Command
* readonly_mbox can be NULL. */
ImapResponse
-imap_mbox_select(ImapMboxHandle* handle, const char *mbox,
- gboolean *readonly_mbox)
+imap_mbox_select_unlocked(ImapMboxHandle* handle, const char *mbox,
+ gboolean *readonly_mbox)
{
gchar* cmd, *mbx7;
ImapResponse rc;
IMAP_REQUIRED_STATE3(handle, IMHS_CONNECTED, IMHS_AUTHENTICATED,
IMHS_SELECTED, IMR_BAD);
- HANDLE_LOCK(handle);
+
if (handle->state == IMHS_SELECTED && strcmp(handle->mbox, mbox) == 0) {
if(readonly_mbox)
*readonly_mbox = handle->readonly_mbox;
- HANDLE_UNLOCK(handle);
return IMR_OK;
}
imap_mbox_resize_cache(handle, 0);
@@ -219,10 +218,20 @@ imap_mbox_select(ImapMboxHandle* handle, const char *mbox,
mbox_view_dispose(&handle->mbox_view);
g_signal_emit_by_name(G_OBJECT(handle), "exists-notify");
}
- HANDLE_UNLOCK(handle);
+
return rc;
}
+ImapResponse
+imap_mbox_select(ImapMboxHandle* handle, const char *mbox,
+ gboolean *readonly_mbox)
+{
+ ImapResponse rc;
+ HANDLE_LOCK(handle);
+ rc = imap_mbox_select_unlocked(handle, mbox, readonly_mbox);
+ HANDLE_UNLOCK(handle);
+ return rc;
+}
/* 6.3.2 EXAMINE Command */
ImapResponse
@@ -390,11 +399,11 @@ enum_flag_to_str(ImapMsgFlags flg)
GString *flags_str = g_string_new("");
unsigned idx;
- for(idx=0; idx < ELEMENTS(msg_flags); idx++) {
+ for(idx=0; idx < ELEMENTS(imap_msg_flags); idx++) {
if((flg & (1<<idx)) == 0) continue;
if(*flags_str->str) g_string_append_c(flags_str, ' ');
g_string_append_c(flags_str, '\\');
- g_string_append(flags_str, msg_flags[idx]);
+ g_string_append(flags_str, imap_msg_flags[idx]);
}
return g_string_free(flags_str, FALSE);
}
diff --git a/libbalsa/imap/imap-handle.c b/libbalsa/imap/imap-handle.c
index 7f47277..c32c5d5 100644
--- a/libbalsa/imap/imap-handle.c
+++ b/libbalsa/imap/imap-handle.c
@@ -583,6 +583,8 @@ imap_mbox_handle_connect(ImapMboxHandle* ret, const char *host, int over_ssl)
ImapResult rc;
g_return_val_if_fail(imap_mbox_is_disconnected(ret), IMAP_CONNECT_FAILED);
+
+ HANDLE_LOCK(ret);
#if !defined(USE_TLS)
if(over_ssl) {
imap_mbox_handle_set_msg(ret,"SSL requested but SSL support not compiled");
@@ -599,6 +601,8 @@ imap_mbox_handle_connect(ImapMboxHandle* ret, const char *host, int over_ssl)
rc = imap_authenticate(ret);
+ HANDLE_UNLOCK(ret);
+
return rc;
}
@@ -627,25 +631,33 @@ imap_mbox_handle_reconnect(ImapMboxHandle* h, gboolean *readonly)
{
ImapResult rc;
+ HANDLE_LOCK(h);
- if( (rc=imap_mbox_connect(h)) != IMAP_SUCCESS)
- return rc;
-
- if( (rc = imap_authenticate(h)) != IMAP_SUCCESS)
- return rc;
-
- imap_mbox_resize_cache(h, 0); /* invalidate cache */
- mbox_view_dispose(&h->mbox_view); /* FIXME: recreate it here? */
+ if( (rc=imap_mbox_connect(h)) == IMAP_SUCCESS) {
+ if( (rc = imap_authenticate(h)) == IMAP_SUCCESS) {
+ imap_mbox_resize_cache(h, 0); /* invalidate cache */
+ mbox_view_dispose(&h->mbox_view); /* FIXME: recreate it here? */
- if(h->mbox) {
- switch(imap_mbox_select(h, h->mbox, readonly)) {
- case IMR_OK: rc = IMAP_SUCCESS; break;
- default: rc = IMAP_SELECT_FAILED; break;
+ if(h->mbox &&
+ imap_mbox_select_unlocked(h, h->mbox, readonly) != IMR_OK) {
+ rc = IMAP_SELECT_FAILED;
+ }
}
}
+ HANDLE_UNLOCK(h);
return rc;
}
+/** Drops the connection without waiting for response. This can be
+ called when eg a signal from NetworkManager arrives. */
+void
+imap_handle_force_disconnect(ImapMboxHandle *h)
+{
+ HANDLE_LOCK(h);
+ imap_handle_disconnect(h);
+ HANDLE_UNLOCK(h);
+}
+
ImapTlsMode
imap_handle_set_tls_mode(ImapMboxHandle* r, ImapTlsMode state)
{
@@ -656,7 +668,7 @@ imap_handle_set_tls_mode(ImapMboxHandle* r, ImapTlsMode state)
return res;
}
-const char* msg_flags[6] = {
+const char* imap_msg_flags[6] = {
"seen", "answered", "flagged", "deleted", "draft", "recent"
};
@@ -745,7 +757,6 @@ imap_mbox_connect(ImapMboxHandle* handle)
static const int SIO_BUFSZ=8192;
ImapResponse resp;
const char *service = "imap";
- HANDLE_LOCK(handle);
/* reset some handle status */
handle->op_cancelled = FALSE;
@@ -763,16 +774,13 @@ imap_mbox_connect(ImapMboxHandle* handle)
#endif
handle->sd = imap_socket_open(handle->host, service);
- if(handle->sd<0) {
- HANDLE_UNLOCK(handle);
+ if(handle->sd<0)
return IMAP_CONNECT_FAILED;
- }
/* Add buffering to the socket */
handle->sio = sio_attach(handle->sd, handle->sd, SIO_BUFSZ);
if (handle->sio == NULL) {
close(handle->sd);
- HANDLE_UNLOCK(handle);
return IMAP_NOMEM;
}
if(handle->timeout>0) {
@@ -784,7 +792,6 @@ imap_mbox_connect(ImapMboxHandle* handle)
SSL *ssl = imap_create_ssl();
if(!ssl) {
imap_mbox_handle_set_msg(handle,"SSL context could not be created");
- HANDLE_UNLOCK(handle);
return IMAP_UNSECURE;
}
if(imap_setup_ssl(handle->sio, handle->host, ssl,
@@ -793,7 +800,6 @@ imap_mbox_connect(ImapMboxHandle* handle)
else {
imap_mbox_handle_set_msg(handle,"SSL negotiation failed");
imap_handle_disconnect(handle);
- HANDLE_UNLOCK(handle);
return IMAP_UNSECURE;
}
}
@@ -806,7 +812,6 @@ imap_mbox_connect(ImapMboxHandle* handle)
g_message("imap_mbox_connect:unexpected initial response(%d):\n%s\n",
resp, handle->last_msg);
imap_handle_disconnect(handle);
- HANDLE_UNLOCK(handle);
return IMAP_PROTOCOL_ERROR;
}
handle->can_fetch_body =
@@ -818,7 +823,6 @@ imap_mbox_connect(ImapMboxHandle* handle)
imap_mbox_handle_can_do(handle, IMCAP_STARTTLS)) {
if( imap_handle_starttls(handle) != IMR_OK) {
imap_mbox_handle_set_msg(handle,"TLS negotiation failed");
- HANDLE_UNLOCK(handle);
return IMAP_UNSECURE; /* TLS negotiation error */
}
resp = IMR_OK; /* secured with TLS */
@@ -829,10 +833,9 @@ imap_mbox_connect(ImapMboxHandle* handle)
#endif
if(handle->tls_mode == IMAP_TLS_REQUIRED && resp != IMR_OK) {
imap_mbox_handle_set_msg(handle,"TLS required but not available");
- HANDLE_UNLOCK(handle);
return IMAP_UNSECURE;
}
- HANDLE_UNLOCK(handle);
+
return IMAP_SUCCESS;
}
@@ -2841,8 +2844,8 @@ ir_msg_att_flags(ImapMboxHandle *h, int c, unsigned seqno)
do {
char buf[LONG_STRING];
c = imap_get_flag(h->sio, buf, sizeof(buf));
- for(i=0; i<ELEMENTS(msg_flags); i++)
- if(buf[0] == '\\' && g_ascii_strcasecmp(msg_flags[i], buf+1) == 0) {
+ for(i=0; i<ELEMENTS(imap_msg_flags); i++)
+ if(buf[0] == '\\' && g_ascii_strcasecmp(imap_msg_flags[i], buf+1) == 0) {
msg->flags |= 1<<i;
break;
}
diff --git a/libbalsa/imap/imap-handle.h b/libbalsa/imap/imap-handle.h
index 3667597..0e84bb0 100644
--- a/libbalsa/imap/imap-handle.h
+++ b/libbalsa/imap/imap-handle.h
@@ -132,6 +132,8 @@ ImapResult imap_mbox_handle_connect(ImapMboxHandle* r, const char *hst,
int over_ssl);
ImapResult imap_mbox_handle_reconnect(ImapMboxHandle* r,
gboolean *readonly);
+void imap_handle_force_disconnect(ImapMboxHandle *h);
+
ImapTlsMode imap_handle_set_tls_mode(ImapMboxHandle *h, ImapTlsMode option);
/* int below is a boolean */
diff --git a/libbalsa/imap/imap_private.h b/libbalsa/imap/imap_private.h
index a0f5771..2e5f66b 100644
--- a/libbalsa/imap/imap_private.h
+++ b/libbalsa/imap/imap_private.h
@@ -166,7 +166,10 @@ struct _ImapMboxHandle {
#define EAT_LINE(h, c) while( (c=sio_getc(h->sio)) != -1 && c != '\n')
-extern const char* msg_flags[6];
+extern const char* imap_msg_flags[6];
+
+ImapResponse imap_mbox_select_unlocked(ImapMboxHandle* handle, const char *mbox,
+ gboolean *readonly_mbox);
void imap_mbox_resize_cache(ImapMboxHandle *h, unsigned new_size);
diff --git a/libbalsa/mailbox.c b/libbalsa/mailbox.c
index e37344a..18588b4 100644
--- a/libbalsa/mailbox.c
+++ b/libbalsa/mailbox.c
@@ -1622,6 +1622,16 @@ libbalsa_mailbox_msgno_filt_check(LibBalsaMailbox * mailbox, guint seqno,
libbalsa_mailbox_msgno_has_flags(mailbox, seqno, 0,
LIBBALSA_MESSAGE_FLAG_SELECTED)
: TRUE;
+#if 1
+ /* a hack. The whole filtering idea is bit silly since we
+ keep checking flags (or maybe more!) on all messages so
+ that the time spent on changing the selection grows
+ linearly with the mailbox size! */
+ if (LIBBALSA_IS_MAILBOX_IMAP(mailbox) &&
+ !libbalsa_mailbox_imap_is_connected
+ (LIBBALSA_MAILBOX_IMAP(mailbox)))
+ filt_out = FALSE;
+#endif
if (filt_out)
libbalsa_mailbox_msgno_filt_out(mailbox, seqno);
}
diff --git a/libbalsa/mailbox_imap.c b/libbalsa/mailbox_imap.c
index 70deeea..8ddc4d6 100644
--- a/libbalsa/mailbox_imap.c
+++ b/libbalsa/mailbox_imap.c
@@ -1653,6 +1653,45 @@ libbalsa_mailbox_imap_noop(LibBalsaMailboxImap* mimap)
;
}
+void
+libbalsa_mailbox_imap_force_disconnect(LibBalsaMailboxImap* mimap)
+{
+ g_return_if_fail(mimap != NULL);
+
+ if (mimap->handle) {/* we do not attempt to reconnect here */
+ printf("Disconnecting %s (%u)\n", LIBBALSA_MAILBOX(mimap)->name,
+ (unsigned)time(NULL));
+ imap_handle_force_disconnect(mimap->handle);
+ printf("Disconnected %s (%u)\n", LIBBALSA_MAILBOX(mimap)->name,
+ (unsigned)time(NULL));
+ }
+}
+
+void
+libbalsa_mailbox_imap_reconnect(LibBalsaMailboxImap* mimap)
+{
+ g_return_if_fail(mimap != NULL);
+
+ if (mimap->handle &&
+ imap_mbox_is_disconnected (mimap->handle)) {
+ printf("Reconnecting %s (%u)\n",
+ LIBBALSA_MAILBOX_REMOTE_SERVER(mimap)->host,
+ (unsigned)time(NULL));
+ if (imap_mbox_handle_reconnect
+ (mimap->handle, &(LIBBALSA_MAILBOX(mimap)->readonly))
+ == IMAP_SUCCESS)
+ printf("Reconnected %s (%u)\n",
+ LIBBALSA_MAILBOX_REMOTE_SERVER(mimap)->host,
+ (unsigned)time(NULL));
+ }
+}
+
+gboolean
+libbalsa_mailbox_imap_is_connected(LibBalsaMailboxImap* mimap)
+{
+ return mimap->handle && !imap_mbox_is_disconnected(mimap->handle);
+}
+
/* imap_close_all_connections:
close all connections to leave the place cleanly.
*/
diff --git a/libbalsa/mailbox_imap.h b/libbalsa/mailbox_imap.h
index 046c091..679f5f2 100644
--- a/libbalsa/mailbox_imap.h
+++ b/libbalsa/mailbox_imap.h
@@ -60,6 +60,9 @@ GHashTable * libbalsa_mailbox_imap_get_matchings(LibBalsaMailboxImap* mbox,
void libbalsa_mailbox_imap_noop(LibBalsaMailboxImap* mbox);
+void libbalsa_mailbox_imap_force_disconnect(LibBalsaMailboxImap* mimap);
+gboolean libbalsa_mailbox_imap_is_connected(LibBalsaMailboxImap* mimap);
+void libbalsa_mailbox_imap_reconnect(LibBalsaMailboxImap* mimap);
void libbalsa_imap_close_all_connections(void);
gboolean libbalsa_imap_new_subfolder(const gchar *parent, const gchar *folder,
diff --git a/src/main-window.c b/src/main-window.c
index e093a56..f5095e5 100644
--- a/src/main-window.c
+++ b/src/main-window.c
@@ -35,6 +35,7 @@
#include <string.h>
#include <gdk-pixbuf/gdk-pixbuf.h>
+#include "imap-server.h"
#include "libbalsa.h"
#include "misc.h"
#include "html.h"
@@ -45,6 +46,10 @@
# include "macosx-helpers.h"
#endif
+#if defined(HAVE_LIBNM_GLIB)
+#include <libnm_glib.h>
+#endif
+
#include "ab-window.h"
#include "balsa-app.h"
#include "balsa-icons.h"
@@ -115,6 +120,10 @@ static void bw_check_messages_thread(struct check_messages_thread_info
#endif
static void bw_display_new_mail_notification(int num_new, int has_new);
+#if defined(HAVE_LIBNM_GLIB)
+static void mw_change_connection_status(libnm_glib_ctx *ctx, gpointer data);
+#endif
+
static void balsa_window_class_init(BalsaWindowClass * klass);
static void balsa_window_init(BalsaWindow * window);
static void balsa_window_real_open_mbnode(BalsaWindow *window,
@@ -973,6 +982,19 @@ balsa_window_class_init(BalsaWindowClass * klass)
static void
balsa_window_init(BalsaWindow * window)
{
+#if defined(HAVE_LIBNM_GLIB)
+ libnm_glib_ctx *ctx;
+ guint id;
+
+ ctx = libnm_glib_init ();
+ if (!ctx) {
+ fprintf (stderr, "Could not initialize libnm.\n");
+ return;
+ }
+
+ id = libnm_glib_register_callback(ctx, mw_change_connection_status,
+ window, NULL);
+#endif /* LIBNM_GLIB */
}
static gboolean
@@ -3390,6 +3412,94 @@ bw_display_new_mail_notification(int num_new, int has_new)
g_free(msg);
}
+#if defined(HAVE_LIBNM_GLIB)
+/*Callback to create or disconnect an IMAP mbox. */
+static gboolean
+mw_mbox_change_connection_status(GtkTreeModel * model, GtkTreePath * path,
+ GtkTreeIter * iter, gboolean is_connected)
+{
+ BalsaMailboxNode *mbnode;
+ LibBalsaMailbox *mailbox;
+
+ gtk_tree_model_get(model, iter, 0, &mbnode, -1);
+ g_return_val_if_fail(mbnode, FALSE);
+
+ if ((mailbox = mbnode->mailbox)) { /* mailbox, not a folder */
+ if (LIBBALSA_IS_MAILBOX_IMAP(mailbox)) {
+ if (is_connected) {
+ libbalsa_mailbox_imap_reconnect
+ (LIBBALSA_MAILBOX_IMAP(mailbox));
+ } else {
+ libbalsa_mailbox_imap_force_disconnect
+ (LIBBALSA_MAILBOX_IMAP(mailbox));
+ }
+ }
+ }
+ g_object_unref(mbnode);
+
+ return FALSE;
+}
+
+#if BALSA_USE_THREADS
+static void*
+bw_change_connection_status_thread(void *arg)
+{
+ gtk_tree_model_foreach(GTK_TREE_MODEL(balsa_app.mblist_tree_store),
+ (GtkTreeModelForeachFunc)
+ mw_mbox_change_connection_status,
+ arg);
+ return NULL;
+}
+#endif /* BALSA_USE_THREADS */
+
+/** Responds to NetworkManager events and creates, alternatively
+forcefully destroys the IMAP connections. */
+static void
+mw_change_connection_status(libnm_glib_ctx *ctx, gpointer data)
+{
+ gboolean is_connected;
+ libnm_glib_state state = libnm_glib_get_network_state (ctx);
+
+ switch (state) {
+ case LIBNM_NO_DBUS:
+ fprintf(stderr, "Status: No DBUS\n");
+ return;
+ case LIBNM_NO_NETWORKMANAGER:
+ fprintf(stderr, "Status: No NetworkManager\n");
+ return;
+ case LIBNM_NO_NETWORK_CONNECTION:
+ fprintf (stderr, "Status: Inactive Connection\n");
+ is_connected = FALSE;
+ break;
+ case LIBNM_ACTIVE_NETWORK_CONNECTION:
+ fprintf (stderr, "Status: Active Connection\n");
+ is_connected = TRUE;
+ break;
+ case LIBNM_INVALID_CONTEXT:
+ fprintf (stderr, "Status: Error\n");
+ return;
+ default:
+ fprintf (stderr, "Status: unknown\n");
+ return;
+ }
+
+#if BALSA_USE_THREADS
+ {
+ pthread_t thread_id;
+ if (pthread_create(&thread_id,
+ NULL, (void *) &bw_change_connection_status_thread,
+ GINT_TO_POINTER(is_connected)) == 0)
+ pthread_detach(thread_id);
+ }
+#else /* BALSA_USE_THREADS */
+ gtk_tree_model_foreach(GTK_TREE_MODEL(balsa_app.mblist_tree_store),
+ (GtkTreeModelForeachFunc)
+ mw_mbox_change_connection_status,
+ GINT_TO_POINTER(is_connected));
+#endif /* BALSA_USE_THREADS */
+}
+#endif /* LIBNM_GLIB */
+
GtkWidget *
balsa_window_find_current_index(BalsaWindow * window)
{
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]