[evolution-exchange] Bug #590251 - Let it compile and run with eds/evo master
- From: Milan Crha <mcrha src gnome org>
- To: svn-commits-list gnome org
- Cc:
- Subject: [evolution-exchange] Bug #590251 - Let it compile and run with eds/evo master
- Date: Fri, 2 Oct 2009 10:33:39 +0000 (UTC)
commit c1516110e34d4858b480f4336b560329f0902ef6
Author: Milan Crha <mcrha redhat com>
Date: Fri Oct 2 12:32:06 2009 +0200
Bug #590251 - Let it compile and run with eds/evo master
Makefile.am | 10 +-
addressbook/Makefile.am | 7 +-
addressbook/e-book-backend-exchange-factory.c | 72 +-
addressbook/e-book-backend-exchange-factory.h | 67 -
addressbook/e-book-backend-exchange.c | 42 +-
addressbook/e-book-backend-gal-factory.c | 76 -
addressbook/e-book-backend-gal-factory.h | 50 -
addressbook/e-book-backend-gal.c | 12 +-
addressbook/e-book-backend-gal.h | 1 -
autogen.sh | 8 +-
calendar/Makefile.am | 7 +-
calendar/e-cal-backend-exchange-factory.c | 9 +-
calendar/e-cal-backend-exchange.c | 9 +-
camel/Makefile.am | 20 +-
camel/camel-exchange-folder.c | 128 +-
camel/camel-exchange-folder.h | 3 -
camel/camel-exchange-journal.c | 27 +-
camel/camel-exchange-search.c | 10 +-
camel/camel-exchange-store.c | 482 +--
camel/camel-exchange-store.h | 6 +-
camel/camel-exchange-summary.c | 28 +-
camel/camel-exchange-transport.c | 26 +-
.../camel-exchange-utils.c | 4025 ++++++++++----------
camel/camel-exchange-utils.h | 141 +
camel/camel-stub-constants.h | 97 -
camel/camel-stub-marshal.c | 489 ---
camel/camel-stub-marshal.h | 47 -
camel/camel-stub.c | 635 ---
camel/camel-stub.h | 56 -
{mail => camel}/mail-utils.c | 16 +-
{mail => camel}/mail-utils.h | 4 +
configure.ac | 5 +-
mail/Makefile.am | 26 -
mail/mail-stub-exchange.h | 47 -
mail/mail-stub-listener.c | 216 --
mail/mail-stub-listener.h | 45 -
mail/mail-stub.c | 787 ----
mail/mail-stub.h | 111 -
po/POTFILES.in | 17 +-
po/POTFILES.skip | 5 -
.../GNOME_Evolution_Exchange_Storage.server.in.in | 41 -
storage/Makefile.am | 115 -
storage/exchange-component.c | 515 ---
storage/exchange-component.h | 56 -
storage/exchange-config-listener.h | 61 -
storage/exchange-migrate.c | 517 ---
storage/exchange-migrate.h | 11 -
storage/exchange-storage.c | 384 --
storage/exchange-storage.h | 43 -
storage/main.c | 188 -
tools/Makefile.am | 78 +
{storage => tools}/connector-mini.png | Bin 1761 -> 1761 bytes
{storage => tools}/connector.png | Bin 3338 -> 3338 bytes
{storage => tools}/exchange-autoconfig-wizard.c | 2 -
{storage => tools}/exchange-autoconfig-wizard.h | 0
{storage => tools}/exchange-delegates-48.png | Bin 3663 -> 3663 bytes
{storage => tools}/exchange-oof-48.png | Bin 3159 -> 3159 bytes
.../exchange-share-config-listener.c | 197 +-
tools/exchange-share-config-listener.h | 69 +
{storage => tools}/migr-test.c | 0
{storage => tools}/ximian-connector-setup.c | 0
{storage => tools}/ximian-connector.xml | 0
62 files changed, 2625 insertions(+), 7521 deletions(-)
---
diff --git a/Makefile.am b/Makefile.am
index 28036bf..31f991e 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -1,8 +1,10 @@
SUBDIRS = \
- camel mail \
- addressbook calendar \
- storage \
- po docs
+ tools \
+ camel \
+ addressbook \
+ calendar \
+ po \
+ docs
DISTCLEANFILES = \
intltool-extract \
diff --git a/addressbook/Makefile.am b/addressbook/Makefile.am
index 66af3ca..b1e9711 100644
--- a/addressbook/Makefile.am
+++ b/addressbook/Makefile.am
@@ -1,6 +1,5 @@
AM_CPPFLAGS = \
-I$(top_srcdir) \
- -I$(top_srcdir)/storage \
-DG_LOG_DOMAIN=\"e-book-backend-exchange\" \
$(ADDRESSBOOK_CFLAGS) \
$(LIBEXCHANGE_CFLAGS) \
@@ -44,9 +43,6 @@ libebookbackendexchange_la_SOURCES = \
e-book-backend-exchange.c \
e-book-backend-exchange.h \
e-book-backend-exchange-factory.c \
- e-book-backend-exchange-factory.h \
- e-book-backend-gal-factory.c \
- e-book-backend-gal-factory.h \
e-book-backend-gal.c \
e-book-backend-gal.h
@@ -55,7 +51,8 @@ libebookbackendexchange_la_SOURCES += \
e-book-backend-db-cache.c \
e-book-backend-db-cache.h
-libebookbackendexchange_la_LIBADD = \
+libebookbackendexchange_la_LIBADD = \
+ $(top_builddir)/tools/libevolution-exchange-shared.la \
$(DB_LIBS)
libebookbackendexchange_la_LDFLAGS = \
diff --git a/addressbook/e-book-backend-exchange-factory.c b/addressbook/e-book-backend-exchange-factory.c
index c045ecc..aa5afa7 100644
--- a/addressbook/e-book-backend-exchange-factory.c
+++ b/addressbook/e-book-backend-exchange-factory.c
@@ -25,64 +25,26 @@
#include <string.h>
#include <libebackend/e-data-server-module.h>
-#include "e-book-backend-exchange-factory.h"
-#include "e-book-backend-exchange.h"
-
-static GType exchange_type;
-
-static const gchar *
-book_backend_exchange_factory_get_protocol (EBookBackendFactory *factory)
-{
- return "exchange";
-}
+#include <libedata-book/e-book-backend-factory.h>
+#include <camel/camel-object.h>
-static EBookBackend*
-book_backend_exchange_factory_new_backend (EBookBackendFactory *factory)
-{
- return e_book_backend_exchange_new ();
-}
-
-static void
-book_backend_exchange_factory_class_init (EBookBackendExchangeFactoryClass *class)
-{
- EBookBackendFactoryClass *factory_class;
-
- factory_class = E_BOOK_BACKEND_FACTORY_CLASS (class);
- factory_class->get_protocol = book_backend_exchange_factory_get_protocol;
- factory_class->new_backend = book_backend_exchange_factory_new_backend;
-}
-
-GType
-e_book_backend_exchange_factory_get_type (void)
-{
- return exchange_type;
-}
+#include "e-book-backend-exchange.h"
+#include "e-book-backend-gal.h"
-void
-e_book_backend_exchange_factory_register_type (GTypeModule *type_module)
-{
- static const GTypeInfo type_info = {
- sizeof (EBookBackendExchangeFactoryClass),
- (GBaseInitFunc) NULL,
- (GBaseFinalizeFunc) NULL,
- (GClassInitFunc) book_backend_exchange_factory_class_init,
- (GClassFinalizeFunc) NULL,
- NULL, /* class_data */
- sizeof (EBookBackend),
- 0, /* n_preallocs */
- (GInstanceInitFunc) NULL,
- NULL /* value_table */
- };
+E_BOOK_BACKEND_FACTORY_SIMPLE (exchange, Exchange, e_book_backend_exchange_new)
+E_BOOK_BACKEND_FACTORY_SIMPLE (gal, Gal, e_book_backend_gal_new)
- exchange_type = g_type_module_register_type (
- type_module, E_TYPE_BOOK_BACKEND_FACTORY,
- "EBookBackendExchangeFactory", &type_info, 0);
-}
+static GType exchange_types[2];
void
eds_module_initialize (GTypeModule *type_module)
{
- e_book_backend_exchange_factory_register_type (type_module);
+ /* to have a camel type initialized properly */
+ camel_type_init ();
+ camel_object_get_type ();
+
+ exchange_types[0] = _exchange_factory_get_type (type_module);
+ exchange_types[1] = _gal_factory_get_type (type_module);
}
void
@@ -93,10 +55,6 @@ eds_module_shutdown (void)
void
eds_module_list_types (const GType **types, gint *num_types)
{
- static GType module_types[1];
-
- module_types[0] = E_TYPE_BOOK_BACKEND_EXCHANGE_FACTORY;
-
- *types = module_types;
- *num_types = G_N_ELEMENTS (module_types);
+ *types = exchange_types;
+ *num_types = G_N_ELEMENTS (exchange_types);
}
diff --git a/addressbook/e-book-backend-exchange.c b/addressbook/e-book-backend-exchange.c
index 1de981b..b6ab7e9 100644
--- a/addressbook/e-book-backend-exchange.c
+++ b/addressbook/e-book-backend-exchange.c
@@ -57,8 +57,9 @@
#include <exchange-hierarchy.h>
#include <exchange-esource.h>
#include <e-folder-exchange.h>
+
+#include "tools/exchange-share-config-listener.h"
#include "e-book-backend-exchange.h"
-#include "exchange-component.h"
#define DEBUG
#define d(x)
@@ -691,7 +692,7 @@ e_book_backend_exchange_connect (EBookBackendExchange *be)
time_t folder_mtime;
if (!bepriv->account) {
- bepriv->account = exchange_component_get_account_for_uri (global_exchange_component, bepriv->exchange_uri);
+ bepriv->account = exchange_share_config_listener_get_account_for_uri (NULL, bepriv->exchange_uri);
if (!bepriv->account)
return GNOME_Evolution_Addressbook_RepositoryOffline;
}
@@ -2278,7 +2279,7 @@ e_book_backend_exchange_start_book_view (EBookBackend *backend,
d(printf("ebbe_start_book_view(%p, %p)\n", backend, book_view));
- bonobo_object_ref (book_view);
+ e_data_book_view_ref (book_view);
e_data_book_view_notify_status_message (book_view, _("Searching..."));
switch (bepriv->mode) {
@@ -2319,16 +2320,15 @@ e_book_backend_exchange_start_book_view (EBookBackend *backend,
GNOME_Evolution_Addressbook_Success);
if (temp_list)
g_list_free (temp_list);
- bonobo_object_unref (book_view);
+ e_data_book_view_unref (book_view);
return;
case GNOME_Evolution_Addressbook_MODE_REMOTE:
if (!be->priv->ctx) {
e_book_backend_notify_auth_required (backend);
- e_data_book_view_notify_complete (book_view,
- GNOME_Evolution_Addressbook_AuthenticationRequired);
- bonobo_object_unref (book_view);
+ e_data_book_view_notify_complete (book_view, GNOME_Evolution_Addressbook_AuthenticationRequired);
+ e_data_book_view_unref (book_view);
return;
}
@@ -2354,9 +2354,8 @@ e_book_backend_exchange_start_book_view (EBookBackend *backend,
}
status = e2k_result_iter_free (iter);
- e_data_book_view_notify_complete (book_view,
- http_status_to_pas (status));
- bonobo_object_unref (book_view);
+ e_data_book_view_notify_complete (book_view, http_status_to_pas (status));
+ e_data_book_view_unref (book_view);
/* also update the folder list */
exchange_account_rescan_tree (bepriv->account);
@@ -2390,9 +2389,14 @@ typedef struct {
} EBookBackendExchangeChangeContext;
static void
-free_change (gpointer change, gpointer user_data)
+free_change (gpointer data, gpointer user_data)
{
- CORBA_free (change);
+ EDataBookChange *change = data;
+
+ if (change) {
+ g_free (change->vcard);
+ g_free (change);
+ }
}
static gboolean
@@ -2623,7 +2627,7 @@ e_book_backend_exchange_authenticate_user (EBookBackend *backend,
EBookBackendExchange *be = E_BOOK_BACKEND_EXCHANGE (backend);
EBookBackendExchangePrivate *bepriv = be->priv;
ExchangeAccountResult result;
- ExchangeAccount *account;
+ ExchangeAccount *account = NULL;
d(printf("ebbe_authenticate_user(%p, %p, %s, %s, %s)\n", backend, book, user, password, auth_method));
@@ -2637,7 +2641,7 @@ e_book_backend_exchange_authenticate_user (EBookBackend *backend,
case GNOME_Evolution_Addressbook_MODE_REMOTE:
- bepriv->account = account = exchange_component_get_account_for_uri (global_exchange_component, NULL);
+ bepriv->account = account = exchange_share_config_listener_get_account_for_uri (NULL, bepriv->exchange_uri);
/* FIXME : Check for failures */
if (!(bepriv->ctx = exchange_account_get_context (account))) {
exchange_account_set_online (account);
@@ -2801,12 +2805,12 @@ e_book_backend_exchange_remove (EBookBackendSync *backend, EDataBook *book, guin
if (int_uri)
result = exchange_account_remove_folder (bepriv->account, int_uri);
else {
- ExchangeAccount *account;
+ ExchangeAccount *account = NULL;
/* internal URI is NULL, mostly the case where folder doesn't exists anymore
* in the server, update the gconf sources.
*/
- account = exchange_component_get_account_for_uri (global_exchange_component, NULL);
+ account = exchange_share_config_listener_get_account_for_uri (NULL, bepriv->exchange_uri);
if (exchange_account_get_context (account)) {
remove_folder_esource (account, EXCHANGE_CONTACTS_FOLDER, bepriv->exchange_uri);
result = EXCHANGE_ACCOUNT_FOLDER_OK;
@@ -2850,7 +2854,7 @@ e_book_backend_exchange_set_mode (EBookBackend *backend,
{
EBookBackendExchange *be = E_BOOK_BACKEND_EXCHANGE (backend);
EBookBackendExchangePrivate *bepriv = be->priv;
- ExchangeAccount *account;
+ ExchangeAccount *account = NULL;
bepriv->mode = mode;
/* if (e_book_backend_is_loaded (backend)) { */
@@ -2863,7 +2867,7 @@ e_book_backend_exchange_set_mode (EBookBackend *backend,
e_book_backend_set_is_writable (backend, bepriv->is_writable);
e_book_backend_notify_writable (backend, bepriv->is_writable);
e_book_backend_notify_connection_status (backend, TRUE);
- account = exchange_component_get_account_for_uri (global_exchange_component, NULL);
+ account = exchange_share_config_listener_get_account_for_uri (NULL, bepriv->exchange_uri);
if (!exchange_account_get_context (account))
e_book_backend_notify_auth_required (backend);
}
@@ -2882,6 +2886,8 @@ e_book_backend_exchange_new (void)
{
EBookBackendExchange *backend;
+ exchange_share_config_listener_get_account_for_uri (NULL, NULL);
+
backend = g_object_new (e_book_backend_exchange_get_type (), NULL);
if (! e_book_backend_exchange_construct (backend)) {
diff --git a/addressbook/e-book-backend-gal.c b/addressbook/e-book-backend-gal.c
index 0371a99..03ac4d3 100644
--- a/addressbook/e-book-backend-gal.c
+++ b/addressbook/e-book-backend-gal.c
@@ -35,7 +35,6 @@
#include <e2k-utils.h>
#include <e2k-global-catalog-ldap.h>
#include <exchange-account.h>
-#include "exchange-component.h"
#define d(x)
@@ -50,6 +49,7 @@
#include <libedata-book/e-data-book.h>
#include <libedata-book/e-data-book-view.h>
#include "libedata-book/e-book-backend-summary.h"
+#include "tools/exchange-share-config-listener.h"
#include "e-book-backend-gal.h"
#include <libical/ical.h>
@@ -271,7 +271,7 @@ gal_connect (EBookBackendGAL *bl)
blpriv->gc = NULL;
blpriv->connected = FALSE;
- blpriv->account = exchange_component_get_account_for_uri (global_exchange_component, blpriv->gal_uri);
+ blpriv->account = exchange_share_config_listener_get_account_for_uri (NULL, blpriv->gal_uri);
if (!blpriv->account)
return GNOME_Evolution_Addressbook_RepositoryOffline;
blpriv->gc = exchange_account_get_global_catalog (blpriv->account);
@@ -1711,7 +1711,7 @@ ldap_search_dtor (LDAPOp *op)
d(printf ("ldap_search_dtor: Setting null inplace of %p in view %p\n", op, search_op->view));
g_object_set_data (G_OBJECT (search_op->view), "EBookBackendGAL.BookView::search_op", NULL);
- bonobo_object_unref (search_op->view);
+ e_data_book_view_unref (search_op->view);
if (!search_op->aborted)
g_free (search_op);
@@ -1923,7 +1923,7 @@ start_book_view (EBookBackend *backend,
op->view = view;
op->aborted = FALSE;
- bonobo_object_ref (view);
+ e_data_book_view_ref (view);
ldap_op_add ((LDAPOp*)op, E_BOOK_BACKEND (bl), NULL, view,
0, search_msgid,
@@ -2325,7 +2325,7 @@ authenticate_user (EBookBackend *backend,
EBookBackendGAL *be = E_BOOK_BACKEND_GAL (backend);
EBookBackendGALPrivate *bepriv = be->priv;
ExchangeAccountResult result;
- ExchangeAccount *account;
+ ExchangeAccount *account = NULL;
GNOME_Evolution_Addressbook_CallStatus res;
GConfClient *gc = gconf_client_get_default();
gint interval = gconf_client_get_int (gc, "/apps/evolution/addressbook/gal_cache_interval", NULL);
@@ -2348,7 +2348,7 @@ authenticate_user (EBookBackend *backend,
case GNOME_Evolution_Addressbook_MODE_REMOTE:
- account = exchange_component_get_account_for_uri (global_exchange_component, NULL);
+ account = exchange_share_config_listener_get_account_for_uri (NULL, bepriv->gal_uri);
/* FIXME : Check for failures */
if (!exchange_account_get_context (account)) {
exchange_account_set_online (account);
diff --git a/addressbook/e-book-backend-gal.h b/addressbook/e-book-backend-gal.h
index 43ad2f3..e074afe 100644
--- a/addressbook/e-book-backend-gal.h
+++ b/addressbook/e-book-backend-gal.h
@@ -5,7 +5,6 @@
#define __E_BOOK_BACKEND_GAL_H__
#include "libedata-book/e-book-backend.h"
-#include "exchange-component.h"
#ifdef SUNLDAP
/* copy from openldap ldap.h */
diff --git a/autogen.sh b/autogen.sh
index 1ba8eb6..dbbfd8b 100755
--- a/autogen.sh
+++ b/autogen.sh
@@ -9,14 +9,14 @@ REQUIRED_AUTOMAKE_VERSION=1.6
(test -f $srcdir/configure.ac \
&& test -f $srcdir/ChangeLog \
- && test -d $srcdir/storage) || {
- echo -n "**Error**: Directory "\`$srcdir\'" does not look like the"
- echo " top-level $PKG_NAME directory"
+ && test -d $srcdir/camel) || {
+ echo -n "**Error**: Directory "\`$srcdir\'" does not look like the" >&2
+ echo " top-level $PKG_NAME directory" >&2
exit 1
}
which gnome-autogen.sh || {
- echo "You need to install gnome-common from the GNOME CVS"
+ echo "You need to install gnome-common from the GNOME git" >&2
exit 1
}
USE_GNOME2_MACROS=1 . gnome-autogen.sh
diff --git a/calendar/Makefile.am b/calendar/Makefile.am
index 270cf09..2664176 100644
--- a/calendar/Makefile.am
+++ b/calendar/Makefile.am
@@ -1,6 +1,5 @@
AM_CPPFLAGS = \
-I$(top_srcdir) \
- -I$(top_srcdir)/storage \
$(CALENDAR_CFLAGS) \
$(LIBEXCHANGE_CFLAGS) \
$(LDAP_CFLAGS) \
@@ -26,4 +25,10 @@ libecalbackendexchange_la_SOURCES = \
libecalbackendexchange_la_LDFLAGS = \
-module -avoid-version $(NO_UNDEFINED)
+libecalbackendexchange_la_LIBADD = \
+ $(top_builddir)/tools/libevolution-exchange-shared.la \
+ $(CALENDAR_LIBS) \
+ $(LIBEXCHANGE_LIBS) \
+ $(LDAP_LIBS)
+
-include $(top_srcdir)/git.mk
diff --git a/calendar/e-cal-backend-exchange-factory.c b/calendar/e-cal-backend-exchange-factory.c
index 62c0de5..6545f41 100644
--- a/calendar/e-cal-backend-exchange-factory.c
+++ b/calendar/e-cal-backend-exchange-factory.c
@@ -25,6 +25,7 @@
#include <string.h>
#include <libebackend/e-data-server-module.h>
+#include <camel/camel-object.h>
#include "e-cal-backend-exchange-factory.h"
#include "e-cal-backend-exchange-calendar.h"
#include "e-cal-backend-exchange-tasks.h"
@@ -98,7 +99,7 @@ e_cal_backend_exchange_events_factory_register_type (GTypeModule *type_module)
(GClassInitFunc) events_backend_exchange_factory_class_init,
(GClassFinalizeFunc) NULL,
NULL, /* class_data */
- sizeof (ECalBackendExchangeFactory),
+ sizeof (ECalBackend),
0, /* n_preallocs */
(GInstanceInitFunc) NULL,
NULL /* value_table */
@@ -125,7 +126,7 @@ e_cal_backend_exchange_todos_factory_register_type (GTypeModule *type_module)
(GClassInitFunc) todos_backend_exchange_factory_class_init,
(GClassFinalizeFunc) NULL,
NULL, /* class_data */
- sizeof (ECalBackendExchangeFactory),
+ sizeof (ECalBackend),
0, /* n_preallocs */
(GInstanceInitFunc) NULL,
NULL /* value_table */
@@ -139,6 +140,10 @@ e_cal_backend_exchange_todos_factory_register_type (GTypeModule *type_module)
void
eds_module_initialize (GTypeModule *type_module)
{
+ /* to have a camel type initialized properly */
+ camel_type_init ();
+ camel_object_get_type ();
+
e_cal_backend_exchange_events_factory_register_type (type_module);
e_cal_backend_exchange_todos_factory_register_type (type_module);
}
diff --git a/calendar/e-cal-backend-exchange.c b/calendar/e-cal-backend-exchange.c
index 031ded6..aae4257 100644
--- a/calendar/e-cal-backend-exchange.c
+++ b/calendar/e-cal-backend-exchange.c
@@ -51,9 +51,10 @@
#include <exchange-account.h>
#include <exchange-hierarchy.h>
-#include "exchange-component.h"
#include <e2k-utils.h>
+#include "tools/exchange-share-config-listener.h"
+
#ifndef O_BINARY
#define O_BINARY 0
#endif
@@ -375,7 +376,7 @@ open_calendar (ECalBackendSync *backend, EDataCal *cal, gboolean only_if_exists,
return GNOME_Evolution_Calendar_RepositoryOffline;
}
- cbex->account = exchange_component_get_account_for_uri (global_exchange_component, NULL);
+ cbex->account = exchange_share_config_listener_get_account_for_uri (NULL, uristr);
if (cbex->account) {
exchange_account_set_offline (cbex->account);
@@ -408,9 +409,7 @@ open_calendar (ECalBackendSync *backend, EDataCal *cal, gboolean only_if_exists,
/* Make sure we have an open connection */
/* This steals the ExchangeAccount from ExchangeComponent */
if (!cbex->account) {
- cbex->account = exchange_component_get_account_for_uri (global_exchange_component, uristr);
- if (!cbex->account)
- cbex->account = exchange_component_get_account_for_uri (global_exchange_component, NULL);
+ cbex->account = exchange_share_config_listener_get_account_for_uri (NULL, uristr);
}
if (!cbex->account) {
diff --git a/camel/Makefile.am b/camel/Makefile.am
index 78a82ea..1b8b629 100644
--- a/camel/Makefile.am
+++ b/camel/Makefile.am
@@ -21,8 +21,8 @@ libcamelexchange_la_SOURCES = \
camel-exchange-store.c \
camel-exchange-summary.c \
camel-exchange-transport.c \
- camel-stub-marshal.c \
- camel-stub.c
+ camel-exchange-utils.c \
+ mail-utils.c
noinst_HEADERS = \
camel-exchange-folder.h \
@@ -31,18 +31,18 @@ noinst_HEADERS = \
camel-exchange-store.h \
camel-exchange-summary.h \
camel-exchange-transport.h \
- camel-stub-constants.h \
- camel-stub-marshal.h \
- camel-stub.h
+ camel-exchange-utils.h \
+ mail-utils.h
libcamelexchange_la_LDFLAGS = \
-avoid-version -module $(NO_UNDEFINED)
-libcamelexchange_la_LIBADD = \
- $(LDAP_LIBS) \
- $(LIBEXCHANGE_LIBS) \
- $(EXCHANGE_STORAGE_LIBS) \
- $(SOCKET_LIBS) \
+libcamelexchange_la_LIBADD = \
+ $(top_builddir)/tools/libevolution-exchange-shared.la \
+ $(LDAP_LIBS) \
+ $(LIBEXCHANGE_LIBS) \
+ $(EXCHANGE_STORAGE_LIBS) \
+ $(SOCKET_LIBS) \
$(PTHREAD_LIB)
EXTRA_DIST = libcamelexchange.urls
diff --git a/camel/camel-exchange-folder.c b/camel/camel-exchange-folder.c
index 359990c..c45243a 100644
--- a/camel/camel-exchange-folder.c
+++ b/camel/camel-exchange-folder.c
@@ -30,12 +30,6 @@
#include <glib/gi18n-lib.h>
#include <libedataserver/e-data-server-util.h>
-#include "camel-exchange-folder.h"
-#include "camel-exchange-search.h"
-#include "camel-exchange-store.h"
-#include "camel-exchange-summary.h"
-#include "camel-exchange-journal.h"
-
#include <camel/camel-data-wrapper.h>
#include <camel/camel-exception.h>
#include <camel/camel-file-utils.h>
@@ -48,6 +42,13 @@
#include <camel/camel-folder-summary.h>
#include <camel/camel-string-utils.h>
+#include "camel-exchange-folder.h"
+#include "camel-exchange-search.h"
+#include "camel-exchange-store.h"
+#include "camel-exchange-summary.h"
+#include "camel-exchange-journal.h"
+#include "camel-exchange-utils.h"
+
static CamelOfflineFolderClass *parent_class = NULL;
/* Returns the class for a CamelFolder */
@@ -173,18 +174,11 @@ refresh_info (CamelFolder *folder, CamelException *ex)
if (camel_exchange_store_connected (store, ex)) {
camel_offline_journal_replay (exch->journal, NULL);
- camel_stub_send (exch->stub, ex, CAMEL_STUB_CMD_REFRESH_FOLDER,
- CAMEL_STUB_ARG_FOLDER, folder->full_name,
- CAMEL_STUB_ARG_END);
+ camel_exchange_utils_refresh_folder (CAMEL_SERVICE (folder->parent_store), folder->full_name, ex);
}
/* sync up the counts now */
- if (!camel_stub_send (exch->stub, ex, CAMEL_STUB_CMD_SYNC_COUNT,
- CAMEL_STUB_ARG_FOLDER, folder->full_name,
- CAMEL_STUB_ARG_RETURN,
- CAMEL_STUB_ARG_UINT32, &unread_count,
- CAMEL_STUB_ARG_UINT32, &visible_count,
- CAMEL_STUB_ARG_END)) {
+ if (!camel_exchange_utils_sync_count (CAMEL_SERVICE (folder->parent_store), folder->full_name, &unread_count, &visible_count, ex)) {
g_print("\n Error syncing up the counts");
}
@@ -195,7 +189,6 @@ refresh_info (CamelFolder *folder, CamelException *ex)
static void
exchange_expunge (CamelFolder *folder, CamelException *ex)
{
- CamelExchangeFolder *exch = CAMEL_EXCHANGE_FOLDER (folder);
CamelFolder *trash;
GPtrArray *uids;
CamelExchangeStore *store = CAMEL_EXCHANGE_STORE (folder->parent_store);
@@ -213,10 +206,7 @@ exchange_expunge (CamelFolder *folder, CamelException *ex)
}
uids = camel_folder_get_uids (trash);
- camel_stub_send (exch->stub, ex, CAMEL_STUB_CMD_EXPUNGE_UIDS,
- CAMEL_STUB_ARG_FOLDER, trash->full_name,
- CAMEL_STUB_ARG_STRINGARRAY, uids,
- CAMEL_STUB_ARG_END);
+ camel_exchange_utils_expunge_uids (CAMEL_SERVICE (trash->parent_store), trash->full_name, uids, ex);
camel_folder_free_uids (trash, uids);
camel_object_unref (CAMEL_OBJECT (trash));
}
@@ -235,14 +225,13 @@ append_message_data (CamelFolder *folder, GByteArray *message,
if (!subject)
subject = _("No Subject");
- if (camel_stub_send (exch->stub, ex, CAMEL_STUB_CMD_APPEND_MESSAGE,
- CAMEL_STUB_ARG_FOLDER, folder->full_name,
- CAMEL_STUB_ARG_UINT32, info? camel_message_info_flags(info): 0,
- CAMEL_STUB_ARG_STRING, subject,
- CAMEL_STUB_ARG_BYTEARRAY, message,
- CAMEL_STUB_ARG_RETURN,
- CAMEL_STUB_ARG_STRING, &new_uid,
- CAMEL_STUB_ARG_END)) {
+ if (camel_exchange_utils_append_message (CAMEL_SERVICE (folder->parent_store),
+ folder->full_name,
+ info ? camel_message_info_flags (info) : 0,
+ subject,
+ message,
+ &new_uid,
+ ex)) {
stream_cache = camel_data_cache_add (exch->cache,
"cache", new_uid, NULL);
if (stream_cache) {
@@ -400,12 +389,7 @@ get_message_data (CamelFolder *folder, const gchar *uid, CamelException *ex)
return NULL;
}
- if (!camel_stub_send (exch->stub, ex, CAMEL_STUB_CMD_GET_MESSAGE,
- CAMEL_STUB_ARG_FOLDER, folder->full_name,
- CAMEL_STUB_ARG_STRING, uid,
- CAMEL_STUB_ARG_RETURN,
- CAMEL_STUB_ARG_BYTEARRAY, &ba,
- CAMEL_STUB_ARG_END))
+ if (!camel_exchange_utils_get_message (CAMEL_SERVICE (folder->parent_store), folder->full_name, uid, &ba, ex))
return NULL;
stream = camel_data_cache_add (exch->cache, "cache", uid, ex);
@@ -539,7 +523,6 @@ transfer_messages_the_hard_way (CamelFolder *source, GPtrArray *uids,
GPtrArray **transferred_uids,
gboolean delete_originals, CamelException *ex)
{
- CamelExchangeFolder *exch_source = CAMEL_EXCHANGE_FOLDER (source);
CamelException local_ex;
CamelMessageInfo *info;
GByteArray *ba;
@@ -580,16 +563,12 @@ transfer_messages_the_hard_way (CamelFolder *source, GPtrArray *uids,
}
if (delete_originals) {
- camel_stub_send (exch_source->stub, ex,
- CAMEL_STUB_CMD_EXPUNGE_UIDS,
- CAMEL_STUB_ARG_FOLDER, source->full_name,
- CAMEL_STUB_ARG_STRINGARRAY, uids,
- CAMEL_STUB_ARG_END);
+ camel_exchange_utils_expunge_uids (CAMEL_SERVICE (source->parent_store), source->full_name, uids, ex);
}
}
static void
-cache_xfer (CamelExchangeFolder *stub_source, CamelExchangeFolder *stub_dest,
+cache_xfer (CamelExchangeFolder *folder_source, CamelExchangeFolder *folder_dest,
GPtrArray *src_uids, GPtrArray *dest_uids, gboolean delete)
{
CamelStream *src, *dest;
@@ -599,12 +578,12 @@ cache_xfer (CamelExchangeFolder *stub_source, CamelExchangeFolder *stub_dest,
if (!*(gchar *)dest_uids->pdata[i])
continue;
- src = camel_data_cache_get (stub_source->cache, "cache",
+ src = camel_data_cache_get (folder_source->cache, "cache",
src_uids->pdata[i], NULL);
if (!src)
continue;
- dest = camel_data_cache_add (stub_dest->cache, "cache",
+ dest = camel_data_cache_add (folder_dest->cache, "cache",
dest_uids->pdata[i], NULL);
if (dest) {
camel_stream_write_to_stream (src, dest);
@@ -613,7 +592,7 @@ cache_xfer (CamelExchangeFolder *stub_source, CamelExchangeFolder *stub_dest,
camel_object_unref (CAMEL_OBJECT (src));
if (delete) {
- camel_data_cache_remove (stub_source->cache, "cache",
+ camel_data_cache_remove (folder_source->cache, "cache",
src_uids->pdata[i], NULL);
}
}
@@ -667,25 +646,20 @@ transfer_messages_to (CamelFolder *source, GPtrArray *uids,
return;
}
- if (camel_stub_send (exch_source->stub, ex,
- CAMEL_STUB_CMD_TRANSFER_MESSAGES,
- CAMEL_STUB_ARG_FOLDER, source->full_name,
- CAMEL_STUB_ARG_FOLDER, dest->full_name,
- CAMEL_STUB_ARG_STRINGARRAY, uids,
- CAMEL_STUB_ARG_UINT32, (guint32)delete_originals,
- CAMEL_STUB_ARG_RETURN,
- CAMEL_STUB_ARG_STRINGARRAY, &ret_uids,
- CAMEL_STUB_ARG_END)) {
+ if (camel_exchange_utils_transfer_messages (CAMEL_SERVICE (store),
+ source->full_name,
+ dest->full_name,
+ uids,
+ delete_originals,
+ &ret_uids,
+ ex)) {
if (ret_uids->len != 0)
cache_xfer (exch_source, exch_dest, uids, ret_uids, FALSE);
if (transferred_uids)
*transferred_uids = ret_uids;
else {
- gint i;
-
- for (i = 0; i < ret_uids->len; i++)
- g_free (ret_uids->pdata[i]);
+ g_ptr_array_foreach (ret_uids, (GFunc) g_free, NULL);
g_ptr_array_free (ret_uids, TRUE);
}
} else if (transferred_uids)
@@ -760,7 +734,7 @@ camel_exchange_folder_add_message (CamelExchangeFolder *exch,
camel_data_wrapper_construct_from_stream (CAMEL_DATA_WRAPPER (msg), stream);
camel_object_unref (CAMEL_OBJECT (stream));
- info = camel_folder_summary_info_new_from_message (folder->summary, msg);
+ info = camel_folder_summary_info_new_from_message (folder->summary, msg, NULL);
einfo = (CamelExchangeMessageInfo *)info;
if (einfo->thread_index) {
@@ -978,19 +952,15 @@ camel_exchange_folder_update_message_tag (CamelExchangeFolder *exch,
* @camel_flags: the folder flags passed to camel_store_get_folder().
* @folder_dir: local directory this folder can cache data into
* @offline_state : offline status
- * @stub: the #CamelStub.
* @ex: a #CamelException
*
- * Constructs @folder by requesting the necessary data from the server
- * via @stub.
- *
* Return value: success or failure.
**/
gboolean
camel_exchange_folder_construct (CamelFolder *folder, CamelStore *parent,
const gchar *name, guint32 camel_flags,
const gchar *folder_dir, gint offline_state,
- CamelStub *stub, CamelException *ex)
+ CamelException *ex)
{
CamelExchangeFolder *exch = (CamelExchangeFolder *)folder;
const gchar *short_name;
@@ -1064,10 +1034,8 @@ camel_exchange_folder_construct (CamelFolder *folder, CamelStore *parent,
camel_message_info_free(info);
}
- if (stub) {
- gboolean ok, create = camel_flags & CAMEL_STORE_FOLDER_CREATE;
-
- exch->stub = stub;
+ if (parent) {
+ gboolean ok, create = camel_flags & CAMEL_STORE_FOLDER_CREATE, readonly = FALSE;
summary = camel_folder_get_summary (folder);
uids = g_ptr_array_new ();
@@ -1089,17 +1057,9 @@ camel_exchange_folder_construct (CamelFolder *folder, CamelStore *parent,
}
camel_operation_start (NULL, _("Scanning for changed messages"));
- ok = camel_stub_send (exch->stub, ex, CAMEL_STUB_CMD_GET_FOLDER,
- CAMEL_STUB_ARG_FOLDER, name,
- CAMEL_STUB_ARG_UINT32, create,
- CAMEL_STUB_ARG_STRINGARRAY, uids,
- CAMEL_STUB_ARG_BYTEARRAY, flags,
- CAMEL_STUB_ARG_STRINGARRAY, hrefs,
- CAMEL_STUB_ARG_UINT32, CAMEL_EXCHANGE_SUMMARY(folder->summary)->high_article_num,
- CAMEL_STUB_ARG_RETURN,
- CAMEL_STUB_ARG_UINT32, &folder_flags,
- CAMEL_STUB_ARG_STRING, &exch->source,
- CAMEL_STUB_ARG_END);
+ ok = camel_exchange_utils_get_folder (CAMEL_SERVICE (parent),
+ name, create, uids, flags, hrefs, CAMEL_EXCHANGE_SUMMARY (folder->summary)->high_article_num,
+ &folder_flags, &exch->source, &readonly, ex);
camel_operation_end (NULL);
g_ptr_array_free (uids, TRUE);
g_byte_array_free (flags, TRUE);
@@ -1108,23 +1068,21 @@ camel_exchange_folder_construct (CamelFolder *folder, CamelStore *parent,
if (!ok)
return FALSE;
- if (folder_flags & CAMEL_STUB_FOLDER_FILTER)
+ if (folder_flags & CAMEL_FOLDER_FILTER_RECENT)
folder->folder_flags |= CAMEL_FOLDER_FILTER_RECENT;
- if (folder_flags & CAMEL_STUB_FOLDER_FILTER_JUNK)
+ if (folder_flags & CAMEL_FOLDER_FILTER_JUNK)
folder->folder_flags |= CAMEL_FOLDER_FILTER_JUNK;
- camel_exchange_summary_set_readonly (folder->summary, folder_flags & CAMEL_STUB_FOLDER_READONLY);
+ camel_exchange_summary_set_readonly (folder->summary, readonly);
- if (offline_state == CAMEL_OFFLINE_STORE_NETWORK_UNAVAIL )
+ if (offline_state == CAMEL_OFFLINE_STORE_NETWORK_UNAVAIL)
return TRUE;
if (len)
return TRUE;
camel_operation_start (NULL, _("Fetching summary information for new messages"));
- ok = camel_stub_send (exch->stub, ex, CAMEL_STUB_CMD_REFRESH_FOLDER,
- CAMEL_STUB_ARG_FOLDER, folder->full_name,
- CAMEL_STUB_ARG_END);
+ ok = camel_exchange_utils_refresh_folder (CAMEL_SERVICE (parent), folder->full_name, ex);
camel_operation_end (NULL);
if (!ok)
return FALSE;
diff --git a/camel/camel-exchange-folder.h b/camel/camel-exchange-folder.h
index ed06d17..590355f 100644
--- a/camel/camel-exchange-folder.h
+++ b/camel/camel-exchange-folder.h
@@ -13,7 +13,6 @@ G_BEGIN_DECLS
#include <camel/camel-data-cache.h>
#include <camel/camel-offline-folder.h>
#include <camel/camel-offline-journal.h>
-#include "camel-stub.h"
#define CAMEL_EXCHANGE_FOLDER_TYPE (camel_exchange_folder_get_type ())
#define CAMEL_EXCHANGE_FOLDER(obj) (CAMEL_CHECK_CAST((obj), CAMEL_EXCHANGE_FOLDER_TYPE, CamelExchangeFolder))
@@ -23,7 +22,6 @@ G_BEGIN_DECLS
typedef struct {
CamelOfflineFolder parent_object;
- CamelStub *stub;
CamelDataCache *cache;
CamelOfflineJournal *journal;
gchar *source;
@@ -45,7 +43,6 @@ gboolean camel_exchange_folder_construct (CamelFolder *folder,
guint32 camel_flags,
const gchar *folder_dir,
gint offline_state,
- CamelStub *stub,
CamelException *ex);
void camel_exchange_folder_add_message (CamelExchangeFolder *exch,
diff --git a/camel/camel-exchange-journal.c b/camel/camel-exchange-journal.c
index d8b2a9d..af11fd0 100644
--- a/camel/camel-exchange-journal.c
+++ b/camel/camel-exchange-journal.c
@@ -42,6 +42,7 @@
#include "camel-exchange-journal.h"
#include "camel-exchange-store.h"
#include "camel-exchange-summary.h"
+#include "camel-exchange-utils.h"
#define d(x)
@@ -231,20 +232,14 @@ exchange_message_info_dup_to (CamelMessageInfoBase *dest, CamelMessageInfoBase *
static gint
exchange_entry_play_delete (CamelOfflineJournal *journal, CamelExchangeJournalEntry *entry, CamelException *ex)
{
- CamelExchangeFolder *exchange_folder = (CamelExchangeFolder *) journal->folder;
-
- camel_stub_send_oneway (exchange_folder->stub,
- CAMEL_STUB_CMD_SET_MESSAGE_FLAGS,
- CAMEL_STUB_ARG_FOLDER,
- ((CamelFolder *)exchange_folder)->full_name,
- CAMEL_STUB_ARG_STRING,
- entry->uid,
- CAMEL_STUB_ARG_UINT32,
- entry->set,
- CAMEL_STUB_ARG_UINT32,
- entry->flags,
- CAMEL_STUB_ARG_END);
+ CamelFolder *folder = (CamelFolder *) journal->folder;
+ camel_exchange_utils_set_message_flags (CAMEL_SERVICE (folder->parent_store),
+ folder->full_name,
+ entry->uid,
+ entry->set,
+ entry->flags,
+ ex);
return 0;
}
@@ -285,7 +280,7 @@ exchange_entry_play_append (CamelOfflineJournal *journal, CamelExchangeJournalEn
return -1;
}
- real = camel_folder_summary_info_new_from_message (folder->summary, message);
+ real = camel_folder_summary_info_new_from_message (folder->summary, message, NULL);
camel_object_unref (message);
if (uid != NULL && real) {
@@ -351,7 +346,7 @@ exchange_entry_play_transfer (CamelOfflineJournal *journal, CamelExchangeJournal
camel_exception_init (&lex);
camel_folder_transfer_messages_to (src, uids, folder, &xuids, entry->delete_original, &lex);
if (!camel_exception_is_set (&lex)) {
- real = camel_folder_summary_info_new_from_message (folder->summary, message);
+ real = camel_folder_summary_info_new_from_message (folder->summary, message, NULL);
camel_object_unref (message);
real->uid = camel_pstring_strdup ((gchar *)xuids->pdata[0]);
/* Transfer flags */
@@ -457,7 +452,7 @@ update_cache (CamelExchangeJournal *exchange_journal, CamelMimeMessage *message,
camel_object_unref (cache);
- info = camel_folder_summary_info_new_from_message (folder->summary, message);
+ info = camel_folder_summary_info_new_from_message (folder->summary, message, NULL);
info->uid = camel_pstring_strdup (uid);
exchange_message_info_dup_to ((CamelMessageInfoBase *) info, (CamelMessageInfoBase *) mi);
diff --git a/camel/camel-exchange-search.c b/camel/camel-exchange-search.c
index 2bdf1b9..a662cf7 100644
--- a/camel/camel-exchange-search.c
+++ b/camel/camel-exchange-search.c
@@ -30,6 +30,7 @@
#include "camel-exchange-search.h"
#include "camel-exchange-folder.h"
+#include "camel-exchange-utils.h"
static ESExpResult *
exchange_body_contains (struct _ESExp *f, gint argc, struct _ESExpResult **argv,
@@ -71,7 +72,6 @@ static ESExpResult *
exchange_body_contains (struct _ESExp *f, gint argc, struct _ESExpResult **argv,
CamelFolderSearch *s)
{
- CamelExchangeFolder *folder = CAMEL_EXCHANGE_FOLDER (s->folder);
gchar *value = argv[0]->value.string, *real_uid;
const gchar *uid;
ESExpResult *r;
@@ -105,13 +105,7 @@ exchange_body_contains (struct _ESExp *f, gint argc, struct _ESExpResult **argv,
}
/* FIXME: what if we have multiple string args? */
- if (!camel_stub_send (folder->stub, NULL,
- CAMEL_STUB_CMD_SEARCH_FOLDER,
- CAMEL_STUB_ARG_FOLDER, s->folder->full_name,
- CAMEL_STUB_ARG_STRING, value,
- CAMEL_STUB_ARG_RETURN,
- CAMEL_STUB_ARG_STRINGARRAY, &found_uids,
- CAMEL_STUB_ARG_END))
+ if (!camel_exchange_utils_search (CAMEL_SERVICE (s->folder->parent_store), s->folder->full_name, value, &found_uids, NULL))
return r;
if (!found_uids->len) {
diff --git a/camel/camel-exchange-store.c b/camel/camel-exchange-store.c
index a6bc9b8..6d53f9c 100644
--- a/camel/camel-exchange-store.c
+++ b/camel/camel-exchange-store.c
@@ -34,6 +34,7 @@
#include "camel-exchange-store.h"
#include "camel-exchange-folder.h"
#include "camel-exchange-summary.h"
+#include "camel-exchange-utils.h"
#define SUBFOLDER_DIR_NAME "subfolders"
#define SUBFOLDER_DIR_NAME_LEN 10
@@ -84,8 +85,6 @@ static void exchange_unsubscribe_folder (CamelStore *store,
CamelException *ex);
static gboolean exchange_can_refresh_folder (CamelStore *store, CamelFolderInfo *info, CamelException *ex);
-static void stub_notification (CamelObject *object, gpointer event_data, gpointer user_data);
-
static void
class_init (CamelExchangeStoreClass *camel_exchange_store_class)
{
@@ -137,11 +136,6 @@ init (CamelExchangeStore *exch, CamelExchangeStoreClass *klass)
static void
finalize (CamelExchangeStore *exch)
{
- if (exch->stub) {
- camel_object_unref (CAMEL_OBJECT (exch->stub));
- exch->stub = NULL;
- }
-
g_free (exch->trash_name);
if (exch->folders_lock)
@@ -292,8 +286,6 @@ construct (CamelService *service, CamelSession *session,
if (!(exch->storage_path = camel_session_get_storage_path (session, service, ex)))
return;
-
- exch->stub = NULL;
}
extern CamelServiceAuthType camel_exchange_password_authtype;
@@ -354,57 +346,21 @@ camel_exchange_forget_password (CamelService *service, CamelException *ex)
}
}
-static void
-update_camel_stub (gpointer folder_name, gpointer folder, gpointer user_data)
-{
- CamelExchangeFolder *exch_folder = CAMEL_EXCHANGE_FOLDER (folder);
- if (exch_folder)
- exch_folder->stub = (CamelStub *)user_data;
-}
-
static gboolean
exchange_connect (CamelService *service, CamelException *ex)
{
CamelExchangeStore *exch = CAMEL_EXCHANGE_STORE (service);
- gchar *real_user, *socket_path, *dot_exchange_username, *user_at_host;
gchar *password = NULL;
guint32 connect_status;
gboolean online_mode = FALSE;
/* This lock is only needed for offline operation. exchange_connect
- is called many times in offline to ensure we are connected atleast
- to the mail stub. Think twice before changing anything here.*/
+ is called many times in offline. */
g_mutex_lock (exch->connect_lock);
online_mode = camel_session_is_online (service->session);
-
- if (exch->stub == NULL) {
- real_user = strpbrk (service->url->user, "\\/");
- if (real_user)
- real_user++;
- else
- real_user = service->url->user;
- dot_exchange_username = g_strdup_printf (".exchange-%s", g_get_user_name ());
- user_at_host = g_strdup_printf ("%s %s", real_user, service->url->host);
- e_filename_make_safe (user_at_host);
- socket_path = g_build_filename (g_get_tmp_dir (),
- dot_exchange_username,
- user_at_host,
- NULL);
- g_free (dot_exchange_username);
- g_free (user_at_host);
-
- exch->stub = camel_stub_new (socket_path, _("Evolution Exchange backend process"), ex);
- g_free (socket_path);
- if (!exch->stub) {
- g_mutex_unlock (exch->connect_lock);
- return FALSE;
- }
-
- camel_object_hook_event (CAMEL_OBJECT (exch->stub), "notification",
- stub_notification, exch);
- } else if (!online_mode && exch->stub_connected) {
+ if (!online_mode) {
g_mutex_unlock (exch->connect_lock);
return TRUE;
}
@@ -412,8 +368,6 @@ exchange_connect (CamelService *service, CamelException *ex)
if (online_mode) {
camel_exchange_get_password (service, ex);
if (camel_exception_is_set (ex)) {
- camel_object_unref (exch->stub);
- exch->stub = NULL;
g_mutex_unlock (exch->connect_lock);
return FALSE;
}
@@ -421,16 +375,10 @@ exchange_connect (CamelService *service, CamelException *ex)
}
/* Initialize the stub connection */
- if (!camel_stub_send (exch->stub, NULL, CAMEL_STUB_CMD_CONNECT,
- CAMEL_STUB_ARG_STRING, password,
- CAMEL_STUB_ARG_RETURN,
- CAMEL_STUB_ARG_UINT32, &connect_status,
- CAMEL_STUB_ARG_END)) {
+ if (!camel_exchange_utils_connect (service, password, &connect_status, ex)) {
/* The user cancelled the connection attempt. */
- camel_exception_set (ex, CAMEL_EXCEPTION_USER_CANCEL,
- "Cancelled");
- camel_object_unref (exch->stub);
- exch->stub = NULL;
+ if (!camel_exception_is_set (ex))
+ camel_exception_set (ex, CAMEL_EXCEPTION_USER_CANCEL, "Cancelled");
g_mutex_unlock (exch->connect_lock);
return FALSE;
}
@@ -440,16 +388,10 @@ exchange_connect (CamelService *service, CamelException *ex)
camel_exception_set (ex, CAMEL_EXCEPTION_SYSTEM,
_("Could not authenticate to server. "
"(Password incorrect?)\n\n"));
- camel_object_unref (exch->stub);
- exch->stub = NULL;
g_mutex_unlock (exch->connect_lock);
return FALSE;
- } else {
- exch->stub_connected = TRUE;
}
- g_hash_table_foreach (exch->folders, update_camel_stub, exch->stub);
-
g_mutex_unlock (exch->connect_lock);
return TRUE;
@@ -458,13 +400,8 @@ exchange_connect (CamelService *service, CamelException *ex)
static gboolean
exchange_disconnect (CamelService *service, gboolean clean, CamelException *ex)
{
-
- CamelExchangeStore *exch = CAMEL_EXCHANGE_STORE (service);
-
- if (exch->stub) {
- exch->stub = NULL;
- }
-
+ /* CamelExchangeStore *exch = CAMEL_EXCHANGE_STORE (service); */
+ /* keep account connect as it can be used for other parts like cal, gal or addressbook? */
return TRUE;
}
@@ -514,7 +451,7 @@ exchange_get_folder (CamelStore *store, const gchar *folder_name,
if (!camel_exchange_folder_construct (folder, store, folder_name,
flags, folder_dir, ((CamelOfflineStore *) store)->state,
- exch->stub, ex)) {
+ ex)) {
gchar *key;
g_mutex_lock (exch->folders_lock);
if (g_hash_table_lookup_extended (exch->folders, folder_name,
@@ -541,23 +478,18 @@ exchange_get_folder (CamelStore *store, const gchar *folder_name,
static gboolean
exchange_folder_subscribed (CamelStore *store, const gchar *folder_name)
{
- CamelExchangeStore *exch = CAMEL_EXCHANGE_STORE (store);
- guint32 is_subscribed;
+ gboolean is_subscribed = FALSE;
d(printf ("is subscribed folder : %s\n", folder_name));
if (((CamelOfflineStore *) store)->state == CAMEL_OFFLINE_STORE_NETWORK_UNAVAIL) {
return FALSE;
}
- if (!camel_stub_send (exch->stub, NULL, CAMEL_STUB_CMD_IS_SUBSCRIBED_FOLDER,
- CAMEL_STUB_ARG_FOLDER, folder_name,
- CAMEL_STUB_ARG_RETURN,
- CAMEL_STUB_ARG_UINT32, &is_subscribed,
- CAMEL_STUB_ARG_END)) {
+ if (!camel_exchange_utils_is_subscribed_folder (CAMEL_SERVICE (store), folder_name, &is_subscribed, NULL)) {
return FALSE;
}
- return is_subscribed ? TRUE : FALSE;
+ return is_subscribed;
}
static void
@@ -572,9 +504,7 @@ exchange_subscribe_folder (CamelStore *store, const gchar *folder_name,
return;
}
- camel_stub_send (exch->stub, ex, CAMEL_STUB_CMD_SUBSCRIBE_FOLDER,
- CAMEL_STUB_ARG_FOLDER, folder_name,
- CAMEL_STUB_ARG_END);
+ camel_exchange_utils_subscribe_folder (CAMEL_SERVICE (store), folder_name, ex);
}
static void
@@ -589,9 +519,7 @@ exchange_unsubscribe_folder (CamelStore *store, const gchar *folder_name,
return;
}
- camel_stub_send (exch->stub, ex, CAMEL_STUB_CMD_UNSUBSCRIBE_FOLDER,
- CAMEL_STUB_ARG_FOLDER, folder_name,
- CAMEL_STUB_ARG_END);
+ camel_exchange_utils_unsubscribe_folder (CAMEL_SERVICE (store), folder_name, ex);
}
static CamelFolder *
@@ -602,10 +530,7 @@ get_trash (CamelStore *store, CamelException *ex)
RETURN_VAL_IF_NOT_CONNECTED (exch, ex, NULL);
if (!exch->trash_name) {
- if (!camel_stub_send (exch->stub, ex, CAMEL_STUB_CMD_GET_TRASH_NAME,
- CAMEL_STUB_ARG_RETURN,
- CAMEL_STUB_ARG_STRING, &exch->trash_name,
- CAMEL_STUB_ARG_END))
+ if (!camel_exchange_utils_get_trash_name (CAMEL_SERVICE (store), &exch->trash_name, ex))
return NULL;
}
@@ -614,7 +539,7 @@ get_trash (CamelStore *store, CamelException *ex)
/* Note: steals @name and @uri */
static CamelFolderInfo *
-make_folder_info (CamelExchangeStore *exch, gchar *name, gchar *uri,
+make_folder_info (CamelExchangeStore *exch, gchar *name, const gchar *uri,
gint unread_count, gint flags)
{
CamelFolderInfo *info;
@@ -657,27 +582,27 @@ make_folder_info (CamelExchangeStore *exch, gchar *name, gchar *uri,
}
info->unread = unread_count;
- if (flags & CAMEL_STUB_FOLDER_NOSELECT)
+ if (flags & CAMEL_FOLDER_NOSELECT)
info->flags = CAMEL_FOLDER_NOSELECT;
- if (flags & CAMEL_STUB_FOLDER_SYSTEM)
+ if (flags & CAMEL_FOLDER_SYSTEM)
info->flags |= CAMEL_FOLDER_SYSTEM;
- if (flags & CAMEL_STUB_FOLDER_TYPE_INBOX)
+ if (flags & CAMEL_FOLDER_TYPE_INBOX)
info->flags |= CAMEL_FOLDER_TYPE_INBOX;
- if (flags & CAMEL_STUB_FOLDER_TYPE_TRASH)
+ if (flags & CAMEL_FOLDER_TYPE_TRASH)
info->flags |= CAMEL_FOLDER_TYPE_TRASH;
- if (flags & CAMEL_STUB_FOLDER_TYPE_SENT)
+ if (flags & CAMEL_FOLDER_TYPE_SENT)
info->flags |= CAMEL_FOLDER_TYPE_SENT;
- if (flags & CAMEL_STUB_FOLDER_SUBSCRIBED) {
+ if (flags & CAMEL_FOLDER_SUBSCRIBED) {
info->flags |= CAMEL_FOLDER_SUBSCRIBED;
d(printf ("MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMmark as subscribed\n"));
}
- if (flags & CAMEL_STUB_FOLDER_NOCHILDREN)
+ if (flags & CAMEL_FOLDER_NOCHILDREN)
info->flags |= CAMEL_FOLDER_NOCHILDREN;
return info;
}
@@ -713,9 +638,9 @@ static CamelFolderInfo *
exchange_get_folder_info (CamelStore *store, const gchar *top, guint32 flags, CamelException *ex)
{
CamelExchangeStore *exch = CAMEL_EXCHANGE_STORE (store);
- GPtrArray *folders, *folder_names, *folder_uris;
- GArray *unread_counts;
- GArray *folder_flags;
+ GPtrArray *folders, *folder_names = NULL, *folder_uris = NULL;
+ GArray *unread_counts = NULL;
+ GArray *folder_flags = NULL;
CamelFolderInfo *info;
guint32 store_flags = 0;
gint i;
@@ -732,25 +657,14 @@ exchange_get_folder_info (CamelStore *store, const gchar *top, guint32 flags, Ca
RETURN_VAL_IF_NOT_CONNECTED (exch, ex, NULL);
- if (camel_stub_marshal_eof (exch->stub->cmd))
- return NULL;
-
if (flags & CAMEL_STORE_FOLDER_INFO_RECURSIVE)
- store_flags |= CAMEL_STUB_STORE_FOLDER_INFO_RECURSIVE;
+ store_flags |= CAMEL_STORE_FOLDER_INFO_RECURSIVE;
if (flags & CAMEL_STORE_FOLDER_INFO_SUBSCRIBED)
- store_flags |= CAMEL_STUB_STORE_FOLDER_INFO_SUBSCRIBED;
+ store_flags |= CAMEL_STORE_FOLDER_INFO_SUBSCRIBED;
if (flags & CAMEL_STORE_FOLDER_INFO_SUBSCRIPTION_LIST)
- store_flags |= CAMEL_STUB_STORE_FOLDER_INFO_SUBSCRIPTION_LIST;
-
- if (!camel_stub_send (exch->stub, ex, CAMEL_STUB_CMD_GET_FOLDER_INFO,
- CAMEL_STUB_ARG_STRING, top,
- CAMEL_STUB_ARG_UINT32, store_flags,
- CAMEL_STUB_ARG_RETURN,
- CAMEL_STUB_ARG_STRINGARRAY, &folder_names,
- CAMEL_STUB_ARG_STRINGARRAY, &folder_uris,
- CAMEL_STUB_ARG_UINT32ARRAY, &unread_counts,
- CAMEL_STUB_ARG_UINT32ARRAY, &folder_flags,
- CAMEL_STUB_ARG_END)) {
+ store_flags |= CAMEL_STORE_FOLDER_INFO_SUBSCRIPTION_LIST;
+
+ if (!camel_exchange_utils_get_folder_info (CAMEL_SERVICE (store), top, store_flags, &folder_names, &folder_uris, &unread_counts, &folder_flags, ex)) {
return NULL;
}
if (!folder_names) {
@@ -771,6 +685,7 @@ exchange_get_folder_info (CamelStore *store, const gchar *top, guint32 flags, Ca
g_ptr_array_add (folders, info);
}
g_ptr_array_free (folder_names, TRUE);
+ g_ptr_array_foreach (folder_uris, (GFunc) g_free, NULL);
g_ptr_array_free (folder_uris, TRUE);
g_array_free (unread_counts, TRUE);
g_array_free (folder_flags, TRUE);
@@ -798,19 +713,15 @@ exchange_create_folder (CamelStore *store, const gchar *parent_name,
return NULL;
}
- if (!camel_stub_send (exch->stub, ex, CAMEL_STUB_CMD_CREATE_FOLDER,
- CAMEL_STUB_ARG_FOLDER, parent_name,
- CAMEL_STUB_ARG_STRING, folder_name,
- CAMEL_STUB_ARG_RETURN,
- CAMEL_STUB_ARG_STRING, &folder_uri,
- CAMEL_STUB_ARG_UINT32, &unread_count,
- CAMEL_STUB_ARG_UINT32, &flags,
- CAMEL_STUB_ARG_END))
+ if (!camel_exchange_utils_create_folder (CAMEL_SERVICE (store), parent_name, folder_name, &folder_uri, &unread_count, &flags, ex))
return NULL;
info = make_folder_info (exch, g_strdup (folder_name),
folder_uri, unread_count, flags);
info->flags |= CAMEL_FOLDER_NOCHILDREN;
+
+ g_free (folder_uri);
+
return info;
}
@@ -825,9 +736,7 @@ exchange_delete_folder (CamelStore *store, const gchar *folder_name,
return;
}
- camel_stub_send (exch->stub, ex, CAMEL_STUB_CMD_DELETE_FOLDER,
- CAMEL_STUB_ARG_FOLDER, folder_name,
- CAMEL_STUB_ARG_END);
+ camel_exchange_utils_delete_folder (CAMEL_SERVICE (store), folder_name, ex);
}
static void
@@ -848,15 +757,7 @@ exchange_rename_folder (CamelStore *store, const gchar *old_name,
camel_exception_set (ex, CAMEL_EXCEPTION_SYSTEM, _("Cannot rename folder in offline mode."));
return;
}
- if (!camel_stub_send (exch->stub, ex, CAMEL_STUB_CMD_RENAME_FOLDER,
- CAMEL_STUB_ARG_STRING, old_name,
- CAMEL_STUB_ARG_STRING, new_name,
- CAMEL_STUB_ARG_RETURN,
- CAMEL_STUB_ARG_STRINGARRAY, &folder_names,
- CAMEL_STUB_ARG_STRINGARRAY, &folder_uris,
- CAMEL_STUB_ARG_UINT32ARRAY, &unread_counts,
- CAMEL_STUB_ARG_UINT32ARRAY, &folder_flags,
- CAMEL_STUB_ARG_END)) {
+ if (!camel_exchange_utils_rename_folder (CAMEL_SERVICE (store), old_name, new_name, &folder_names, &folder_uris, &unread_counts, &folder_flags, ex)) {
return;
}
@@ -878,6 +779,7 @@ exchange_rename_folder (CamelStore *store, const gchar *old_name,
g_ptr_array_add (folders, info);
}
g_ptr_array_free (folder_names, TRUE);
+ g_ptr_array_foreach (folder_uris, (GFunc) g_free, NULL);
g_ptr_array_free (folder_uris, TRUE);
g_array_free (unread_counts, TRUE);
g_array_free (folder_flags, TRUE);
@@ -905,291 +807,53 @@ exchange_rename_folder (CamelStore *store, const gchar *old_name,
}
-static void
-stub_notification (CamelObject *object, gpointer event_data, gpointer user_data)
+static gboolean
+exchange_can_refresh_folder (CamelStore *store, CamelFolderInfo *info, CamelException *ex)
{
- CamelStub *stub = CAMEL_STUB (object);
- CamelExchangeStore *exch = CAMEL_EXCHANGE_STORE (user_data);
- guint32 retval = GPOINTER_TO_UINT (event_data);
-
- switch (retval) {
- case CAMEL_STUB_RETVAL_NEW_MESSAGE:
- {
- CamelExchangeFolder *folder;
- gchar *folder_name, *uid, *headers, *href;
- guint32 flags, size;
-
- if (camel_stub_marshal_decode_folder (stub->status, &folder_name) == -1 ||
- camel_stub_marshal_decode_string (stub->status, &uid) == -1 ||
- camel_stub_marshal_decode_uint32 (stub->status, &flags) == -1 ||
- camel_stub_marshal_decode_uint32 (stub->status, &size) == -1 ||
- camel_stub_marshal_decode_string (stub->status, &headers) == -1 ||
- camel_stub_marshal_decode_string (stub->status, &href) == -1)
- return;
-
- g_mutex_lock (exch->folders_lock);
- folder = g_hash_table_lookup (exch->folders, folder_name);
- g_mutex_unlock (exch->folders_lock);
- if (folder) {
- camel_exchange_folder_add_message (folder, uid, flags,
- size, headers, href);
- }
-
- g_free (folder_name);
- g_free (uid);
- g_free (headers);
- g_free (href);
- break;
- }
-
- case CAMEL_STUB_RETVAL_REMOVED_MESSAGE:
- {
- CamelExchangeFolder *folder;
- gchar *folder_name, *uid;
- CamelMessageInfo *info;
-
- if (camel_stub_marshal_decode_folder (stub->status, &folder_name) == -1 ||
- camel_stub_marshal_decode_string (stub->status, &uid) == -1)
- return;
-
- g_mutex_lock (exch->folders_lock);
- folder = g_hash_table_lookup (exch->folders, folder_name);
- g_mutex_unlock (exch->folders_lock);
- if (folder && (info = camel_folder_summary_uid (((CamelFolder *)folder)->summary, uid))) {
- camel_message_info_free (info);
- camel_exchange_folder_remove_message (folder, uid);
- }
-
- g_free (folder_name);
- g_free (uid);
- break;
- }
-
- case CAMEL_STUB_RETVAL_CHANGED_MESSAGE:
- {
- CamelExchangeFolder *folder;
- gchar *folder_name, *uid;
-
- if (camel_stub_marshal_decode_folder (stub->status, &folder_name) == -1 ||
- camel_stub_marshal_decode_string (stub->status, &uid) == -1)
- break;
-
- g_mutex_lock (exch->folders_lock);
- folder = g_hash_table_lookup (exch->folders, folder_name);
- g_mutex_unlock (exch->folders_lock);
- if (folder)
- camel_exchange_folder_uncache_message (folder, uid);
-
- g_free (folder_name);
- g_free (uid);
- break;
- }
-
- case CAMEL_STUB_RETVAL_CHANGED_FLAGS:
- {
- CamelExchangeFolder *folder;
- gchar *folder_name, *uid;
- guint32 flags;
-
- if (camel_stub_marshal_decode_folder (stub->status, &folder_name) == -1 ||
- camel_stub_marshal_decode_string (stub->status, &uid) == -1 ||
- camel_stub_marshal_decode_uint32 (stub->status, &flags) == -1)
- break;
-
- g_mutex_lock (exch->folders_lock);
- folder = g_hash_table_lookup (exch->folders, folder_name);
- g_mutex_unlock (exch->folders_lock);
- if (folder)
- camel_exchange_folder_update_message_flags (folder, uid, flags);
-
- g_free (folder_name);
- g_free (uid);
- break;
- }
-
- case CAMEL_STUB_RETVAL_CHANGED_FLAGS_EX:
- {
- CamelExchangeFolder *folder;
- gchar *folder_name, *uid;
- guint32 flags;
- guint32 mask;
-
- if (camel_stub_marshal_decode_folder (stub->status, &folder_name) == -1 ||
- camel_stub_marshal_decode_string (stub->status, &uid) == -1 ||
- camel_stub_marshal_decode_uint32 (stub->status, &flags) == -1 ||
- camel_stub_marshal_decode_uint32 (stub->status, &mask) == -1)
- break;
-
- g_mutex_lock (exch->folders_lock);
- folder = g_hash_table_lookup (exch->folders, folder_name);
- g_mutex_unlock (exch->folders_lock);
- if (folder)
- camel_exchange_folder_update_message_flags_ex (folder, uid,
- flags, mask);
-
- g_free (folder_name);
- g_free (uid);
- break;
- }
-
- case CAMEL_STUB_RETVAL_CHANGED_TAG:
- {
- CamelExchangeFolder *folder;
- gchar *folder_name, *uid, *name, *value;
-
- if (camel_stub_marshal_decode_folder (stub->status, &folder_name) == -1 ||
- camel_stub_marshal_decode_string (stub->status, &uid) == -1 ||
- camel_stub_marshal_decode_string (stub->status, &name) == -1 ||
- camel_stub_marshal_decode_string (stub->status, &value) == -1)
- break;
-
- g_mutex_lock (exch->folders_lock);
- folder = g_hash_table_lookup (exch->folders, folder_name);
- g_mutex_unlock (exch->folders_lock);
- if (folder)
- camel_exchange_folder_update_message_tag (folder, uid, name, value);
-
- g_free (folder_name);
- g_free (uid);
- g_free (name);
- g_free (value);
- break;
- }
-
- case CAMEL_STUB_RETVAL_FREEZE_FOLDER:
- {
- CamelFolder *folder;
- gchar *folder_name;
-
- if (camel_stub_marshal_decode_folder (stub->status, &folder_name) == -1)
- break;
-
- g_mutex_lock (exch->folders_lock);
- folder = g_hash_table_lookup (exch->folders, folder_name);
- g_mutex_unlock (exch->folders_lock);
- if (folder)
- camel_folder_freeze (folder);
-
- g_free (folder_name);
- break;
- }
-
- case CAMEL_STUB_RETVAL_THAW_FOLDER:
- {
- CamelFolder *folder;
- gchar *folder_name;
-
- if (camel_stub_marshal_decode_folder (stub->status, &folder_name) == -1)
- break;
-
- g_mutex_lock (exch->folders_lock);
- folder = g_hash_table_lookup (exch->folders, folder_name);
- g_mutex_unlock (exch->folders_lock);
- if (folder)
- camel_folder_thaw (folder);
-
- g_free (folder_name);
- break;
- }
-
- case CAMEL_STUB_RETVAL_FOLDER_CREATED:
- {
- CamelFolderInfo *info;
- gchar *name, *uri;
-
- if (camel_stub_marshal_decode_string (stub->status, &name) == -1 ||
- camel_stub_marshal_decode_string (stub->status, &uri) == -1)
- break;
-
- info = make_folder_info (exch, name, uri, -1, 0);
- info->flags |= CAMEL_FOLDER_NOCHILDREN;
- camel_object_trigger_event (CAMEL_OBJECT (exch),
- "folder_subscribed", info);
- camel_folder_info_free (info);
- break;
- }
-
- case CAMEL_STUB_RETVAL_FOLDER_DELETED:
- {
- CamelFolderInfo *info;
- CamelFolder *folder;
- gchar *name, *uri;
-
- if (camel_stub_marshal_decode_string (stub->status, &name) == -1 ||
- camel_stub_marshal_decode_string (stub->status, &uri) == -1)
- break;
-
- info = make_folder_info (exch, name, uri, -1, 0);
+ gboolean res;
- g_mutex_lock (exch->folders_lock);
- folder = g_hash_table_lookup (exch->folders, info->full_name);
- if (folder) {
- g_hash_table_remove (exch->folders, info->full_name);
- camel_object_unref (CAMEL_OBJECT (folder));
- }
- g_mutex_unlock (exch->folders_lock);
+ res = CAMEL_STORE_CLASS(parent_class)->can_refresh_folder (store, info, ex) ||
+ (camel_url_get_param (((CamelService *)store)->url, "check_all") != NULL);
- camel_object_trigger_event (CAMEL_OBJECT (exch),
- "folder_unsubscribed", info);
- camel_folder_info_free (info);
- break;
- }
+ return res;
+}
- case CAMEL_STUB_RETVAL_FOLDER_SET_READONLY:
- {
- CamelFolder *folder;
- gchar *folder_name;
- guint32 readonly;
+void
+camel_exchange_store_folder_created (CamelExchangeStore *estore, const gchar *name, const gchar *uri)
+{
+ CamelFolderInfo *info;
- if (camel_stub_marshal_decode_folder (stub->status, &folder_name) == -1 ||
- camel_stub_marshal_decode_uint32 (stub->status, &readonly) == -1)
- break;
+ g_return_if_fail (estore != NULL);
+ g_return_if_fail (CAMEL_IS_EXCHANGE_STORE (estore));
- g_mutex_lock (exch->folders_lock);
- folder = g_hash_table_lookup (exch->folders, folder_name);
- g_mutex_unlock (exch->folders_lock);
- if (folder) {
- camel_exchange_summary_set_readonly (folder->summary, readonly ? TRUE : FALSE);
- }
+ info = make_folder_info (estore, g_strdup (name), uri, -1, 0);
+ info->flags |= CAMEL_FOLDER_NOCHILDREN;
- g_free (folder_name);
- break;
- }
+ camel_object_trigger_event (CAMEL_OBJECT (estore), "folder_subscribed", info);
- case CAMEL_STUB_RETVAL_FOLDER_SET_ARTICLE_NUM:
- {
- CamelFolder *folder;
- gchar *folder_name;
- guint32 high_article_num;
+ camel_folder_info_free (info);
+}
- if (camel_stub_marshal_decode_folder (stub->status, &folder_name) == -1 ||
- camel_stub_marshal_decode_uint32 (stub->status, &high_article_num) == -1)
- break;
+void
+camel_exchange_store_folder_deleted (CamelExchangeStore *estore, const gchar *name, const gchar *uri)
+{
+ CamelFolderInfo *info;
+ CamelFolder *folder;
- g_mutex_lock (exch->folders_lock);
- folder = g_hash_table_lookup (exch->folders, folder_name);
- g_mutex_unlock (exch->folders_lock);
- if (folder) {
- camel_exchange_summary_set_article_num (folder->summary, high_article_num);
- }
+ g_return_if_fail (estore != NULL);
+ g_return_if_fail (CAMEL_IS_EXCHANGE_STORE (estore));
- g_free (folder_name);
- break;
- }
+ info = make_folder_info (estore, g_strdup (name), uri, -1, 0);
- default:
- g_critical ("%s: Uncaught case (%d)", G_STRLOC, retval);
- break;
+ g_mutex_lock (estore->folders_lock);
+ folder = g_hash_table_lookup (estore->folders, info->full_name);
+ if (folder) {
+ g_hash_table_remove (estore->folders, info->full_name);
+ camel_object_unref (CAMEL_OBJECT (folder));
}
-}
+ g_mutex_unlock (estore->folders_lock);
-static gboolean
-exchange_can_refresh_folder (CamelStore *store, CamelFolderInfo *info, CamelException *ex)
-{
- gboolean res;
-
- res = CAMEL_STORE_CLASS(parent_class)->can_refresh_folder (store, info, ex) ||
- (camel_url_get_param (((CamelService *)store)->url, "check_all") != NULL);
+ camel_object_trigger_event (CAMEL_OBJECT (estore), "folder_unsubscribed", info);
- return res;
+ camel_folder_info_free (info);
}
diff --git a/camel/camel-exchange-store.h b/camel/camel-exchange-store.h
index 5aeae45..d634fb0 100644
--- a/camel/camel-exchange-store.h
+++ b/camel/camel-exchange-store.h
@@ -10,7 +10,6 @@ G_BEGIN_DECLS
#include <camel/camel-store.h>
#include <camel/camel-offline-store.h>
-#include "camel-stub.h"
#define CAMEL_EXCHANGE_STORE_TYPE (camel_exchange_store_get_type ())
#define CAMEL_EXCHANGE_STORE(obj) (CAMEL_CHECK_CAST((obj), CAMEL_EXCHANGE_STORE_TYPE, CamelExchangeStore))
@@ -20,13 +19,11 @@ G_BEGIN_DECLS
typedef struct {
CamelOfflineStore parent_object;
- CamelStub *stub;
gchar *storage_path, *base_url;
gchar *trash_name;
GHashTable *folders;
GMutex *folders_lock;
- gboolean stub_connected;
GMutex *connect_lock;
} CamelExchangeStore;
@@ -41,6 +38,9 @@ CamelType camel_exchange_store_get_type (void);
gboolean camel_exchange_store_connected (CamelExchangeStore *store, CamelException *ex);
+void camel_exchange_store_folder_created (CamelExchangeStore *estore, const gchar *name, const gchar *uri);
+void camel_exchange_store_folder_deleted (CamelExchangeStore *estore, const gchar *name, const gchar *uri);
+
G_END_DECLS
#endif /* CAMEL_EXCHANGE_STORE_H */
diff --git a/camel/camel-exchange-summary.c b/camel/camel-exchange-summary.c
index 0924e29..8d7a15f 100644
--- a/camel/camel-exchange-summary.c
+++ b/camel/camel-exchange-summary.c
@@ -32,10 +32,10 @@
#include <camel/camel-offline-store.h>
#include <camel/camel-string-utils.h>
-#include "camel-stub.h"
#include "camel-exchange-folder.h"
#include "camel-exchange-journal.h"
#include "camel-exchange-summary.h"
+#include "camel-exchange-utils.h"
#define CAMEL_EXCHANGE_SUMMARY_VERSION (2)
@@ -389,7 +389,6 @@ check_for_trash (CamelFolder *folder)
static gboolean
expunge_mail (CamelFolder *folder, CamelMessageInfo *info)
{
- CamelExchangeFolder *exchange_folder = (CamelExchangeFolder *) folder;
GPtrArray *uids = g_ptr_array_new ();
gchar *uid = g_strdup (info->uid);
CamelException lex;
@@ -397,11 +396,7 @@ expunge_mail (CamelFolder *folder, CamelMessageInfo *info)
g_ptr_array_add (uids, uid);
camel_exception_init (&lex);
- camel_stub_send (exchange_folder->stub, &lex,
- CAMEL_STUB_CMD_EXPUNGE_UIDS,
- CAMEL_STUB_ARG_FOLDER, folder->full_name,
- CAMEL_STUB_ARG_STRINGARRAY, uids,
- CAMEL_STUB_ARG_END);
+ camel_exchange_utils_expunge_uids (CAMEL_SERVICE (folder->parent_store), folder->full_name, uids, &lex);
g_ptr_array_free (uids, TRUE);
return camel_exception_is_set (&lex);
@@ -422,13 +417,7 @@ info_set_flags(CamelMessageInfo *info, guint32 flags, guint32 set)
check_for_trash (folder)) {
return expunge_mail (folder, info);
} else {
- camel_stub_send_oneway (((CamelExchangeFolder *)folder)->stub,
- CAMEL_STUB_CMD_SET_MESSAGE_FLAGS,
- CAMEL_STUB_ARG_FOLDER, folder->full_name,
- CAMEL_STUB_ARG_STRING, info->uid,
- CAMEL_STUB_ARG_UINT32, set,
- CAMEL_STUB_ARG_UINT32, flags,
- CAMEL_STUB_ARG_END);
+ camel_exchange_utils_set_message_flags (CAMEL_SERVICE (folder->parent_store), folder->full_name, info->uid, set, flags, NULL);
return CAMEL_FOLDER_SUMMARY_CLASS (parent_class)->info_set_flags(info, flags, set);
}
}
@@ -459,13 +448,8 @@ info_set_user_tag(CamelMessageInfo *info, const gchar *name, const gchar *value)
res = CAMEL_FOLDER_SUMMARY_CLASS (parent_class)->info_set_user_tag(info, name, value);
if (res && info->summary->folder && info->uid) {
- camel_stub_send_oneway (((CamelExchangeFolder *)info->summary->folder)->stub,
- CAMEL_STUB_CMD_SET_MESSAGE_TAG,
- CAMEL_STUB_ARG_FOLDER, info->summary->folder->full_name,
- CAMEL_STUB_ARG_STRING, info->uid,
- CAMEL_STUB_ARG_STRING, name,
- CAMEL_STUB_ARG_STRING, value,
- CAMEL_STUB_ARG_END);
+ CamelFolder *folder = info->summary->folder;
+ camel_exchange_utils_set_message_tag (CAMEL_SERVICE (folder->parent_store), folder->full_name, info->uid, name, value, NULL);
}
return res;
@@ -568,7 +552,7 @@ camel_exchange_summary_add_offline (CamelFolderSummary *summary,
const CamelTag *tag;
/* Create summary entry */
- mi = (CamelMessageInfoBase *)camel_folder_summary_info_new_from_message (summary, message);
+ mi = (CamelMessageInfoBase *)camel_folder_summary_info_new_from_message (summary, message, NULL);
/* Copy flags 'n' tags */
mi->flags = camel_message_info_flags(info);
diff --git a/camel/camel-exchange-transport.c b/camel/camel-exchange-transport.c
index cf33bba..2403b7e 100644
--- a/camel/camel-exchange-transport.c
+++ b/camel/camel-exchange-transport.c
@@ -26,7 +26,7 @@
#include <glib/gi18n-lib.h>
#include "camel-exchange-transport.h"
-#include "camel-stub.h"
+#include "camel-exchange-utils.h"
#include <camel/camel-data-wrapper.h>
#include <camel/camel-exception.h>
@@ -38,8 +38,6 @@
#include <string.h>
-extern CamelStub *das_global_camel_stub;
-
static gboolean exchange_send_to (CamelTransport *transport,
CamelMimeMessage *message,
CamelAddress *from,
@@ -111,6 +109,8 @@ exchange_send_to (CamelTransport *transport, CamelMimeMessage *message,
return FALSE;
}
+ g_free (url_string);
+
recipients_array = g_ptr_array_new ();
len = camel_address_length (recipients);
cia = CAMEL_INTERNET_ADDRESS (recipients);
@@ -119,7 +119,6 @@ exchange_send_to (CamelTransport *transport, CamelMimeMessage *message,
camel_exception_set (ex, CAMEL_EXCEPTION_SYSTEM,
_("Cannot send message: one or more invalid recipients"));
g_ptr_array_free (recipients_array, TRUE);
- g_free (url_string);
return FALSE;
}
g_ptr_array_add (recipients_array, (gchar *)addr);
@@ -129,21 +128,9 @@ exchange_send_to (CamelTransport *transport, CamelMimeMessage *message,
camel_exception_set (ex, CAMEL_EXCEPTION_SERVICE_UNAVAILABLE,
_("Could not find 'From' address in message"));
g_ptr_array_free (recipients_array, TRUE);
- g_free (url_string);
return FALSE;
}
- if (!das_global_camel_stub) {
- store = camel_session_get_store (service->session, url_string, ex);
- if (!store) {
- g_ptr_array_free (recipients_array, TRUE);
- g_free (url_string);
- return FALSE;
- }
- g_return_val_if_fail (das_global_camel_stub, FALSE);
- }
- g_free (url_string);
-
stream = camel_stream_mem_new ();
crlffilter = camel_mime_filter_crlf_new (CAMEL_MIME_FILTER_CRLF_ENCODE, CAMEL_MIME_FILTER_CRLF_MODE_CRLF_ONLY);
filtered_stream = camel_stream_filter_new_with_stream (stream);
@@ -177,12 +164,7 @@ exchange_send_to (CamelTransport *transport, CamelMimeMessage *message,
g_slist_free (bcc);
}
- success = camel_stub_send (das_global_camel_stub, ex,
- CAMEL_STUB_CMD_SEND_MESSAGE,
- CAMEL_STUB_ARG_STRING, addr,
- CAMEL_STUB_ARG_STRINGARRAY, recipients_array,
- CAMEL_STUB_ARG_BYTEARRAY, CAMEL_STREAM_MEM (stream)->buffer,
- CAMEL_STUB_ARG_END);
+ success = camel_exchange_utils_send_message (CAMEL_SERVICE (transport), addr, recipients_array, CAMEL_STREAM_MEM (stream)->buffer, ex);
g_ptr_array_free (recipients_array, TRUE);
camel_object_unref (CAMEL_OBJECT (stream));
diff --git a/mail/mail-stub-exchange.c b/camel/camel-exchange-utils.c
similarity index 54%
rename from mail/mail-stub-exchange.c
rename to camel/camel-exchange-utils.c
index 6a5906a..e8b5253 100644
--- a/mail/mail-stub-exchange.c
+++ b/camel/camel-exchange-utils.c
@@ -17,60 +17,72 @@
* Boston, MA 02111-1307, USA.
*/
-/* mail-stub-exchange.c: an Exchange implementation of MailStub */
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include "mail-stub-exchange.h"
-#include "mail-utils.h"
-
#include <ctype.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <exchange-constants.h>
+#include <exchange-account.h>
#include <e-folder-exchange.h>
-#include "camel-stub-constants.h"
#include <e2k-propnames.h>
#include <e2k-restriction.h>
#include <e2k-uri.h>
#include <e2k-utils.h>
-#include "exchange-component.h" // for using global_exchange_component
-#include "exchange-config-listener.h"
#include <exchange-hierarchy.h>
#include <mapi.h>
+#include <camel/camel-folder.h>
+#include <camel/camel-service.h>
+#include <camel/camel-session.h>
+#include <camel/camel-store.h>
+
+#include "camel-exchange-folder.h"
+#include "camel-exchange-store.h"
+#include "camel-exchange-summary.h"
+#include "camel-exchange-utils.h"
+#include "mail-utils.h"
+
+#include "tools/exchange-share-config-listener.h"
+
#define d(x)
-#define PARENT_TYPE MAIL_TYPE_STUB
-static MailStubClass *parent_class = NULL;
+typedef struct {
+ /* the first two are set immediately, the rest after connect */
+ CamelExchangeStore *estore;
+ ExchangeAccount *account;
+ GHashTable *folders_by_name;
+
+ E2kContext *ctx;
+ const gchar *mail_submission_uri;
+ EFolder *inbox, *deleted_items, *sent_items;
-/* FIXME : Have this as part of the appropriate class in 2.5 */
-/* static gulong offline_listener_handler_id; */
+ GStaticRecMutex changed_msgs_mutex;
+
+ guint new_folder_id, removed_folder_id;
+ const gchar *ignore_new_folder, *ignore_removed_folder;
+} ExchangeData;
typedef struct {
gchar *uid, *href;
guint32 seq, flags;
guint32 change_flags, change_mask;
GData *tag_updates;
-} MailStubExchangeMessage;
+} ExchangeMessage;
typedef enum {
- MAIL_STUB_EXCHANGE_FOLDER_REAL,
- MAIL_STUB_EXCHANGE_FOLDER_POST,
- MAIL_STUB_EXCHANGE_FOLDER_NOTES,
- MAIL_STUB_EXCHANGE_FOLDER_OTHER
-} MailStubExchangeFolderType;
+ EXCHANGE_FOLDER_REAL,
+ EXCHANGE_FOLDER_POST,
+ EXCHANGE_FOLDER_NOTES,
+ EXCHANGE_FOLDER_OTHER
+} ExchangeFolderType;
typedef struct {
- MailStubExchange *mse;
+ ExchangeData *ed;
EFolder *folder;
const gchar *name;
- MailStubExchangeFolderType type;
+ ExchangeFolderType type;
guint32 access;
GPtrArray *messages;
@@ -85,227 +97,160 @@ typedef struct {
time_t last_activity;
guint sync_deletion_timeout;
-} MailStubExchangeFolder;
-
-static void dispose (GObject *);
-
-static void stub_connect (MailStub *stub, gchar *pwd);
-static void get_folder (MailStub *stub, const gchar *name, gboolean create,
- GPtrArray *uids, GByteArray *flags, GPtrArray *hrefs, guint32 high_article_num);
-static void get_trash_name (MailStub *stub);
-static void sync_folder (MailStub *stub, const gchar *folder_name);
-static void refresh_folder (MailStub *stub, const gchar *folder_name);
-static void sync_count (MailStub *stub, const gchar *folder_name);
-static void refresh_folder_internal (MailStub *stub, MailStubExchangeFolder *mfld,
- gboolean background);
-static gboolean sync_deletions (MailStubExchange *mse, MailStubExchangeFolder *mfld);
-static void expunge_uids (MailStub *stub, const gchar *folder_name, GPtrArray *uids);
-static void append_message (MailStub *stub, const gchar *folder_name, guint32 flags,
- const gchar *subject, const gchar *data, gint length);
-static void set_message_flags (MailStub *, const gchar *folder_name,
- const gchar *uid, guint32 flags, guint32 mask);
-static void set_message_tag (MailStub *, const gchar *folder_name,
- const gchar *uid, const gchar *name, const gchar *value);
-static void get_message (MailStub *stub, const gchar *folder_name, const gchar *uid);
-static void search (MailStub *stub, const gchar *folder_name, const gchar *text);
-static void transfer_messages (MailStub *stub, const gchar *source_name,
- const gchar *dest_name, GPtrArray *uids,
- gboolean delete_originals);
-static void get_folder_info (MailStub *stub, const gchar *top,
- guint32 store_flags);
-static void send_message (MailStub *stub, const gchar *from,
- GPtrArray *recipients,
- const gchar *data, gint length);
-static void create_folder (MailStub *, const gchar *parent_name,
- const gchar *folder_name);
-static void delete_folder (MailStub *, const gchar *folder_name);
-static void rename_folder (MailStub *, const gchar *old_name,
- const gchar *new_name);
-static void subscribe_folder (MailStub *, const gchar *folder_name);
-static void unsubscribe_folder (MailStub *, const gchar *folder_name);
-static void is_subscribed_folder (MailStub *, const gchar *folder_name);
-
-static gboolean process_flags (gpointer user_data);
-
-static void storage_folder_changed (EFolder *folder, gpointer user_data);
-
-/* static void linestatus_listener (ExchangeComponent *component,
- gint linestatus,
- gpointer data); */
-static void folder_update_linestatus (gpointer key, gpointer value, gpointer data);
-static void free_folder (gpointer value);
-static gboolean get_folder_online (MailStubExchangeFolder *mfld, gboolean background);
-static void get_folder_info_data (MailStub *stub, const gchar *top, guint32 store_flags,
- GPtrArray **names, GPtrArray **uris,
- GArray **unread, GArray **flags);
+} ExchangeFolder;
-static GStaticRecMutex g_changed_msgs_mutex = G_STATIC_REC_MUTEX_INIT;
-
-static void
-class_init (GObjectClass *object_class)
-{
- MailStubClass *stub_class = MAIL_STUB_CLASS (object_class);
-
- parent_class = g_type_class_ref (PARENT_TYPE);
-
- /* virtual method override */
- object_class->dispose = dispose;
-
- stub_class->connect = stub_connect;
- stub_class->get_folder = get_folder;
- stub_class->get_trash_name = get_trash_name;
- stub_class->sync_folder = sync_folder;
- stub_class->refresh_folder = refresh_folder;
- stub_class->sync_count = sync_count;
- stub_class->expunge_uids = expunge_uids;
- stub_class->append_message = append_message;
- stub_class->set_message_flags = set_message_flags;
- stub_class->set_message_tag = set_message_tag;
- stub_class->get_message = get_message;
- stub_class->search = search;
- stub_class->transfer_messages = transfer_messages;
- stub_class->get_folder_info = get_folder_info;
- stub_class->send_message = send_message;
- stub_class->create_folder = create_folder;
- stub_class->delete_folder = delete_folder;
- stub_class->rename_folder = rename_folder;
- stub_class->subscribe_folder = subscribe_folder;
- stub_class->unsubscribe_folder = unsubscribe_folder;
- stub_class->is_subscribed_folder = is_subscribed_folder;
-}
+static const gchar *mapi_message_props[] = {
+ E2K_PR_MAILHEADER_SUBJECT,
+ E2K_PR_MAILHEADER_FROM,
+ E2K_PR_MAILHEADER_TO,
+ E2K_PR_MAILHEADER_CC,
+ E2K_PR_MAILHEADER_DATE,
+ E2K_PR_MAILHEADER_RECEIVED,
+ E2K_PR_MAILHEADER_MESSAGE_ID,
+ E2K_PR_MAILHEADER_IN_REPLY_TO,
+ E2K_PR_MAILHEADER_REFERENCES,
+ E2K_PR_MAILHEADER_THREAD_INDEX,
+ E2K_PR_DAV_CONTENT_TYPE
+};
-static void
-init (GObject *object)
+static gboolean
+is_same_ed (CamelExchangeStore *estore, ExchangeAccount *eaccount, CamelService *service)
{
- MailStubExchange *mse = MAIL_STUB_EXCHANGE (object);
+ g_return_val_if_fail (eaccount != NULL, FALSE);
+ g_return_val_if_fail (service != NULL, FALSE);
+ g_return_val_if_fail (CAMEL_IS_SERVICE (service), FALSE);
- mse->folders_by_name = g_hash_table_new_full (g_str_hash, g_str_equal,
- NULL, free_folder);
-}
+ if (CAMEL_IS_EXCHANGE_STORE (service) && estore && estore == CAMEL_EXCHANGE_STORE (service))
+ return TRUE;
-static void
-free_message (MailStubExchangeMessage *mmsg)
-{
- g_datalist_clear (&mmsg->tag_updates);
- g_free (mmsg->uid);
- g_free (mmsg->href);
- g_free (mmsg);
-}
+ if (service->url) {
+ if (estore && camel_url_equal (CAMEL_SERVICE (estore)->url, service->url))
+ return TRUE;
-static void
-free_folder (gpointer value)
-{
- MailStubExchangeFolder *mfld = value;
- gint i;
+ if (eaccount) {
+ EAccount *account = exchange_account_fetch (eaccount);
- d(g_print ("%s:%s:%d: freeing mfld: name=[%s]\n", __FILE__, __PRETTY_FUNCTION__, __LINE__,
- mfld->name));
+ /* source url and transport url are same for exchange */
+ if (account && e_account_get_string (account, E_ACCOUNT_SOURCE_URL)) {
+ CamelURL *url = camel_url_new (e_account_get_string (account, E_ACCOUNT_SOURCE_URL), NULL);
- e_folder_exchange_unsubscribe (mfld->folder);
- g_signal_handlers_disconnect_by_func (mfld->folder, storage_folder_changed, mfld);
- g_object_unref (mfld->folder);
- mfld->folder = NULL;
+ if (url) {
+ CamelProvider *provider = camel_service_get_provider (service);
- for (i = 0; i < mfld->messages->len; i++)
- free_message (mfld->messages->pdata[i]);
- g_ptr_array_free (mfld->messages, TRUE);
- g_hash_table_destroy (mfld->messages_by_uid);
- g_hash_table_destroy (mfld->messages_by_href);
+ if ((provider && provider->url_equal && provider->url_equal (url, service->url))
+ || camel_url_equal (url, service->url)) {
+ camel_url_free (url);
+ return TRUE;
+ }
- g_ptr_array_free (mfld->changed_messages, TRUE);
- if (mfld->flag_timeout) {
- g_warning ("unreffing mse with unsynced flags");
- g_source_remove (mfld->flag_timeout);
+ camel_url_free (url);
+ }
+ }
+ }
}
- if (mfld->sync_deletion_timeout)
- g_source_remove (mfld->sync_deletion_timeout);
- g_free (mfld);
+
+ return FALSE;
}
-static void
-dispose (GObject *object)
+static void free_folder (gpointer value);
+
+static ExchangeData *
+get_data_for_service (CamelService *service)
{
- MailStubExchange *mse = MAIL_STUB_EXCHANGE (object);
+ static GSList *edies = NULL;
+ G_LOCK_DEFINE_STATIC (edies);
- if (mse->folders_by_name) {
- g_hash_table_destroy (mse->folders_by_name);
- mse->folders_by_name = NULL;
- }
+ GSList *p, *accounts;
+ ExchangeData *res = NULL;
- if (mse->ctx) {
- g_object_unref (mse->ctx);
- mse->ctx = NULL;
- }
+ g_return_val_if_fail (service != NULL, NULL);
+ g_return_val_if_fail (CAMEL_IS_SERVICE (service), NULL);
- if (mse->new_folder_id != 0) {
- g_signal_handler_disconnect (mse->account, mse->new_folder_id);
- mse->new_folder_id = 0;
- g_signal_handler_disconnect (mse->account, mse->removed_folder_id);
- mse->removed_folder_id = 0;
+ G_LOCK (edies);
+ for (p = edies; p; p = p->next) {
+ ExchangeData *ed = p->data;
+
+ if (ed && is_same_ed (ed->estore, ed->account, service)) {
+ G_UNLOCK (edies);
+ return ed;
+ }
}
-/* if (g_signal_handler_is_connected (G_OBJECT (global_exchange_component),
- offline_listener_handler_id)) {
- g_signal_handler_disconnect (G_OBJECT (global_exchange_component),
- offline_listener_handler_id);
- offline_listener_handler_id = 0;
+ accounts = exchange_share_config_listener_get_accounts (exchange_share_config_listener_get_global ());
+ for (p = accounts; p; p = p->next) {
+ ExchangeAccount *a = p->data;
+
+ if (a && is_same_ed (NULL, a, service)) {
+ res = g_new0 (ExchangeData, 1);
+ res->account = a;
+ if (CAMEL_IS_EXCHANGE_STORE (service))
+ res->estore = CAMEL_EXCHANGE_STORE (service);
+ res->folders_by_name = g_hash_table_new_full (g_str_hash, g_str_equal, NULL, free_folder);
+ g_static_rec_mutex_init (&res->changed_msgs_mutex);
+
+ edies = g_slist_prepend (edies, res);
+ break;
+ }
}
-*/
- G_OBJECT_CLASS (parent_class)->dispose (object);
+
+ g_slist_free (accounts);
+
+ G_UNLOCK (edies);
+
+ return res;
}
-E2K_MAKE_TYPE (mail_stub_exchange, MailStubExchange, class_init, init, PARENT_TYPE)
+static gint
+is_online (ExchangeData *ed)
+{
+ CamelSession *session;
+
+ g_return_val_if_fail (ed != NULL, OFFLINE_MODE);
+ g_return_val_if_fail (ed->estore != NULL, OFFLINE_MODE);
+
+ session = camel_service_get_session (CAMEL_SERVICE (ed->estore));
+ g_return_val_if_fail (session != NULL, OFFLINE_MODE);
+
+ return camel_session_is_online (session) ? ONLINE_MODE : OFFLINE_MODE;
+}
-static MailStubExchangeFolder *
-folder_from_name (MailStubExchange *mse, const gchar *folder_name,
- guint32 perms, gboolean background)
+static void
+set_exception (CamelException *ex, const gchar *err)
{
- MailStubExchangeFolder *mfld;
+ g_return_if_fail (err != NULL);
- mfld = g_hash_table_lookup (mse->folders_by_name, folder_name);
- if (!mfld) {
- if (!background)
- mail_stub_return_error (MAIL_STUB (mse), _("No such folder"));
- return NULL;
- }
+ if (ex && !camel_exception_is_set (ex))
+ camel_exception_set (ex, CAMEL_EXCEPTION_SYSTEM, err);
+}
- /* If sync_deletion_timeout is set, that means the user has been
- * idle in Evolution for longer than a minute, during which
- * time he has deleted messages using another email client,
- * which we haven't bothered to sync up with yet. Do that now.
- */
- if (mfld->sync_deletion_timeout) {
- g_source_remove (mfld->sync_deletion_timeout);
- mfld->sync_deletion_timeout = 0;
- sync_deletions (mse, mfld);
- }
+static CamelFolder *
+get_camel_folder (ExchangeFolder *mfld)
+{
+ CamelFolder *folder;
- if ((perms == MAPI_ACCESS_MODIFY || perms == MAPI_ACCESS_DELETE) &&
- !(mfld->access & perms)) {
- /* try with MAPI_ACCESS_CREATE_CONTENTS */
- perms = MAPI_ACCESS_CREATE_CONTENTS;
- }
+ g_return_val_if_fail (mfld != NULL, NULL);
+ g_return_val_if_fail (mfld->name != NULL, NULL);
+ g_return_val_if_fail (mfld->ed != NULL, NULL);
+ g_return_val_if_fail (mfld->ed->estore != NULL, NULL);
+ g_return_val_if_fail (mfld->ed->estore->folders != NULL, NULL);
- if (perms && !(mfld->access & perms)) {
- if (!background)
- mail_stub_return_error (MAIL_STUB (mse), _("Permission denied"));
- return NULL;
- }
+ g_mutex_lock (mfld->ed->estore->folders_lock);
+ folder = g_hash_table_lookup (mfld->ed->estore->folders, mfld->name);
+ g_mutex_unlock (mfld->ed->estore->folders_lock);
- mfld->last_activity = time (NULL);
- return mfld;
+ return folder;
}
static void
-folder_changed (MailStubExchangeFolder *mfld)
+folder_changed (ExchangeFolder *mfld)
{
e_folder_set_unread_count (mfld->folder, mfld->unread_count);
}
static gint
-find_message_index (MailStubExchangeFolder *mfld, gint seq)
+find_message_index (ExchangeFolder *mfld, gint seq)
{
- MailStubExchangeMessage *mmsg;
+ ExchangeMessage *mmsg;
gint low, high, mid;
low = 0;
@@ -325,24 +270,24 @@ find_message_index (MailStubExchangeFolder *mfld, gint seq)
return -1;
}
-static inline MailStubExchangeMessage *
-find_message (MailStubExchangeFolder *mfld, const gchar *uid)
+static inline ExchangeMessage *
+find_message (ExchangeFolder *mfld, const gchar *uid)
{
return g_hash_table_lookup (mfld->messages_by_uid, uid);
}
-static inline MailStubExchangeMessage *
-find_message_by_href (MailStubExchangeFolder *mfld, const gchar *href)
+static inline ExchangeMessage *
+find_message_by_href (ExchangeFolder *mfld, const gchar *href)
{
return g_hash_table_lookup (mfld->messages_by_href, href);
}
-static MailStubExchangeMessage *
+static ExchangeMessage *
new_message (const gchar *uid, const gchar *uri, guint32 seq, guint32 flags)
{
- MailStubExchangeMessage *mmsg;
+ ExchangeMessage *mmsg;
- mmsg = g_new0 (MailStubExchangeMessage, 1);
+ mmsg = g_new0 (ExchangeMessage, 1);
mmsg->uid = g_strdup (uid);
mmsg->href = g_strdup (uri);
mmsg->seq = seq;
@@ -352,27 +297,28 @@ new_message (const gchar *uid, const gchar *uri, guint32 seq, guint32 flags)
}
static void
-message_remove_at_index (MailStub *stub, MailStubExchangeFolder *mfld, gint index)
+message_remove_at_index (ExchangeFolder *mfld, CamelFolder *folder, gint index)
{
- MailStubExchangeMessage *mmsg;
+ ExchangeMessage *mmsg;
+ CamelMessageInfo *info;
mmsg = mfld->messages->pdata[index];
d(printf("Deleting mmsg %p\n", mmsg));
- g_static_rec_mutex_lock (&g_changed_msgs_mutex);
+ g_static_rec_mutex_lock (&mfld->ed->changed_msgs_mutex);
g_ptr_array_remove_index (mfld->messages, index);
g_hash_table_remove (mfld->messages_by_uid, mmsg->uid);
if (mmsg->href)
g_hash_table_remove (mfld->messages_by_href, mmsg->href);
- if (!(mmsg->flags & MAIL_STUB_MESSAGE_SEEN)) {
+ if (!(mmsg->flags & CAMEL_MESSAGE_SEEN)) {
mfld->unread_count--;
folder_changed (mfld);
}
- g_static_rec_mutex_unlock (&g_changed_msgs_mutex);
+ g_static_rec_mutex_unlock (&mfld->ed->changed_msgs_mutex);
if (mmsg->change_mask || mmsg->tag_updates) {
gint i;
- g_static_rec_mutex_lock (&g_changed_msgs_mutex);
+ g_static_rec_mutex_lock (&mfld->ed->changed_msgs_mutex);
for (i = 0; i < mfld->changed_messages->len; i++) {
if (mfld->changed_messages->pdata[i] == (gpointer)mmsg) {
@@ -380,15 +326,15 @@ message_remove_at_index (MailStub *stub, MailStubExchangeFolder *mfld, gint inde
break;
}
}
- g_static_rec_mutex_unlock (&g_changed_msgs_mutex);
+ g_static_rec_mutex_unlock (&mfld->ed->changed_msgs_mutex);
g_datalist_clear (&mmsg->tag_updates);
}
- mail_stub_return_data (stub, CAMEL_STUB_RETVAL_REMOVED_MESSAGE,
- CAMEL_STUB_ARG_FOLDER, mfld->name,
- CAMEL_STUB_ARG_STRING, mmsg->uid,
- CAMEL_STUB_ARG_END);
+ if (folder && (info = camel_folder_summary_uid (folder->summary, mmsg->uid))) {
+ camel_message_info_free (info);
+ camel_exchange_folder_remove_message (CAMEL_EXCHANGE_FOLDER (folder), mmsg->uid);
+ }
g_free (mmsg->uid);
g_free (mmsg->href);
@@ -396,56 +342,22 @@ message_remove_at_index (MailStub *stub, MailStubExchangeFolder *mfld, gint inde
}
static void
-message_removed (MailStub *stub, MailStubExchangeFolder *mfld, const gchar *href)
+message_removed (ExchangeFolder *mfld, CamelFolder *folder, const gchar *href)
{
- MailStubExchangeMessage *mmsg;
+ ExchangeMessage *mmsg;
guint index;
- g_static_rec_mutex_lock (&g_changed_msgs_mutex);
+ g_static_rec_mutex_lock (&mfld->ed->changed_msgs_mutex);
mmsg = g_hash_table_lookup (mfld->messages_by_href, href);
if (!mmsg) {
- g_static_rec_mutex_unlock (&g_changed_msgs_mutex);
+ g_static_rec_mutex_unlock (&mfld->ed->changed_msgs_mutex);
return;
}
index = find_message_index (mfld, mmsg->seq);
g_return_if_fail (index != -1);
- message_remove_at_index (stub, mfld, index);
- g_static_rec_mutex_unlock (&g_changed_msgs_mutex);
-}
-
-static void
-return_tag (MailStubExchangeFolder *mfld, const gchar *uid,
- const gchar *name, const gchar *value)
-{
- mail_stub_return_data (MAIL_STUB (mfld->mse),
- CAMEL_STUB_RETVAL_CHANGED_TAG,
- CAMEL_STUB_ARG_FOLDER, mfld->name,
- CAMEL_STUB_ARG_STRING, uid,
- CAMEL_STUB_ARG_STRING, name,
- CAMEL_STUB_ARG_STRING, value,
- CAMEL_STUB_ARG_END);
-}
-
-static void
-change_flags (MailStubExchangeFolder *mfld, MailStubExchangeMessage *mmsg,
- guint32 new_flags)
-{
- if ((mmsg->flags ^ new_flags) & MAIL_STUB_MESSAGE_SEEN) {
- if (mmsg->flags & MAIL_STUB_MESSAGE_SEEN)
- mfld->unread_count++;
- else
- mfld->unread_count--;
- folder_changed (mfld);
- }
- mmsg->flags = new_flags;
-
- mail_stub_return_data (MAIL_STUB (mfld->mse),
- CAMEL_STUB_RETVAL_CHANGED_FLAGS,
- CAMEL_STUB_ARG_FOLDER, mfld->name,
- CAMEL_STUB_ARG_STRING, mmsg->uid,
- CAMEL_STUB_ARG_UINT32, mmsg->flags,
- CAMEL_STUB_ARG_END);
+ message_remove_at_index (mfld, folder, index);
+ g_static_rec_mutex_unlock (&mfld->ed->changed_msgs_mutex);
}
static const gchar *
@@ -463,135 +375,481 @@ uidstrip (const gchar *repl_uid)
return repl_uid + 36;
}
-#define FIVE_SECONDS (5)
-#define ONE_MINUTE (60)
-#define FIVE_MINUTES (60*5)
+struct refresh_message {
+ gchar *uid, *href, *headers, *fff, *reply_by, *completed;
+ guint32 flags, size, article_num;
+};
-static gboolean
-timeout_sync_deletions (gpointer user_data)
+static gint
+refresh_message_compar (gconstpointer a, gconstpointer b)
{
- MailStubExchangeFolder *mfld = user_data;
+ const struct refresh_message *rma = a, *rmb = b;
- sync_deletions (mfld->mse, mfld);
- return FALSE;
+ return strcmp (rma->uid, rmb->uid);
}
static void
-notify_cb (E2kContext *ctx, const gchar *uri,
- E2kContextChangeType type, gpointer user_data)
+change_flags (ExchangeFolder *mfld, CamelFolder *folder, ExchangeMessage *mmsg, guint32 new_flags)
{
- MailStubExchangeFolder *mfld = user_data;
- time_t now;
+ if ((mmsg->flags ^ new_flags) & CAMEL_MESSAGE_SEEN) {
+ if (mmsg->flags & CAMEL_MESSAGE_SEEN)
+ mfld->unread_count++;
+ else
+ mfld->unread_count--;
+ folder_changed (mfld);
+ }
+ mmsg->flags = new_flags;
- if (type == E2K_CONTEXT_OBJECT_ADDED)
- refresh_folder_internal (MAIL_STUB (mfld->mse), mfld, TRUE);
- else {
- now = time (NULL);
+ if (folder)
+ camel_exchange_folder_update_message_flags (CAMEL_EXCHANGE_FOLDER (folder), mmsg->uid, mmsg->flags);
+}
- /* If the user did something in Evolution in the
- * last 5 seconds, assume that this notification is
- * a result of that and ignore it.
+static void
+refresh_folder_internal (ExchangeFolder *mfld, CamelException *ex)
+{
+ static const gchar *new_message_props[] = {
+ E2K_PR_REPL_UID,
+ PR_INTERNET_ARTICLE_NUMBER,
+ PR_TRANSPORT_MESSAGE_HEADERS,
+ E2K_PR_HTTPMAIL_READ,
+ E2K_PR_HTTPMAIL_HAS_ATTACHMENT,
+ PR_ACTION_FLAG,
+ PR_IMPORTANCE,
+ PR_DELEGATED_BY_RULE,
+ E2K_PR_HTTPMAIL_MESSAGE_FLAG,
+ E2K_PR_MAILHEADER_REPLY_BY,
+ E2K_PR_MAILHEADER_COMPLETED,
+ E2K_PR_DAV_CONTENT_LENGTH
+ };
+
+ E2kRestriction *rn;
+ GArray *messages;
+ GHashTable *mapi_message_hash;
+ GPtrArray *mapi_hrefs;
+ gboolean has_read_flag = (mfld->access & MAPI_ACCESS_READ);
+ E2kResultIter *iter;
+ E2kResult *result;
+ gchar *prop, *uid, *href;
+ struct refresh_message rm, *rmp;
+ E2kHTTPStatus status;
+ gint got, total, i, n;
+ gpointer key, value;
+ ExchangeMessage *mmsg;
+ CamelFolder *folder;
+
+ if (is_online (mfld->ed) != ONLINE_MODE) {
+ return;
+ }
+
+ messages = g_array_new (FALSE, FALSE, sizeof (struct refresh_message));
+ mapi_message_hash = g_hash_table_new (g_str_hash, g_str_equal);
+ mapi_hrefs = g_ptr_array_new ();
+
+ /*
+ * STEP 1: Fetch information about new messages, including SMTP
+ * headers when available.
+ */
+
+ rn = e2k_restriction_andv (
+ e2k_restriction_prop_bool (E2K_PR_DAV_IS_COLLECTION,
+ E2K_RELOP_EQ, FALSE),
+ e2k_restriction_prop_bool (E2K_PR_DAV_IS_HIDDEN,
+ E2K_RELOP_EQ, FALSE),
+ e2k_restriction_prop_int (PR_INTERNET_ARTICLE_NUMBER,
+ E2K_RELOP_GT,
+ mfld->high_article_num),
+ NULL);
+ iter = e_folder_exchange_search_start (mfld->folder, NULL,
+ new_message_props,
+ G_N_ELEMENTS (new_message_props),
+ rn, NULL, TRUE);
+ e2k_restriction_unref (rn);
+
+ got = 0;
+ total = e2k_result_iter_get_total (iter);
+ while ((result = e2k_result_iter_next (iter))) {
+ if (!E2K_HTTP_STATUS_IS_SUCCESSFUL (result->status)) {
+ g_message ("%s: got unsuccessful at %s (%s)", G_STRFUNC, mfld->name, result->href ? result->href : "[null]");
+ continue;
+ }
+
+ uid = e2k_properties_get_prop (result->props, E2K_PR_REPL_UID);
+ if (!uid)
+ continue;
+ prop = e2k_properties_get_prop (result->props,
+ PR_INTERNET_ARTICLE_NUMBER);
+ if (!prop)
+ continue;
+
+ rm.uid = g_strdup (uidstrip (uid));
+ rm.href = g_strdup (result->href);
+ rm.article_num = strtoul (prop, NULL, 10);
+
+ rm.flags = mail_util_props_to_camel_flags (result->props,
+ has_read_flag);
+
+ prop = e2k_properties_get_prop (result->props,
+ E2K_PR_HTTPMAIL_MESSAGE_FLAG);
+ if (prop)
+ rm.fff = g_strdup (prop);
+ else
+ rm.fff = NULL;
+ prop = e2k_properties_get_prop (result->props,
+ E2K_PR_MAILHEADER_REPLY_BY);
+ if (prop)
+ rm.reply_by = g_strdup (prop);
+ else
+ rm.reply_by = NULL;
+ prop = e2k_properties_get_prop (result->props,
+ E2K_PR_MAILHEADER_COMPLETED);
+ if (prop)
+ rm.completed = g_strdup (prop);
+ else
+ rm.completed = NULL;
+
+ prop = e2k_properties_get_prop (result->props,
+ E2K_PR_DAV_CONTENT_LENGTH);
+ rm.size = prop ? strtoul (prop, NULL, 10) : 0;
+
+ rm.headers = mail_util_extract_transport_headers (result->props);
+
+ g_array_append_val (messages, rm);
+
+ if (rm.headers) {
+ got++;
+ camel_operation_progress (NULL, (got * 100) / total);
+ } else {
+ href = strrchr (rm.href, '/');
+ if (!href++)
+ href = rm.href;
+
+ g_hash_table_insert (mapi_message_hash, href,
+ GINT_TO_POINTER (messages->len - 1));
+ g_ptr_array_add (mapi_hrefs, href);
+ }
+ }
+ status = e2k_result_iter_free (iter);
+
+ if (!E2K_HTTP_STATUS_IS_SUCCESSFUL (status)) {
+ g_warning ("got_new_smtp_messages: %d", status);
+ set_exception (ex, _("Could not get new messages"));
+ goto done;
+ }
+
+ if (mapi_hrefs->len == 0)
+ goto return_data;
+
+ /*
+ * STEP 2: Fetch MAPI property data for non-SMTP messages.
+ */
+
+ iter = e_folder_exchange_bpropfind_start (mfld->folder, NULL,
+ (const gchar **)mapi_hrefs->pdata,
+ mapi_hrefs->len,
+ mapi_message_props,
+ G_N_ELEMENTS (mapi_message_props));
+ while ((result = e2k_result_iter_next (iter))) {
+ if (!E2K_HTTP_STATUS_IS_SUCCESSFUL (result->status))
+ continue;
+
+ href = strrchr (result->href, '/');
+ if (!href++)
+ href = result->href;
+
+ if (!g_hash_table_lookup_extended (mapi_message_hash, href,
+ &key, &value))
+ continue;
+ n = GPOINTER_TO_INT (value);
+
+ rmp = &((struct refresh_message *)messages->data)[n];
+ rmp->headers = mail_util_mapi_to_smtp_headers (result->props);
+
+ got++;
+ camel_operation_progress (NULL, (got * 100) / total);
+ }
+ status = e2k_result_iter_free (iter);
+
+ if (!E2K_HTTP_STATUS_IS_SUCCESSFUL (status)) {
+ g_warning ("got_new_mapi_messages: %d", status);
+ set_exception (ex, _("Could not get new messages"));
+ goto done;
+ }
+
+ /*
+ * STEP 3: Organize the data, update our records and Camel's
+ */
+
+ return_data:
+ camel_operation_progress (NULL, 100);
+ folder = get_camel_folder (mfld);
+ if (folder)
+ camel_folder_freeze (folder);
+
+ g_static_rec_mutex_lock (&mfld->ed->changed_msgs_mutex);
+ qsort (messages->data, messages->len,
+ sizeof (rm), refresh_message_compar);
+ for (i = 0; i < messages->len; i++) {
+ rm = g_array_index (messages, struct refresh_message, i);
+
+ /* If we already have a message with this UID, then
+ * that means it's not a new message, it's just that
+ * the article number changed.
*/
- if (now < mfld->last_activity + FIVE_SECONDS)
+ mmsg = find_message (mfld, rm.uid);
+ if (mmsg) {
+ if (rm.flags != mmsg->flags)
+ change_flags (mfld, folder, mmsg, rm.flags);
+ } else {
+ if (g_hash_table_lookup (mfld->messages_by_href, rm.href)) {
+ mfld->deleted_count++;
+ message_removed (mfld, folder, rm.href);
+ }
+
+ mmsg = new_message (rm.uid, rm.href, mfld->seq++, rm.flags);
+ g_ptr_array_add (mfld->messages, mmsg);
+ g_hash_table_insert (mfld->messages_by_uid, mmsg->uid, mmsg);
+ g_hash_table_insert (mfld->messages_by_href, mmsg->href, mmsg);
+
+ if (!(mmsg->flags & CAMEL_MESSAGE_SEEN))
+ mfld->unread_count++;
+
+ if (folder)
+ camel_exchange_folder_add_message (CAMEL_EXCHANGE_FOLDER (folder), rm.uid, rm.flags, rm.size, rm.headers, rm.href);
+ }
+
+ if (rm.article_num > mfld->high_article_num) {
+ mfld->high_article_num = rm.article_num;
+ if (folder)
+ camel_exchange_summary_set_article_num (folder->summary, mfld->high_article_num);
+ }
+
+ if (rm.fff && folder)
+ camel_exchange_folder_update_message_tag (CAMEL_EXCHANGE_FOLDER (folder), rm.uid, "follow-up", rm.fff);
+ if (rm.reply_by && folder)
+ camel_exchange_folder_update_message_tag (CAMEL_EXCHANGE_FOLDER (folder), rm.uid, "due-by", rm.reply_by);
+ if (rm.completed && folder)
+ camel_exchange_folder_update_message_tag (CAMEL_EXCHANGE_FOLDER (folder), rm.uid, "completed-on", rm.completed);
+ }
+
+ if (folder)
+ camel_folder_thaw (folder);
+
+ mfld->scanned = TRUE;
+ g_static_rec_mutex_unlock (&mfld->ed->changed_msgs_mutex);
+ folder_changed (mfld);
+
+ done:
+ /*
+ * CLEANUP
+ */
+ rmp = (struct refresh_message *)messages->data;
+ for (i = 0; i < messages->len; i++) {
+ g_free (rmp[i].uid);
+ g_free (rmp[i].href);
+ g_free (rmp[i].headers);
+ g_free (rmp[i].fff);
+ g_free (rmp[i].reply_by);
+ g_free (rmp[i].completed);
+ }
+ g_array_free (messages, TRUE);
+
+ g_hash_table_destroy (mapi_message_hash);
+ g_ptr_array_free (mapi_hrefs, TRUE);
+}
+
+static void
+sync_deletions (ExchangeFolder *mfld)
+{
+ static const gchar *sync_deleted_props[] = {
+ PR_DELETED_COUNT_TOTAL,
+ E2K_PR_DAV_VISIBLE_COUNT
+ };
+
+ E2kHTTPStatus status;
+ E2kResult *results;
+ gint nresults = 0;
+ const gchar *prop;
+ gint deleted_count = -1, visible_count = -1;
+ E2kRestriction *rn;
+ E2kResultIter *iter;
+ E2kResult *result;
+ gint my_i, read;
+ ExchangeMessage *mmsg;
+ GHashTable *known_messages;
+ CamelFolder *folder;
+
+ g_return_if_fail (mfld != NULL);
+ g_return_if_fail (mfld->ed != NULL);
+
+ if (is_online (mfld->ed) != ONLINE_MODE)
+ return;
+
+ status = e_folder_exchange_propfind (mfld->folder, NULL,
+ sync_deleted_props,
+ G_N_ELEMENTS (sync_deleted_props),
+ &results, &nresults);
+
+ if (!E2K_HTTP_STATUS_IS_SUCCESSFUL (status) || !nresults) {
+ g_warning ("got_sync_deleted_props: %d", status);
+ return;
+ }
+
+ prop = e2k_properties_get_prop (results[0].props,
+ PR_DELETED_COUNT_TOTAL);
+ if (prop)
+ deleted_count = atoi (prop);
+
+ prop = e2k_properties_get_prop (results[0].props,
+ E2K_PR_DAV_VISIBLE_COUNT);
+ if (prop)
+ visible_count = atoi (prop);
+
+ e2k_results_free (results, nresults);
+
+ g_static_rec_mutex_lock (&mfld->ed->changed_msgs_mutex);
+ if (visible_count >= mfld->messages->len) {
+ if (mfld->deleted_count == deleted_count) {
+ g_static_rec_mutex_unlock (&mfld->ed->changed_msgs_mutex);
return;
+ }
- /* sync_deletions() is somewhat server-intensive, so
- * we don't want to run it unnecessarily. In
- * particular, if the user leaves Evolution running,
- * goes home for the night, and then reads mail from
- * home, we don't want to run sync_deletions() every
- * time the user deletes a message; we just need to
- * make sure we do it by the time the user gets back
- * in the morning. On the other hand, if the user just
- * switches to Outlook for just a moment and then
- * comes back, we'd like to update fairly quickly.
- *
- * So, if the user has been idle for less than a
- * minute, we update right away. Otherwise, we set a
- * timer, and keep resetting it with each new
- * notification, meaning we (hopefully) only sync
- * after the user stops changing things.
- *
- * If the user returns to Evolution while we have a
- * timer set, then folder_from_name() will immediately
- * call sync_deletions.
- */
+ if (mfld->deleted_count == 0) {
+ mfld->deleted_count = deleted_count;
+ g_static_rec_mutex_unlock (&mfld->ed->changed_msgs_mutex);
+ return;
+ }
+ }
- if (mfld->sync_deletion_timeout) {
- g_source_remove (mfld->sync_deletion_timeout);
- mfld->sync_deletion_timeout = 0;
+ prop = E2K_PR_HTTPMAIL_READ;
+ rn = e2k_restriction_andv (
+ e2k_restriction_prop_bool (E2K_PR_DAV_IS_COLLECTION,
+ E2K_RELOP_EQ, FALSE),
+ e2k_restriction_prop_bool (E2K_PR_DAV_IS_HIDDEN,
+ E2K_RELOP_EQ, FALSE),
+ NULL);
+
+ iter = e_folder_exchange_search_start (mfld->folder, NULL,
+ &prop, 1, rn,
+ E2K_PR_DAV_CREATION_DATE,
+ FALSE);
+ e2k_restriction_unref (rn);
+
+ known_messages = g_hash_table_new (g_direct_hash, g_direct_equal);
+
+ folder = get_camel_folder (mfld);
+
+ my_i = mfld->messages->len - 1;
+ while ((result = e2k_result_iter_next (iter))) {
+ mmsg = find_message_by_href (mfld, result->href);
+ if (!mmsg) {
+ /* oops, message from the server not found in our list;
+ return failure to possibly do full resync again? */
+ g_message ("%s: Oops, message %s not found in %s", G_STRFUNC, result->href, mfld->name);
+ continue;
}
- if (now < mfld->last_activity + ONE_MINUTE)
- sync_deletions (mfld->mse, mfld);
- else if (now < mfld->last_activity + FIVE_MINUTES) {
- mfld->sync_deletion_timeout =
- g_timeout_add (ONE_MINUTE * 1000,
- timeout_sync_deletions,
- mfld);
- } else {
- mfld->sync_deletion_timeout =
- g_timeout_add (FIVE_MINUTES * 1000,
- timeout_sync_deletions,
- mfld);
+ g_hash_table_insert (known_messages, mmsg, mmsg);
+
+ /* See if its read flag changed while we weren't watching */
+ prop = e2k_properties_get_prop (result->props,
+ E2K_PR_HTTPMAIL_READ);
+ read = (prop && atoi (prop)) ? CAMEL_MESSAGE_SEEN : 0;
+ if ((mmsg->flags & CAMEL_MESSAGE_SEEN) != read) {
+ change_flags (mfld, folder, mmsg, mmsg->flags ^ CAMEL_MESSAGE_SEEN);
}
+
}
+ status = e2k_result_iter_free (iter);
+
+ if (!E2K_HTTP_STATUS_IS_SUCCESSFUL (status))
+ g_warning ("synced_deleted: %d", status);
+
+ /* Clear out removed messages from mfld */
+ for (my_i = mfld->messages->len - 1; my_i >= 0; my_i --) {
+ mmsg = mfld->messages->pdata[my_i];
+ if (!g_hash_table_lookup (known_messages, mmsg)) {
+ mfld->deleted_count++;
+ message_remove_at_index (mfld, folder, my_i);
+ }
+ }
+
+ g_hash_table_destroy (known_messages);
+ g_static_rec_mutex_unlock (&mfld->ed->changed_msgs_mutex);
}
static void
storage_folder_changed (EFolder *folder, gpointer user_data)
{
- MailStubExchangeFolder *mfld = user_data;
+ ExchangeFolder *mfld = user_data;
if (e_folder_get_unread_count (folder) > mfld->unread_count)
- refresh_folder_internal (MAIL_STUB (mfld->mse), mfld, TRUE);
+ refresh_folder_internal (mfld, NULL);
}
static void
-got_folder_error (MailStubExchangeFolder *mfld, const gchar *error)
+free_message (ExchangeMessage *mmsg)
{
- mail_stub_return_error (MAIL_STUB (mfld->mse), error);
- free_folder (mfld);
+ g_datalist_clear (&mmsg->tag_updates);
+ g_free (mmsg->uid);
+ g_free (mmsg->href);
+ g_free (mmsg);
}
-static const gchar *open_folder_sync_props[] = {
- E2K_PR_REPL_UID,
- PR_INTERNET_ARTICLE_NUMBER,
- PR_ACTION_FLAG,
- PR_IMPORTANCE,
- PR_DELEGATED_BY_RULE,
- E2K_PR_HTTPMAIL_READ,
- E2K_PR_HTTPMAIL_MESSAGE_FLAG,
- E2K_PR_MAILHEADER_REPLY_BY,
- E2K_PR_MAILHEADER_COMPLETED
-};
-static const gint n_open_folder_sync_props = sizeof (open_folder_sync_props) / sizeof (open_folder_sync_props[0]);
+static void
+free_folder (gpointer value)
+{
+ ExchangeFolder *mfld = value;
+ gint i;
-static const gchar *open_folder_props[] = {
- PR_ACCESS,
- PR_DELETED_COUNT_TOTAL
-};
-static const gint n_open_folder_props = sizeof (open_folder_props) / sizeof (open_folder_props[0]);
+ d(g_print ("%s:%s:%d: freeing mfld: name=[%s]\n", __FILE__, __PRETTY_FUNCTION__, __LINE__,
+ mfld->name));
+
+ e_folder_exchange_unsubscribe (mfld->folder);
+ g_signal_handlers_disconnect_by_func (mfld->folder, storage_folder_changed, mfld);
+ g_object_unref (mfld->folder);
+ mfld->folder = NULL;
+
+ for (i = 0; i < mfld->messages->len; i++)
+ free_message (mfld->messages->pdata[i]);
+ g_ptr_array_free (mfld->messages, TRUE);
+ g_hash_table_destroy (mfld->messages_by_uid);
+ g_hash_table_destroy (mfld->messages_by_href);
+
+ g_ptr_array_free (mfld->changed_messages, TRUE);
+ if (mfld->flag_timeout) {
+ g_warning ("unreffing mfld with unsynced flags");
+ g_source_remove (mfld->flag_timeout);
+ }
+ if (mfld->sync_deletion_timeout)
+ g_source_remove (mfld->sync_deletion_timeout);
+ g_free (mfld);
+}
+
+static void
+got_folder_error (ExchangeFolder *mfld, CamelException *ex, const gchar *err)
+{
+ set_exception (ex, err);
+
+ free_folder (mfld);
+}
static void
-mse_get_folder_online_sync_updates (gpointer key, gpointer value,
- gpointer user_data)
+mfld_get_folder_online_sync_updates (gpointer key, gpointer value, gpointer user_data)
{
guint index, seq, i;
- MailStubExchangeFolder *mfld = (MailStubExchangeFolder *)user_data;
- /*MailStub *stub = MAIL_STUB (mfld->mse);*/
- MailStubExchangeMessage *mmsg = NULL;
+ ExchangeFolder *mfld = (ExchangeFolder *) user_data;
+ ExchangeMessage *mmsg = NULL;
index = GPOINTER_TO_UINT (key);
seq = GPOINTER_TO_UINT (value);
- g_static_rec_mutex_lock (&g_changed_msgs_mutex);
+ g_static_rec_mutex_lock (&mfld->ed->changed_msgs_mutex);
/* Camel DB Summary changes are not fetching all the messages at start-up.
Use this else it would crash badly.
*/
if (index >= mfld->messages->len) {
- g_static_rec_mutex_unlock (&g_changed_msgs_mutex);
+ g_static_rec_mutex_unlock (&mfld->ed->changed_msgs_mutex);
return;
}
@@ -604,7 +862,7 @@ mse_get_folder_online_sync_updates (gpointer key, gpointer value,
}
seq = i;
}
- g_static_rec_mutex_unlock (&g_changed_msgs_mutex);
+ g_static_rec_mutex_unlock (&mfld->ed->changed_msgs_mutex);
/* FIXME FIXME FIXME: Some miscalculation happens here,though,
not a serious one
@@ -613,11 +871,23 @@ mse_get_folder_online_sync_updates (gpointer key, gpointer value,
/*message_remove_at_index (stub, mfld, seq);*/
}
+
static gboolean
-get_folder_contents_online (MailStubExchangeFolder *mfld, gboolean background)
-{
- MailStubExchangeMessage *mmsg, *mmsg_cpy;
- MailStub *stub = MAIL_STUB (mfld->mse);
+get_folder_contents_online (ExchangeFolder *mfld, CamelException *ex)
+{
+ static const gchar *open_folder_sync_props[] = {
+ E2K_PR_REPL_UID,
+ PR_INTERNET_ARTICLE_NUMBER,
+ PR_ACTION_FLAG,
+ PR_IMPORTANCE,
+ PR_DELEGATED_BY_RULE,
+ E2K_PR_HTTPMAIL_READ,
+ E2K_PR_HTTPMAIL_MESSAGE_FLAG,
+ E2K_PR_MAILHEADER_REPLY_BY,
+ E2K_PR_MAILHEADER_COMPLETED
+ };
+
+ ExchangeMessage *mmsg, *mmsg_cpy;
E2kHTTPStatus status;
gboolean readonly = FALSE;
E2kRestriction *rn;
@@ -627,6 +897,7 @@ get_folder_contents_online (MailStubExchangeFolder *mfld, gboolean background)
guint32 article_num, camel_flags, high_article_num;
gint i, total = -1;
guint m;
+ CamelFolder *folder;
GPtrArray *msgs_copy = NULL;
GHashTable *rm_idx_uid = NULL;
@@ -637,14 +908,14 @@ get_folder_contents_online (MailStubExchangeFolder *mfld, gboolean background)
/* Store the index/seq of the messages to be removed from mfld->messages */
rm_idx_uid = g_hash_table_new (g_direct_hash, g_direct_equal);
- g_static_rec_mutex_lock (&g_changed_msgs_mutex);
+ g_static_rec_mutex_lock (&mfld->ed->changed_msgs_mutex);
for (i = 0; i < mfld->messages->len; i++) {
mmsg = mfld->messages->pdata[i];
mmsg_cpy = new_message (mmsg->uid, mmsg->href, mmsg->seq, mmsg->flags);
g_ptr_array_add (msgs_copy, mmsg_cpy);
}
high_article_num = 0;
- g_static_rec_mutex_unlock (&g_changed_msgs_mutex);
+ g_static_rec_mutex_unlock (&mfld->ed->changed_msgs_mutex);
rn = e2k_restriction_andv (
e2k_restriction_prop_bool (E2K_PR_DAV_IS_COLLECTION,
@@ -655,11 +926,13 @@ get_folder_contents_online (MailStubExchangeFolder *mfld, gboolean background)
iter = e_folder_exchange_search_start (mfld->folder, NULL,
open_folder_sync_props,
- n_open_folder_sync_props,
+ G_N_ELEMENTS (open_folder_sync_props),
rn, E2K_PR_DAV_CREATION_DATE,
TRUE);
e2k_restriction_unref (rn);
+ folder = get_camel_folder (mfld);
+
m = 0;
total = e2k_result_iter_get_total (iter);
while (m < msgs_copy->len && (result = e2k_result_iter_next (iter))) {
@@ -706,7 +979,7 @@ get_folder_contents_online (MailStubExchangeFolder *mfld, gboolean background)
if (article_num > high_article_num)
high_article_num = article_num;
- g_static_rec_mutex_lock (&g_changed_msgs_mutex);
+ g_static_rec_mutex_lock (&mfld->ed->changed_msgs_mutex);
mmsg = mfld->messages->pdata[m];
/* Validate mmsg == mmsg_cpy - this may fail if user has deleted some messages,
@@ -735,27 +1008,27 @@ get_folder_contents_online (MailStubExchangeFolder *mfld, gboolean background)
}
if (mmsg->flags != camel_flags)
- change_flags (mfld, mmsg, camel_flags);
+ change_flags (mfld, folder, mmsg, camel_flags);
- g_static_rec_mutex_unlock (&g_changed_msgs_mutex);
+ g_static_rec_mutex_unlock (&mfld->ed->changed_msgs_mutex);
if (article_num > high_article_num)
high_article_num = article_num;
prop = e2k_properties_get_prop (result->props, E2K_PR_HTTPMAIL_MESSAGE_FLAG);
- if (prop)
- return_tag (mfld, mmsg->uid, "follow-up", prop);
+ if (prop && folder)
+ camel_exchange_folder_update_message_tag (CAMEL_EXCHANGE_FOLDER (folder), mmsg->uid, "follow-up", prop);
prop = e2k_properties_get_prop (result->props, E2K_PR_MAILHEADER_REPLY_BY);
- if (prop)
- return_tag (mfld, mmsg->uid, "due-by", prop);
+ if (prop && folder)
+ camel_exchange_folder_update_message_tag (CAMEL_EXCHANGE_FOLDER (folder), mmsg->uid, "due-by", prop);
prop = e2k_properties_get_prop (result->props, E2K_PR_MAILHEADER_COMPLETED);
- if (prop)
- return_tag (mfld, mmsg->uid, "completed-on", prop);
+ if (prop && folder)
+ camel_exchange_folder_update_message_tag (CAMEL_EXCHANGE_FOLDER (folder), mmsg->uid, "completed-on", prop);
m++;
#if 0
- if (!background) {
- mail_stub_return_progress (stub, (m * 100) / total);
+ if (ex) {
+ camel_operation_progress (NULL, (m * 100) / total);
}
#endif
}
@@ -778,17 +1051,15 @@ get_folder_contents_online (MailStubExchangeFolder *mfld, gboolean background)
m++;
#if 0
- if (!background) {
- mail_stub_return_progress (stub, (m * 100) / total);
+ if (ex) {
+ camel_operation_progress (NULL, (m * 100) / total);
}
#endif
}
status = e2k_result_iter_free (iter);
if (!E2K_HTTP_STATUS_IS_SUCCESSFUL (status)) {
g_warning ("got_folder: %d", status);
- if (!background) {
- got_folder_error (mfld, _("Could not open folder"));
- }
+ got_folder_error (mfld, ex, _("Could not open folder"));
return FALSE;
}
@@ -812,17 +1083,14 @@ get_folder_contents_online (MailStubExchangeFolder *mfld, gboolean background)
g_free (mmsg_cpy);
}
- g_static_rec_mutex_lock (&g_changed_msgs_mutex);
+ g_static_rec_mutex_lock (&mfld->ed->changed_msgs_mutex);
mfld->high_article_num = high_article_num;
- g_static_rec_mutex_unlock (&g_changed_msgs_mutex);
+ g_static_rec_mutex_unlock (&mfld->ed->changed_msgs_mutex);
- mail_stub_return_data (stub, CAMEL_STUB_RETVAL_FOLDER_SET_ARTICLE_NUM,
- CAMEL_STUB_ARG_FOLDER, mfld->name,
- CAMEL_STUB_ARG_UINT32, mfld->high_article_num,
- CAMEL_STUB_ARG_END);
+ if (folder)
+ camel_exchange_summary_set_article_num (folder->summary, mfld->high_article_num);
- g_hash_table_foreach (rm_idx_uid, mse_get_folder_online_sync_updates,
- mfld);
+ g_hash_table_foreach (rm_idx_uid, mfld_get_folder_online_sync_updates, mfld);
g_ptr_array_free (msgs_copy, TRUE);
g_hash_table_destroy (rm_idx_uid);
@@ -830,35 +1098,101 @@ get_folder_contents_online (MailStubExchangeFolder *mfld, gboolean background)
return TRUE;
}
-struct _get_folder_thread_data {
- MailStubExchangeFolder *mfld;
- gboolean background;
-};
-
static gpointer
get_folder_contents_online_func (gpointer data)
{
- MailStubExchangeFolder* mfld;
- gboolean background;
+ ExchangeFolder *mfld = data;
- struct _get_folder_thread_data *gf_thread_data = (struct _get_folder_thread_data *)data;
- if (!gf_thread_data)
+ if (!mfld)
return NULL;
- mfld = gf_thread_data->mfld;
- background = gf_thread_data->background;
+ get_folder_contents_online (mfld, NULL);
- get_folder_contents_online (mfld, background);
+ return NULL;
+}
- g_free (gf_thread_data);
+#define FIVE_SECONDS (5)
+#define ONE_MINUTE (60)
+#define FIVE_MINUTES (60*5)
- return NULL;
+static gboolean
+timeout_sync_deletions (gpointer user_data)
+{
+ ExchangeFolder *mfld = user_data;
+
+ sync_deletions (mfld);
+ return FALSE;
+}
+
+static void
+notify_cb (E2kContext *ctx, const gchar *uri, E2kContextChangeType type, gpointer user_data)
+{
+ ExchangeFolder *mfld = user_data;
+ time_t now;
+
+ if (type == E2K_CONTEXT_OBJECT_ADDED)
+ refresh_folder_internal (mfld, NULL);
+ else {
+ now = time (NULL);
+
+ /* If the user did something in Evolution in the
+ * last 5 seconds, assume that this notification is
+ * a result of that and ignore it.
+ */
+ if (now < mfld->last_activity + FIVE_SECONDS)
+ return;
+
+ /* sync_deletions() is somewhat server-intensive, so
+ * we don't want to run it unnecessarily. In
+ * particular, if the user leaves Evolution running,
+ * goes home for the night, and then reads mail from
+ * home, we don't want to run sync_deletions() every
+ * time the user deletes a message; we just need to
+ * make sure we do it by the time the user gets back
+ * in the morning. On the other hand, if the user just
+ * switches to Outlook for just a moment and then
+ * comes back, we'd like to update fairly quickly.
+ *
+ * So, if the user has been idle for less than a
+ * minute, we update right away. Otherwise, we set a
+ * timer, and keep resetting it with each new
+ * notification, meaning we (hopefully) only sync
+ * after the user stops changing things.
+ *
+ * If the user returns to Evolution while we have a
+ * timer set, then folder_from_name() will immediately
+ * call sync_deletions.
+ */
+
+ if (mfld->sync_deletion_timeout) {
+ g_source_remove (mfld->sync_deletion_timeout);
+ mfld->sync_deletion_timeout = 0;
+ }
+
+ if (now < mfld->last_activity + ONE_MINUTE)
+ sync_deletions (mfld);
+ else if (now < mfld->last_activity + FIVE_MINUTES) {
+ mfld->sync_deletion_timeout =
+ g_timeout_add (ONE_MINUTE * 1000,
+ timeout_sync_deletions,
+ mfld);
+ } else {
+ mfld->sync_deletion_timeout =
+ g_timeout_add (FIVE_MINUTES * 1000,
+ timeout_sync_deletions,
+ mfld);
+ }
+ }
}
static gboolean
-get_folder_online (MailStubExchangeFolder *mfld, gboolean background)
+get_folder_online (ExchangeFolder *mfld, CamelException *ex)
{
- MailStub *stub = MAIL_STUB (mfld->mse);
+ static const gchar *open_folder_props[] = {
+ PR_ACCESS,
+ PR_DELETED_COUNT_TOTAL
+ };
+
E2kHTTPStatus status;
E2kResult *results;
gint nresults = 0;
@@ -869,18 +1203,14 @@ get_folder_online (MailStubExchangeFolder *mfld, gboolean background)
status = e_folder_exchange_propfind (mfld->folder, NULL,
open_folder_props,
- n_open_folder_props,
+ G_N_ELEMENTS (open_folder_props),
&results, &nresults);
if (status == E2K_HTTP_UNAUTHORIZED) {
- if (!background) {
- got_folder_error (mfld, _("Could not open folder: Permission denied"));
- }
+ got_folder_error (mfld, ex, _("Could not open folder: Permission denied"));
return FALSE;
} else if (!E2K_HTTP_STATUS_IS_SUCCESSFUL (status)) {
g_warning ("got_folder_props: %d", status);
- if (!background) {
- got_folder_error (mfld, _("Could not open folder"));
- }
+ got_folder_error (mfld, ex, _("Could not open folder"));
return FALSE;
}
@@ -894,9 +1224,7 @@ get_folder_online (MailStubExchangeFolder *mfld, gboolean background)
mfld->access = ~0;
if (!(mfld->access & MAPI_ACCESS_READ)) {
- if (!background) {
- got_folder_error (mfld, _("Could not open folder: Permission denied"));
- }
+ got_folder_error (mfld, ex, _("Could not open folder: Permission denied"));
if (nresults)
e2k_results_free (results, nresults);
return FALSE;
@@ -915,19 +1243,12 @@ get_folder_online (MailStubExchangeFolder *mfld, gboolean background)
change the PR_LAST_MODIFICATION_TIME property of a message.
*/
if (g_hash_table_size (mfld->messages_by_href) < 1) {
- if (!get_folder_contents_online (mfld, background))
+ if (!get_folder_contents_online (mfld, ex))
return FALSE;
} else {
- struct _get_folder_thread_data *gf_thread_data = NULL;
-
- gf_thread_data = g_new0 (struct _get_folder_thread_data, 1);
- gf_thread_data->mfld = mfld;
- gf_thread_data->background = background;
-
/* FIXME: Pass a GError and handle the error */
g_thread_create (get_folder_contents_online_func,
- gf_thread_data, FALSE,
- NULL);
+ mfld, FALSE, NULL);
}
e_folder_exchange_subscribe (mfld->folder,
@@ -939,712 +1260,47 @@ get_folder_online (MailStubExchangeFolder *mfld, gboolean background)
e_folder_exchange_subscribe (mfld->folder,
E2K_CONTEXT_OBJECT_MOVED, 30,
notify_cb, mfld);
- if (background) {
- mail_stub_push_changes (stub);
- }
if (nresults)
e2k_results_free (results, nresults);
- return TRUE;
-}
-
-static void
-get_folder (MailStub *stub, const gchar *name, gboolean create,
- GPtrArray *uids, GByteArray *flags, GPtrArray *hrefs,
- guint32 high_article_num)
-{
- MailStubExchange *mse = MAIL_STUB_EXCHANGE (stub);
- MailStubExchangeFolder *mfld;
- MailStubExchangeMessage *mmsg;
- EFolder *folder;
- gchar *path;
- const gchar *outlook_class;
- guint32 camel_flags;
- gint i, mode;
- ExchangeHierarchy *hier;
-
- path = g_strdup_printf ("/%s", name);
- folder = exchange_account_get_folder (mse->account, path);
- if (!folder && !create) {
- mail_stub_return_error (stub, _("No such folder"));
- g_free (path);
- return;
- } else if (!folder) {
- ExchangeAccountFolderResult result;
-
- result = exchange_account_create_folder (mse->account, path, "mail");
- folder = exchange_account_get_folder (mse->account, path);
- if (result != EXCHANGE_ACCOUNT_FOLDER_OK || !folder) {
- mail_stub_return_error (stub, _("Could not create folder."));
- g_free (path);
- return;
- }
- }
- g_free (path);
-
- mfld = g_new0 (MailStubExchangeFolder, 1);
- mfld->mse = MAIL_STUB_EXCHANGE (stub);
- mfld->folder = folder;
- g_object_ref (folder);
- mfld->name = e_folder_exchange_get_path (folder) + 1;
-
- if (!strcmp (e_folder_get_type_string (folder), "mail/public"))
- mfld->type = MAIL_STUB_EXCHANGE_FOLDER_POST;
- else {
- outlook_class = e_folder_exchange_get_outlook_class (folder);
- if (!outlook_class)
- mfld->type = MAIL_STUB_EXCHANGE_FOLDER_OTHER;
- else if (!g_ascii_strncasecmp (outlook_class, "IPF.Note", 8))
- mfld->type = MAIL_STUB_EXCHANGE_FOLDER_REAL;
- else if (!g_ascii_strncasecmp (outlook_class, "IPF.Post", 8))
- mfld->type = MAIL_STUB_EXCHANGE_FOLDER_POST;
- else if (!g_ascii_strncasecmp (outlook_class, "IPF.StickyNote", 14))
- mfld->type = MAIL_STUB_EXCHANGE_FOLDER_NOTES;
- else
- mfld->type = MAIL_STUB_EXCHANGE_FOLDER_OTHER;
- }
-
- mfld->messages = g_ptr_array_new ();
- mfld->messages_by_uid = g_hash_table_new (g_str_hash, g_str_equal);
- mfld->messages_by_href = g_hash_table_new (g_str_hash, g_str_equal);
- for (i = 0; i < uids->len; i++) {
- mmsg = new_message (uids->pdata[i], NULL, mfld->seq++, flags->data[i]);
- g_ptr_array_add (mfld->messages, mmsg);
- g_hash_table_insert (mfld->messages_by_uid, mmsg->uid, mmsg);
-
- if (hrefs->pdata[i] && *((gchar *)hrefs->pdata[i])) {
- mmsg->href = g_strdup (hrefs->pdata[i]);
- g_hash_table_insert (mfld->messages_by_href, mmsg->href, mmsg);
- }
- if (!(mmsg->flags & MAIL_STUB_MESSAGE_SEEN))
- mfld->unread_count++;
- }
-
- mfld->high_article_num = high_article_num;
-
- exchange_component_is_offline (global_exchange_component, &mode);
- if (mode == ONLINE_MODE) {
- if (!get_folder_online (mfld, FALSE)) {
- return;
- }
- }
- g_signal_connect (mfld->folder, "changed",
- G_CALLBACK (storage_folder_changed), mfld);
-
- g_hash_table_insert (mse->folders_by_name, (gchar *)mfld->name, mfld);
- folder_changed (mfld);
-
- camel_flags = 0;
- if ((mfld->access & (MAPI_ACCESS_MODIFY | MAPI_ACCESS_CREATE_CONTENTS)) == 0)
- camel_flags |= CAMEL_STUB_FOLDER_READONLY;
- if (mse->account->filter_inbox && (mfld->folder == mse->inbox))
- camel_flags |= CAMEL_STUB_FOLDER_FILTER;
- if (mse->account->filter_junk) {
- if ((mfld->folder != mse->deleted_items) &&
- ((mfld->folder == mse->inbox) ||
- !mse->account->filter_junk_inbox_only))
- camel_flags |= CAMEL_STUB_FOLDER_FILTER_JUNK;
- }
- if (mfld->type == MAIL_STUB_EXCHANGE_FOLDER_POST)
- camel_flags |= CAMEL_STUB_FOLDER_POST;
-
- hier = e_folder_exchange_get_hierarchy (mfld->folder);
-
- mail_stub_return_data (stub, CAMEL_STUB_RETVAL_RESPONSE,
- CAMEL_STUB_ARG_UINT32, camel_flags,
- CAMEL_STUB_ARG_STRING, hier->source_uri,
- CAMEL_STUB_ARG_END);
- mail_stub_return_ok (stub);
-}
-
-static void
-get_trash_name (MailStub *stub)
-{
- MailStubExchange *mse = MAIL_STUB_EXCHANGE (stub);
-
- if (!mse->deleted_items) {
- mail_stub_return_error (stub, _("Could not open Deleted Items folder"));
- return;
- }
-
- mail_stub_return_data (stub, CAMEL_STUB_RETVAL_RESPONSE,
- CAMEL_STUB_ARG_STRING, e_folder_exchange_get_path (mse->deleted_items) + 1,
- CAMEL_STUB_ARG_END);
- mail_stub_return_ok (stub);
-}
-
-static void
-sync_folder (MailStub *stub, const gchar *folder_name)
-{
- MailStubExchangeFolder *mfld;
-
- mfld = folder_from_name (MAIL_STUB_EXCHANGE (stub), folder_name, 0, FALSE);
- if (!mfld)
- return;
-
- while (mfld->flag_timeout)
- process_flags (mfld);
- while (mfld->pending_delete_ops)
- g_main_context_iteration (NULL, TRUE);
-
- mail_stub_return_ok (stub);
-}
-
-static const gchar *sync_deleted_props[] = {
- PR_DELETED_COUNT_TOTAL,
- E2K_PR_DAV_VISIBLE_COUNT
-};
-static const gint n_sync_deleted_props = sizeof (sync_deleted_props) / sizeof (sync_deleted_props[0]);
-
-static gboolean
-sync_deletions (MailStubExchange *mse, MailStubExchangeFolder *mfld)
-{
- MailStub *stub = MAIL_STUB (mse);
- E2kHTTPStatus status;
- E2kResult *results;
- gint nresults = 0;
- const gchar *prop;
- gint deleted_count = -1, visible_count = -1, mode;
- E2kRestriction *rn;
- E2kResultIter *iter;
- E2kResult *result;
- gint my_i, read;
- MailStubExchangeMessage *mmsg;
- gboolean changes = FALSE;
- GHashTable *known_messages;
-
- exchange_component_is_offline (global_exchange_component, &mode);
- if (mode != ONLINE_MODE)
- return FALSE;
-
- status = e_folder_exchange_propfind (mfld->folder, NULL,
- sync_deleted_props,
- n_sync_deleted_props,
- &results, &nresults);
-
- if (!E2K_HTTP_STATUS_IS_SUCCESSFUL (status) || !nresults) {
- g_warning ("got_sync_deleted_props: %d", status);
- return FALSE;
- }
-
- prop = e2k_properties_get_prop (results[0].props,
- PR_DELETED_COUNT_TOTAL);
- if (prop)
- deleted_count = atoi (prop);
-
- prop = e2k_properties_get_prop (results[0].props,
- E2K_PR_DAV_VISIBLE_COUNT);
- if (prop)
- visible_count = atoi (prop);
-
- e2k_results_free (results, nresults);
-
- g_static_rec_mutex_lock (&g_changed_msgs_mutex);
- if (visible_count >= mfld->messages->len) {
- if (mfld->deleted_count == deleted_count) {
- g_static_rec_mutex_unlock (&g_changed_msgs_mutex);
- return FALSE;
- }
-
- if (mfld->deleted_count == 0) {
- mfld->deleted_count = deleted_count;
- g_static_rec_mutex_unlock (&g_changed_msgs_mutex);
- return FALSE;
- }
- }
-
- prop = E2K_PR_HTTPMAIL_READ;
- rn = e2k_restriction_andv (
- e2k_restriction_prop_bool (E2K_PR_DAV_IS_COLLECTION,
- E2K_RELOP_EQ, FALSE),
- e2k_restriction_prop_bool (E2K_PR_DAV_IS_HIDDEN,
- E2K_RELOP_EQ, FALSE),
- NULL);
-
- iter = e_folder_exchange_search_start (mfld->folder, NULL,
- &prop, 1, rn,
- E2K_PR_DAV_CREATION_DATE,
- FALSE);
- e2k_restriction_unref (rn);
-
- known_messages = g_hash_table_new (g_direct_hash, g_direct_equal);
-
- my_i = mfld->messages->len - 1;
- while ((result = e2k_result_iter_next (iter))) {
- mmsg = find_message_by_href (mfld, result->href);
- if (!mmsg) {
- /* oops, message from the server not found in our list;
- return failure to possibly do full resync again? */
- g_message ("%s: Oops, message %s not found in %s", G_STRFUNC, result->href, mfld->name);
- continue;
- }
-
- g_hash_table_insert (known_messages, mmsg, mmsg);
-
- /* See if its read flag changed while we weren't watching */
- prop = e2k_properties_get_prop (result->props,
- E2K_PR_HTTPMAIL_READ);
- read = (prop && atoi (prop)) ? MAIL_STUB_MESSAGE_SEEN : 0;
- if ((mmsg->flags & MAIL_STUB_MESSAGE_SEEN) != read) {
- changes = TRUE;
- change_flags (mfld, mmsg,
- mmsg->flags ^ MAIL_STUB_MESSAGE_SEEN);
- }
-
- }
- status = e2k_result_iter_free (iter);
-
- if (!E2K_HTTP_STATUS_IS_SUCCESSFUL (status))
- g_warning ("synced_deleted: %d", status);
-
- /* Clear out removed messages from mfld */
- for (my_i = mfld->messages->len - 1; my_i >= 0; my_i --) {
- mmsg = mfld->messages->pdata[my_i];
- if (!g_hash_table_lookup (known_messages, mmsg)) {
- mfld->deleted_count++;
- message_remove_at_index (stub, mfld, my_i);
- changes = TRUE;
- }
- }
-
- g_hash_table_destroy (known_messages);
- g_static_rec_mutex_unlock (&g_changed_msgs_mutex);
-
- if (changes)
- mail_stub_push_changes (stub);
-
- return changes;
-}
-
-struct refresh_message {
- gchar *uid, *href, *headers, *fff, *reply_by, *completed;
- guint32 flags, size, article_num;
-};
-
-static gint
-refresh_message_compar (gconstpointer a, gconstpointer b)
-{
- const struct refresh_message *rma = a, *rmb = b;
-
- return strcmp (rma->uid, rmb->uid);
-}
-
-static const gchar *mapi_message_props[] = {
- E2K_PR_MAILHEADER_SUBJECT,
- E2K_PR_MAILHEADER_FROM,
- E2K_PR_MAILHEADER_TO,
- E2K_PR_MAILHEADER_CC,
- E2K_PR_MAILHEADER_DATE,
- E2K_PR_MAILHEADER_RECEIVED,
- E2K_PR_MAILHEADER_MESSAGE_ID,
- E2K_PR_MAILHEADER_IN_REPLY_TO,
- E2K_PR_MAILHEADER_REFERENCES,
- E2K_PR_MAILHEADER_THREAD_INDEX,
- E2K_PR_DAV_CONTENT_TYPE
-};
-static const gint n_mapi_message_props = sizeof (mapi_message_props) / sizeof (mapi_message_props[0]);
-
-static const gchar *new_message_props[] = {
- E2K_PR_REPL_UID,
- PR_INTERNET_ARTICLE_NUMBER,
- PR_TRANSPORT_MESSAGE_HEADERS,
- E2K_PR_HTTPMAIL_READ,
- E2K_PR_HTTPMAIL_HAS_ATTACHMENT,
- PR_ACTION_FLAG,
- PR_IMPORTANCE,
- PR_DELEGATED_BY_RULE,
- E2K_PR_HTTPMAIL_MESSAGE_FLAG,
- E2K_PR_MAILHEADER_REPLY_BY,
- E2K_PR_MAILHEADER_COMPLETED,
- E2K_PR_DAV_CONTENT_LENGTH
-};
-static const gint num_new_message_props = sizeof (new_message_props) / sizeof (new_message_props[0]);
-static void
-refresh_folder_internal (MailStub *stub, MailStubExchangeFolder *mfld,
- gboolean background)
-{
- E2kRestriction *rn;
- GArray *messages;
- GHashTable *mapi_message_hash;
- GPtrArray *mapi_hrefs;
- gboolean has_read_flag = (mfld->access & MAPI_ACCESS_READ);
- E2kResultIter *iter;
- E2kResult *result;
- gchar *prop, *uid, *href;
- struct refresh_message rm, *rmp;
- E2kHTTPStatus status;
- gint got, total, i, n, mode;
- gpointer key, value;
- MailStubExchangeMessage *mmsg;
-
- g_object_ref (stub);
-
- exchange_component_is_offline (global_exchange_component, &mode);
- if (mode == OFFLINE_MODE) {
- if (background)
- mail_stub_push_changes (stub);
- else
- mail_stub_return_ok (stub);
-
- g_object_unref (stub); /* Is this needed ? */
- return;
- }
-
- messages = g_array_new (FALSE, FALSE, sizeof (struct refresh_message));
- mapi_message_hash = g_hash_table_new (g_str_hash, g_str_equal);
- mapi_hrefs = g_ptr_array_new ();
-
- /*
- * STEP 1: Fetch information about new messages, including SMTP
- * headers when available.
- */
-
- rn = e2k_restriction_andv (
- e2k_restriction_prop_bool (E2K_PR_DAV_IS_COLLECTION,
- E2K_RELOP_EQ, FALSE),
- e2k_restriction_prop_bool (E2K_PR_DAV_IS_HIDDEN,
- E2K_RELOP_EQ, FALSE),
- e2k_restriction_prop_int (PR_INTERNET_ARTICLE_NUMBER,
- E2K_RELOP_GT,
- mfld->high_article_num),
- NULL);
- iter = e_folder_exchange_search_start (mfld->folder, NULL,
- new_message_props,
- num_new_message_props,
- rn, NULL, TRUE);
- e2k_restriction_unref (rn);
-
- got = 0;
- total = e2k_result_iter_get_total (iter);
- while ((result = e2k_result_iter_next (iter))) {
- if (!E2K_HTTP_STATUS_IS_SUCCESSFUL (result->status)) {
- g_message ("%s: got unsuccessful at %s (%s)", G_STRFUNC, mfld->name, result->href ? result->href : "[null]");
- continue;
- }
-
- uid = e2k_properties_get_prop (result->props, E2K_PR_REPL_UID);
- if (!uid)
- continue;
- prop = e2k_properties_get_prop (result->props,
- PR_INTERNET_ARTICLE_NUMBER);
- if (!prop)
- continue;
-
- rm.uid = g_strdup (uidstrip (uid));
- rm.href = g_strdup (result->href);
- rm.article_num = strtoul (prop, NULL, 10);
-
- rm.flags = mail_util_props_to_camel_flags (result->props,
- has_read_flag);
-
- prop = e2k_properties_get_prop (result->props,
- E2K_PR_HTTPMAIL_MESSAGE_FLAG);
- if (prop)
- rm.fff = g_strdup (prop);
- else
- rm.fff = NULL;
- prop = e2k_properties_get_prop (result->props,
- E2K_PR_MAILHEADER_REPLY_BY);
- if (prop)
- rm.reply_by = g_strdup (prop);
- else
- rm.reply_by = NULL;
- prop = e2k_properties_get_prop (result->props,
- E2K_PR_MAILHEADER_COMPLETED);
- if (prop)
- rm.completed = g_strdup (prop);
- else
- rm.completed = NULL;
-
- prop = e2k_properties_get_prop (result->props,
- E2K_PR_DAV_CONTENT_LENGTH);
- rm.size = prop ? strtoul (prop, NULL, 10) : 0;
-
- rm.headers = mail_util_extract_transport_headers (result->props);
-
- g_array_append_val (messages, rm);
-
- if (rm.headers) {
- got++;
- mail_stub_return_progress (stub, (got * 100) / total);
- } else {
- href = strrchr (rm.href, '/');
- if (!href++)
- href = rm.href;
-
- g_hash_table_insert (mapi_message_hash, href,
- GINT_TO_POINTER (messages->len - 1));
- g_ptr_array_add (mapi_hrefs, href);
- }
- }
- status = e2k_result_iter_free (iter);
-
- if (!E2K_HTTP_STATUS_IS_SUCCESSFUL (status)) {
- g_warning ("got_new_smtp_messages: %d", status);
- if (!background)
- mail_stub_return_error (stub, _("Could not get new messages"));
- goto done;
- }
-
- if (mapi_hrefs->len == 0)
- goto return_data;
-
- /*
- * STEP 2: Fetch MAPI property data for non-SMTP messages.
- */
-
- iter = e_folder_exchange_bpropfind_start (mfld->folder, NULL,
- (const gchar **)mapi_hrefs->pdata,
- mapi_hrefs->len,
- mapi_message_props,
- n_mapi_message_props);
- while ((result = e2k_result_iter_next (iter))) {
- if (!E2K_HTTP_STATUS_IS_SUCCESSFUL (result->status))
- continue;
-
- href = strrchr (result->href, '/');
- if (!href++)
- href = result->href;
-
- if (!g_hash_table_lookup_extended (mapi_message_hash, href,
- &key, &value))
- continue;
- n = GPOINTER_TO_INT (value);
-
- rmp = &((struct refresh_message *)messages->data)[n];
- rmp->headers = mail_util_mapi_to_smtp_headers (result->props);
-
- got++;
- mail_stub_return_progress (stub, (got * 100) / total);
- }
- status = e2k_result_iter_free (iter);
-
- if (!E2K_HTTP_STATUS_IS_SUCCESSFUL (status)) {
- g_warning ("got_new_mapi_messages: %d", status);
- if (!background)
- mail_stub_return_error (stub, _("Could not get new messages"));
- goto done;
- }
-
- /*
- * STEP 3: Organize the data, update our records and Camel's
- */
-
- return_data:
- mail_stub_return_progress (stub, 100);
- mail_stub_return_data (stub, CAMEL_STUB_RETVAL_FREEZE_FOLDER,
- CAMEL_STUB_ARG_FOLDER, mfld->name,
- CAMEL_STUB_ARG_END);
-
- g_static_rec_mutex_lock (&g_changed_msgs_mutex);
- qsort (messages->data, messages->len,
- sizeof (rm), refresh_message_compar);
- for (i = 0; i < messages->len; i++) {
- rm = g_array_index (messages, struct refresh_message, i);
-
- /* If we already have a message with this UID, then
- * that means it's not a new message, it's just that
- * the article number changed.
- */
- mmsg = find_message (mfld, rm.uid);
- if (mmsg) {
- if (rm.flags != mmsg->flags)
- change_flags (mfld, mmsg, rm.flags);
- } else {
- if (g_hash_table_lookup (mfld->messages_by_href, rm.href)) {
- mfld->deleted_count++;
- message_removed (stub, mfld, rm.href);
- }
-
- mmsg = new_message (rm.uid, rm.href, mfld->seq++, rm.flags);
- g_ptr_array_add (mfld->messages, mmsg);
- g_hash_table_insert (mfld->messages_by_uid,
- mmsg->uid, mmsg);
- g_hash_table_insert (mfld->messages_by_href,
- mmsg->href, mmsg);
-
- if (!(mmsg->flags & MAIL_STUB_MESSAGE_SEEN))
- mfld->unread_count++;
-
- mail_stub_return_data (stub, CAMEL_STUB_RETVAL_NEW_MESSAGE,
- CAMEL_STUB_ARG_FOLDER, mfld->name,
- CAMEL_STUB_ARG_STRING, rm.uid,
- CAMEL_STUB_ARG_UINT32, rm.flags,
- CAMEL_STUB_ARG_UINT32, rm.size,
- CAMEL_STUB_ARG_STRING, rm.headers,
- CAMEL_STUB_ARG_STRING, rm.href,
- CAMEL_STUB_ARG_END);
- }
-
- if (rm.article_num > mfld->high_article_num) {
- mfld->high_article_num = rm.article_num;
- mail_stub_return_data (stub, CAMEL_STUB_RETVAL_FOLDER_SET_ARTICLE_NUM,
- CAMEL_STUB_ARG_FOLDER, mfld->name,
- CAMEL_STUB_ARG_UINT32, mfld->high_article_num,
- CAMEL_STUB_ARG_END);
- }
-
- if (rm.fff)
- return_tag (mfld, rm.uid, "follow-up", rm.fff);
- if (rm.reply_by)
- return_tag (mfld, rm.uid, "due-by", rm.reply_by);
- if (rm.completed)
- return_tag (mfld, rm.uid, "completed-on", rm.completed);
- }
- mail_stub_return_data (stub, CAMEL_STUB_RETVAL_THAW_FOLDER,
- CAMEL_STUB_ARG_FOLDER, mfld->name,
- CAMEL_STUB_ARG_END);
-
- mfld->scanned = TRUE;
- g_static_rec_mutex_unlock (&g_changed_msgs_mutex);
- folder_changed (mfld);
-
- if (background)
- mail_stub_push_changes (stub);
- else
- mail_stub_return_ok (stub);
-
- done:
- /*
- * CLEANUP
- */
- rmp = (struct refresh_message *)messages->data;
- for (i = 0; i < messages->len; i++) {
- g_free (rmp[i].uid);
- g_free (rmp[i].href);
- g_free (rmp[i].headers);
- g_free (rmp[i].fff);
- g_free (rmp[i].reply_by);
- g_free (rmp[i].completed);
- }
- g_array_free (messages, TRUE);
-
- g_hash_table_destroy (mapi_message_hash);
- g_ptr_array_free (mapi_hrefs, TRUE);
-
- g_object_unref (stub);
+ return TRUE;
}
-static void
-sync_count (MailStub *stub, const gchar *folder_name)
+static ExchangeFolder *
+folder_from_name (ExchangeData *ed, const gchar *folder_name, guint32 perms, CamelException *ex)
{
- MailStubExchange *mse = MAIL_STUB_EXCHANGE (stub);
- MailStubExchangeFolder *mfld;
- guint32 unread_count = 0, visible_count = 0;
+ ExchangeFolder *mfld;
- mfld = folder_from_name (mse, folder_name, 0, FALSE);
+ mfld = g_hash_table_lookup (ed->folders_by_name, folder_name);
if (!mfld) {
- mail_stub_return_data (stub, CAMEL_STUB_RETVAL_RESPONSE,
- CAMEL_STUB_ARG_UINT32, unread_count,
- CAMEL_STUB_ARG_UINT32, visible_count,
- CAMEL_STUB_ARG_END);
- mail_stub_return_ok (stub);
- return;
- }
-
- unread_count = mfld->unread_count;
- visible_count = mfld->messages->len;
-
- mail_stub_return_data (stub, CAMEL_STUB_RETVAL_RESPONSE,
- CAMEL_STUB_ARG_UINT32, unread_count,
- CAMEL_STUB_ARG_UINT32, visible_count,
- CAMEL_STUB_ARG_END);
- mail_stub_return_ok (stub);
-}
-
-static void
-refresh_folder (MailStub *stub, const gchar *folder_name)
-{
- MailStubExchange *mse = MAIL_STUB_EXCHANGE (stub);
- MailStubExchangeFolder *mfld;
-
- mfld = folder_from_name (mse, folder_name, 0, FALSE);
- if (!mfld)
- return;
-
- refresh_folder_internal (stub, mfld, FALSE);
- if (!sync_deletions (mse, mfld)) {
- /* sync_deletions didn't call this, thus call it now */
- mail_stub_push_changes (stub);
- }
-}
-
-static void
-expunge_uids (MailStub *stub, const gchar *folder_name, GPtrArray *uids)
-{
- MailStubExchange *mse = MAIL_STUB_EXCHANGE (stub);
- MailStubExchangeFolder *mfld;
- MailStubExchangeMessage *mmsg;
- GPtrArray *hrefs;
- E2kResultIter *iter;
- E2kResult *result;
- E2kHTTPStatus status;
- gint i, ndeleted;
- gboolean some_error = FALSE;
-
- if (!uids->len) {
- mail_stub_return_ok (stub);
- return;
- }
-
- mfld = folder_from_name (mse, folder_name, MAPI_ACCESS_DELETE, FALSE);
- if (!mfld)
- return;
-
- g_static_rec_mutex_lock (&g_changed_msgs_mutex);
- hrefs = g_ptr_array_new ();
- for (i = 0; i < uids->len; i++) {
- mmsg = find_message (mfld, uids->pdata[i]);
- if (mmsg)
- g_ptr_array_add (hrefs, strrchr (mmsg->href, '/') + 1);
+ set_exception (ex, _("No such folder"));
+ return NULL;
}
- if (!hrefs->len) {
- /* Can only happen if there's a bug somewhere else, but we
- * don't want to crash.
- */
- g_ptr_array_free (hrefs, TRUE);
- mail_stub_return_ok (stub);
- g_static_rec_mutex_unlock (&g_changed_msgs_mutex);
- return;
+ /* If sync_deletion_timeout is set, that means the user has been
+ * idle in Evolution for longer than a minute, during which
+ * time he has deleted messages using another email client,
+ * which we haven't bothered to sync up with yet. Do that now.
+ */
+ if (mfld->sync_deletion_timeout) {
+ g_source_remove (mfld->sync_deletion_timeout);
+ mfld->sync_deletion_timeout = 0;
+ sync_deletions (mfld);
}
- mail_stub_return_data (stub, CAMEL_STUB_RETVAL_FREEZE_FOLDER,
- CAMEL_STUB_ARG_FOLDER, mfld->name,
- CAMEL_STUB_ARG_END);
-
- iter = e_folder_exchange_bdelete_start (mfld->folder, NULL,
- (const gchar **)hrefs->pdata,
- hrefs->len);
- ndeleted = 0;
- while ((result = e2k_result_iter_next (iter))) {
- if (result->status == E2K_HTTP_UNAUTHORIZED) {
- some_error = TRUE;
- continue;
- }
- message_removed (stub, mfld, result->href);
- mfld->deleted_count++;
- ndeleted++;
-
- mail_stub_return_progress (stub, ndeleted * 100 / hrefs->len);
+ if ((perms == MAPI_ACCESS_MODIFY || perms == MAPI_ACCESS_DELETE) &&
+ !(mfld->access & perms)) {
+ /* try with MAPI_ACCESS_CREATE_CONTENTS */
+ perms = MAPI_ACCESS_CREATE_CONTENTS;
}
- status = e2k_result_iter_free (iter);
- g_static_rec_mutex_unlock (&g_changed_msgs_mutex);
- mail_stub_return_data (stub, CAMEL_STUB_RETVAL_THAW_FOLDER,
- CAMEL_STUB_ARG_FOLDER, mfld->name,
- CAMEL_STUB_ARG_END);
-
- if (!E2K_HTTP_STATUS_IS_SUCCESSFUL (status)) {
- g_warning ("expunged: %d", status);
- mail_stub_return_error (stub, _("Could not empty Deleted Items folder"));
- } else if (some_error) {
- mail_stub_return_error (stub, _("Permission denied. Could not delete certain messages."));
- } else {
- mail_stub_return_ok (stub);
+ if (perms && !(mfld->access & perms)) {
+ set_exception (ex, _("Permission denied"));
+ return NULL;
}
- g_ptr_array_free (hrefs, TRUE);
+ mfld->last_activity = time (NULL);
+ return mfld;
}
static void
@@ -1686,193 +1342,16 @@ mark_read (EFolder *folder, GPtrArray *hrefs, gboolean read)
}
static gboolean
-test_uri (E2kContext *ctx, const gchar *test_name, gpointer messages_by_href)
-{
- return g_hash_table_lookup (messages_by_href, test_name) == NULL;
-}
-
-static void
-append_message (MailStub *stub, const gchar *folder_name, guint32 flags,
- const gchar *subject, const gchar *data, gint length)
-{
- MailStubExchange *mse = MAIL_STUB_EXCHANGE (stub);
- MailStubExchangeFolder *mfld;
- E2kHTTPStatus status;
- gchar *ru_header = NULL, *repl_uid, *location = NULL;
-
- mfld = folder_from_name (mse, folder_name, MAPI_ACCESS_CREATE_CONTENTS, FALSE);
- if (!mfld)
- return;
-
- status = e_folder_exchange_put_new (mfld->folder, NULL, subject,
- test_uri, mfld->messages_by_href,
- "message/rfc822", data, length,
- &location, &ru_header);
- if (status != E2K_HTTP_CREATED) {
- g_warning ("appended_message: %d", status);
- mail_stub_return_error (stub,
- status == E2K_HTTP_INSUFFICIENT_SPACE_ON_RESOURCE ?
- _("Could not append message; mailbox is over quota") :
- _("Could not append message"));
- return;
- }
-
- if (location) {
- if (flags & MAIL_STUB_MESSAGE_SEEN)
- mark_one_read (mse->ctx, location, TRUE);
- else
- mark_one_read (mse->ctx, location, FALSE);
- }
-
- if (ru_header && *ru_header == '<' && strlen (ru_header) > 3)
- repl_uid = g_strndup (ru_header + 1, strlen (ru_header) - 2);
- else
- repl_uid = NULL;
- mail_stub_return_data (stub, CAMEL_STUB_RETVAL_RESPONSE,
- CAMEL_STUB_ARG_STRING, repl_uid ? uidstrip (repl_uid) : "",
- CAMEL_STUB_ARG_END);
-
- g_free (repl_uid);
- g_free (ru_header);
- g_free (location);
-
- mail_stub_return_ok (stub);
-}
-
-static inline void
-change_pending (MailStubExchangeFolder *mfld)
-{
- if (!mfld->pending_delete_ops && !mfld->changed_messages->len)
- g_object_ref (mfld->mse);
-}
-
-static inline void
-change_complete (MailStubExchangeFolder *mfld)
-{
- if (!mfld->pending_delete_ops && !mfld->changed_messages->len)
- g_object_unref (mfld->mse);
-}
-
-static void
-set_replied_flags (MailStubExchange *mse, MailStubExchangeMessage *mmsg)
-{
- E2kProperties *props;
- E2kHTTPStatus status;
-
- props = e2k_properties_new ();
-
- if (mmsg->change_flags & MAIL_STUB_MESSAGE_ANSWERED) {
- e2k_properties_set_int (props, PR_ACTION, MAPI_ACTION_REPLIED);
- e2k_properties_set_int (props, PR_ACTION_FLAG, (mmsg->change_flags & MAIL_STUB_MESSAGE_ANSWERED_ALL) ?
- MAPI_ACTION_FLAG_REPLIED_TO_ALL :
- MAPI_ACTION_FLAG_REPLIED_TO_SENDER);
- e2k_properties_set_date (props, PR_ACTION_DATE,
- e2k_make_timestamp (time (NULL)));
- } else {
- e2k_properties_remove (props, PR_ACTION);
- e2k_properties_remove (props, PR_ACTION_FLAG);
- e2k_properties_remove (props, PR_ACTION_DATE);
- }
-
- status = e2k_context_proppatch (mse->ctx, NULL, mmsg->href, props,
- FALSE, NULL);
- e2k_properties_free (props);
- if (!E2K_HTTP_STATUS_IS_SUCCESSFUL (status))
- g_warning ("set_replied_flags: %d", status);
-}
-
-static void
-set_important_flag (MailStubExchange *mse, MailStubExchangeMessage *mmsg)
-{
- E2kProperties *props;
- E2kHTTPStatus status;
-
- props = e2k_properties_new ();
-
- if (mmsg->change_flags & MAIL_STUB_MESSAGE_FLAGGED) {
- e2k_properties_set_int (props, PR_IMPORTANCE, MAPI_IMPORTANCE_HIGH);
- }
- else {
- e2k_properties_set_int (props, PR_IMPORTANCE, MAPI_IMPORTANCE_NORMAL);
- }
-
- status = e2k_context_proppatch (mse->ctx, NULL, mmsg->href, props,
- FALSE, NULL);
- e2k_properties_free (props);
- if (!E2K_HTTP_STATUS_IS_SUCCESSFUL (status))
- g_warning ("set_important_flag: %d", status);
-}
-
-static void
-update_tags (MailStubExchange *mse, MailStubExchangeMessage *mmsg)
-{
- E2kProperties *props;
- const gchar *value;
- gint flag_status;
- E2kHTTPStatus status;
-
- flag_status = MAPI_FOLLOWUP_UNFLAGGED;
- props = e2k_properties_new ();
-
- value = g_datalist_get_data (&mmsg->tag_updates, "follow-up");
- if (value) {
- if (*value) {
- e2k_properties_set_string (
- props, E2K_PR_HTTPMAIL_MESSAGE_FLAG,
- g_strdup (value));
- flag_status = MAPI_FOLLOWUP_FLAGGED;
- } else {
- e2k_properties_remove (
- props, E2K_PR_HTTPMAIL_MESSAGE_FLAG);
- }
- }
-
- value = g_datalist_get_data (&mmsg->tag_updates, "due-by");
- if (value) {
- if (*value) {
- e2k_properties_set_string (
- props, E2K_PR_MAILHEADER_REPLY_BY,
- g_strdup (value));
- } else {
- e2k_properties_remove (
- props, E2K_PR_MAILHEADER_REPLY_BY);
- }
- }
-
- value = g_datalist_get_data (&mmsg->tag_updates, "completed-on");
- if (value) {
- if (*value) {
- e2k_properties_set_string (
- props, E2K_PR_MAILHEADER_COMPLETED,
- g_strdup (value));
- flag_status = MAPI_FOLLOWUP_COMPLETED;
- } else {
- e2k_properties_remove (
- props, E2K_PR_MAILHEADER_COMPLETED);
- }
- }
- g_datalist_clear (&mmsg->tag_updates);
-
- e2k_properties_set_int (props, PR_FLAG_STATUS, flag_status);
-
- status = e2k_context_proppatch (mse->ctx, NULL, mmsg->href, props,
- FALSE, NULL);
- e2k_properties_free (props);
- if (!E2K_HTTP_STATUS_IS_SUCCESSFUL (status))
- g_warning ("update_tags: %d", status);
-}
-
-static gboolean
process_flags (gpointer user_data)
{
- MailStubExchangeFolder *mfld = user_data;
- MailStubExchange *mse = mfld->mse;
- MailStubExchangeMessage *mmsg;
+ ExchangeFolder *mfld = user_data;
+ ExchangeData *ed = mfld->ed;
+ ExchangeMessage *mmsg;
GPtrArray *seen = NULL, *unseen = NULL, *deleted = NULL;
gint i;
guint32 hier_type = e_folder_exchange_get_hierarchy (mfld->folder)->type;
- g_static_rec_mutex_lock (&g_changed_msgs_mutex);
+ g_static_rec_mutex_lock (&ed->changed_msgs_mutex);
for (i = 0; i < mfld->changed_messages->len; i++) {
mmsg = mfld->changed_messages->pdata[i];
@@ -1882,39 +1361,126 @@ process_flags (gpointer user_data)
__LINE__, mfld->name, mfld->type));
}
- if (mmsg->change_mask & MAIL_STUB_MESSAGE_SEEN) {
- if (mmsg->change_flags & MAIL_STUB_MESSAGE_SEEN) {
+ if (mmsg->change_mask & CAMEL_MESSAGE_SEEN) {
+ if (mmsg->change_flags & CAMEL_MESSAGE_SEEN) {
if (!seen)
seen = g_ptr_array_new ();
g_ptr_array_add (seen, g_strdup (strrchr (mmsg->href, '/') + 1));
- mmsg->flags |= MAIL_STUB_MESSAGE_SEEN;
+ mmsg->flags |= CAMEL_MESSAGE_SEEN;
} else {
if (!unseen)
unseen = g_ptr_array_new ();
g_ptr_array_add (unseen, g_strdup (strrchr (mmsg->href, '/') + 1));
- mmsg->flags &= ~MAIL_STUB_MESSAGE_SEEN;
+ mmsg->flags &= ~CAMEL_MESSAGE_SEEN;
}
- mmsg->change_mask &= ~MAIL_STUB_MESSAGE_SEEN;
+ mmsg->change_mask &= ~CAMEL_MESSAGE_SEEN;
}
- if (mmsg->change_mask & MAIL_STUB_MESSAGE_ANSWERED) {
- set_replied_flags (mse, mmsg);
- mmsg->change_mask &= ~(MAIL_STUB_MESSAGE_ANSWERED | MAIL_STUB_MESSAGE_ANSWERED_ALL);
+ if (mmsg->change_mask & CAMEL_MESSAGE_ANSWERED) {
+ E2kProperties *props;
+ E2kHTTPStatus status;
+
+ props = e2k_properties_new ();
+
+ if (mmsg->change_flags & CAMEL_MESSAGE_ANSWERED) {
+ e2k_properties_set_int (props, PR_ACTION, MAPI_ACTION_REPLIED);
+ e2k_properties_set_int (props, PR_ACTION_FLAG, (mmsg->change_flags & CAMEL_MESSAGE_ANSWERED_ALL) ?
+ MAPI_ACTION_FLAG_REPLIED_TO_ALL :
+ MAPI_ACTION_FLAG_REPLIED_TO_SENDER);
+ e2k_properties_set_date (props, PR_ACTION_DATE,
+ e2k_make_timestamp (time (NULL)));
+ } else {
+ e2k_properties_remove (props, PR_ACTION);
+ e2k_properties_remove (props, PR_ACTION_FLAG);
+ e2k_properties_remove (props, PR_ACTION_DATE);
+ }
+
+ status = e2k_context_proppatch (ed->ctx, NULL, mmsg->href, props, FALSE, NULL);
+
+ e2k_properties_free (props);
+
+ if (!E2K_HTTP_STATUS_IS_SUCCESSFUL (status))
+ g_warning ("set_replied_flags: %d", status);
+
+ mmsg->change_mask &= ~(CAMEL_MESSAGE_ANSWERED | CAMEL_MESSAGE_ANSWERED_ALL);
}
- if (mmsg->change_mask & MAIL_STUB_MESSAGE_FLAGGED) {
- set_important_flag (mse, mmsg);
- mmsg->change_mask &= ~MAIL_STUB_MESSAGE_FLAGGED;
+ if (mmsg->change_mask & CAMEL_MESSAGE_FLAGGED) {
+ E2kProperties *props;
+ E2kHTTPStatus status;
+
+ props = e2k_properties_new ();
+
+ if (mmsg->change_flags & CAMEL_MESSAGE_FLAGGED) {
+ e2k_properties_set_int (props, PR_IMPORTANCE, MAPI_IMPORTANCE_HIGH);
+ } else {
+ e2k_properties_set_int (props, PR_IMPORTANCE, MAPI_IMPORTANCE_NORMAL);
+ }
+
+ status = e2k_context_proppatch (ed->ctx, NULL, mmsg->href, props, FALSE, NULL);
+
+ e2k_properties_free (props);
+
+ if (!E2K_HTTP_STATUS_IS_SUCCESSFUL (status))
+ g_warning ("set_important_flag: %d", status);
+
+ mmsg->change_mask &= ~CAMEL_MESSAGE_FLAGGED;
}
- if (mmsg->tag_updates)
- update_tags (mse, mmsg);
+ if (mmsg->tag_updates) {
+ E2kProperties *props;
+ const gchar *value;
+ gint flag_status;
+ E2kHTTPStatus status;
+
+ flag_status = MAPI_FOLLOWUP_UNFLAGGED;
+ props = e2k_properties_new ();
+
+ value = g_datalist_get_data (&mmsg->tag_updates, "follow-up");
+ if (value) {
+ if (*value) {
+ e2k_properties_set_string (props, E2K_PR_HTTPMAIL_MESSAGE_FLAG, g_strdup (value));
+ flag_status = MAPI_FOLLOWUP_FLAGGED;
+ } else {
+ e2k_properties_remove (props, E2K_PR_HTTPMAIL_MESSAGE_FLAG);
+ }
+ }
+
+ value = g_datalist_get_data (&mmsg->tag_updates, "due-by");
+ if (value) {
+ if (*value) {
+ e2k_properties_set_string (props, E2K_PR_MAILHEADER_REPLY_BY, g_strdup (value));
+ } else {
+ e2k_properties_remove (props, E2K_PR_MAILHEADER_REPLY_BY);
+ }
+ }
+
+ value = g_datalist_get_data (&mmsg->tag_updates, "completed-on");
+ if (value) {
+ if (*value) {
+ e2k_properties_set_string (props, E2K_PR_MAILHEADER_COMPLETED, g_strdup (value));
+ flag_status = MAPI_FOLLOWUP_COMPLETED;
+ } else {
+ e2k_properties_remove (props, E2K_PR_MAILHEADER_COMPLETED);
+ }
+ }
+ g_datalist_clear (&mmsg->tag_updates);
+
+ e2k_properties_set_int (props, PR_FLAG_STATUS, flag_status);
+
+ status = e2k_context_proppatch (ed->ctx, NULL, mmsg->href, props, FALSE, NULL);
+
+ e2k_properties_free (props);
+
+ if (!E2K_HTTP_STATUS_IS_SUCCESSFUL (status))
+ g_warning ("update_tags: %d", status);
+ }
if (!mmsg->change_mask)
g_ptr_array_remove_index_fast (mfld->changed_messages, i--);
}
- g_static_rec_mutex_unlock (&g_changed_msgs_mutex);
+ g_static_rec_mutex_unlock (&ed->changed_msgs_mutex);
if (seen || unseen) {
if (seen) {
@@ -1930,39 +1496,38 @@ process_flags (gpointer user_data)
if (mfld->changed_messages->len == 0) {
mfld->flag_timeout = 0;
- change_complete (mfld);
+ /* change_complete (mfld); */
return FALSE;
} else
return TRUE;
}
- g_static_rec_mutex_lock (&g_changed_msgs_mutex);
+ g_static_rec_mutex_lock (&ed->changed_msgs_mutex);
for (i = 0; i < mfld->changed_messages->len; i++) {
mmsg = mfld->changed_messages->pdata[i];
- if (mmsg->change_mask & mmsg->change_flags & MAIL_STUB_MESSAGE_DELETED) {
+ if (mmsg->change_mask & mmsg->change_flags & CAMEL_MESSAGE_DELETED) {
if (!deleted)
deleted = g_ptr_array_new ();
g_ptr_array_add (deleted, strrchr (mmsg->href, '/') + 1);
}
}
- g_static_rec_mutex_unlock (&g_changed_msgs_mutex);
+ g_static_rec_mutex_unlock (&ed->changed_msgs_mutex);
if (deleted) {
- MailStub *stub = MAIL_STUB (mse);
+ CamelFolder *folder = get_camel_folder (mfld);
E2kResultIter *iter;
E2kResult *result;
E2kHTTPStatus status;
- change_pending (mfld);
+ /* change_pending (mfld); */
mfld->pending_delete_ops++;
- mail_stub_return_data (stub, CAMEL_STUB_RETVAL_FREEZE_FOLDER,
- CAMEL_STUB_ARG_FOLDER, mfld->name,
- CAMEL_STUB_ARG_END);
+ if (folder)
+ camel_folder_freeze (folder);
if (hier_type == EXCHANGE_HIERARCHY_PERSONAL) {
iter = e_folder_exchange_transfer_start (mfld->folder, NULL,
- mse->deleted_items,
+ ed->deleted_items,
deleted, TRUE);
} else {
/* This is for public folder hierarchy. We cannot move
@@ -1982,175 +1547,54 @@ process_flags (gpointer user_data)
continue;
}
} else if (result->status == E2K_HTTP_UNAUTHORIZED) {
- mail_stub_return_data (MAIL_STUB (mfld->mse),
- CAMEL_STUB_RETVAL_CHANGED_FLAGS_EX,
- CAMEL_STUB_ARG_FOLDER, mfld->name,
- CAMEL_STUB_ARG_STRING, mmsg->uid,
- CAMEL_STUB_ARG_UINT32, 0,
- CAMEL_STUB_ARG_UINT32, MAIL_STUB_MESSAGE_DELETED,
- CAMEL_STUB_ARG_END);
+ camel_exchange_folder_update_message_flags_ex (CAMEL_EXCHANGE_FOLDER (folder), mmsg->uid, 0, CAMEL_MESSAGE_DELETED);
continue;
}
- message_removed (stub, mfld, result->href);
+ message_removed (mfld, folder, result->href);
mfld->deleted_count++;
}
status = e2k_result_iter_free (iter);
- mail_stub_return_data (stub, CAMEL_STUB_RETVAL_THAW_FOLDER,
- CAMEL_STUB_ARG_FOLDER, mfld->name,
- CAMEL_STUB_ARG_END);
+ if (folder)
+ camel_folder_thaw (folder);
if (!E2K_HTTP_STATUS_IS_SUCCESSFUL (status))
g_warning ("deleted: %d", status);
- mail_stub_push_changes (stub);
mfld->pending_delete_ops--;
- change_complete (mfld);
+ /* change_complete (mfld); */
}
if (mfld->changed_messages->len) {
g_ptr_array_set_size (mfld->changed_messages, 0);
- change_complete (mfld);
+ /* change_complete (mfld); */
}
- mfld->flag_timeout = 0;
- return FALSE;
-}
-static void
-change_message (MailStubExchange *mse, MailStubExchangeFolder *mfld,
- MailStubExchangeMessage *mmsg)
-{
- gint i;
-
- g_static_rec_mutex_lock (&g_changed_msgs_mutex);
-
- for (i=0; i<mfld->changed_messages->len; i++) {
- if (mfld->changed_messages->pdata[i] == mmsg)
- break;
- }
-
- if (i == mfld->changed_messages->len) {
- change_pending (mfld);
- g_ptr_array_add (mfld->changed_messages, mmsg);
- }
- g_static_rec_mutex_unlock (&g_changed_msgs_mutex);
-
- if (mfld->flag_timeout)
- g_source_remove (mfld->flag_timeout);
- mfld->flag_timeout = g_timeout_add (1000, process_flags, mfld);
-}
-
-static void
-set_message_flags (MailStub *stub, const gchar *folder_name, const gchar *uid,
- guint32 flags, guint32 mask)
-{
- MailStubExchange *mse = MAIL_STUB_EXCHANGE (stub);
- MailStubExchangeFolder *mfld;
- MailStubExchangeMessage *mmsg;
-
- mfld = folder_from_name (mse, folder_name, MAPI_ACCESS_MODIFY, TRUE);
- if (!mfld)
- return;
-
- mmsg = find_message (mfld, uid);
- if (!mmsg)
- return;
-
- /* Although we don't actually process the flag change right
- * away, we need to update the folder's unread count to match
- * what the user now believes it is. (We take advantage of the
- * fact that the mailer will never delete a message without
- * also marking it read.)
- */
- if (mask & MAIL_STUB_MESSAGE_SEEN) {
- if (((mmsg->flags ^ flags) & MAIL_STUB_MESSAGE_SEEN) == 0) {
- /* The user is just setting it to what it
- * already is, so ignore it.
- */
- mask &= ~MAIL_STUB_MESSAGE_SEEN;
- } else {
- mmsg->flags ^= MAIL_STUB_MESSAGE_SEEN;
- if (mmsg->flags & MAIL_STUB_MESSAGE_SEEN)
- mfld->unread_count--;
- else
- mfld->unread_count++;
- folder_changed (mfld);
- }
- }
-
- /* If the user tries to delete a message in a non-person
- * hierarchy, we ignore it (which will cause camel to delete
- * it the hard way next time it syncs).
- */
-
-#if 0
- /* If we allow camel stub to delete these messages hard way, it may
- fail to delete a mail because of permissions, but will append
- a mail in deleted items */
-
- if (mask & flags & MAIL_STUB_MESSAGE_DELETED) {
- ExchangeHierarchy *hier;
-
- hier = e_folder_exchange_get_hierarchy (mfld->folder);
- if (hier->type != EXCHANGE_HIERARCHY_PERSONAL)
- mask &= ~MAIL_STUB_MESSAGE_DELETED;
- }
-#endif
-
- /* If there's nothing left to change, return. */
- if (!mask)
- return;
-
- mmsg->change_flags |= (flags & mask);
- mmsg->change_flags &= ~(~flags & mask);
- mmsg->change_mask |= mask;
-
- change_message (mse, mfld, mmsg);
-}
-
-static void
-set_message_tag (MailStub *stub, const gchar *folder_name, const gchar *uid,
- const gchar *name, const gchar *value)
-{
- MailStubExchange *mse = MAIL_STUB_EXCHANGE (stub);
- MailStubExchangeFolder *mfld;
- MailStubExchangeMessage *mmsg;
-
- mfld = folder_from_name (mse, folder_name, MAPI_ACCESS_MODIFY, TRUE);
- if (!mfld)
- return;
-
- mmsg = find_message (mfld, uid);
- if (!mmsg)
- return;
+ mfld->flag_timeout = 0;
- g_datalist_set_data_full (&mmsg->tag_updates, name,
- g_strdup (value), g_free);
- change_message (mse, mfld, mmsg);
+ return FALSE;
}
-static const gchar *stickynote_props[] = {
- E2K_PR_MAILHEADER_SUBJECT,
- E2K_PR_DAV_LAST_MODIFIED,
- E2K_PR_OUTLOOK_STICKYNOTE_COLOR,
- E2K_PR_OUTLOOK_STICKYNOTE_HEIGHT,
- E2K_PR_OUTLOOK_STICKYNOTE_WIDTH,
- E2K_PR_HTTPMAIL_TEXT_DESCRIPTION,
-};
-static const gint n_stickynote_props = sizeof (stickynote_props) / sizeof (stickynote_props[0]);
-
static E2kHTTPStatus
-get_stickynote (E2kContext *ctx, E2kOperation *op, const gchar *uri,
- gchar **body, gint *len)
+get_stickynote (E2kContext *ctx, E2kOperation *op, const gchar *uri, gchar **body, gint *len)
{
+ static const gchar *stickynote_props[] = {
+ E2K_PR_MAILHEADER_SUBJECT,
+ E2K_PR_DAV_LAST_MODIFIED,
+ E2K_PR_OUTLOOK_STICKYNOTE_COLOR,
+ E2K_PR_OUTLOOK_STICKYNOTE_HEIGHT,
+ E2K_PR_OUTLOOK_STICKYNOTE_WIDTH,
+ E2K_PR_HTTPMAIL_TEXT_DESCRIPTION,
+ };
+
E2kHTTPStatus status;
E2kResult *results;
gint nresults = 0;
GString *message;
status = e2k_context_propfind (ctx, op, uri,
- stickynote_props, n_stickynote_props,
+ stickynote_props, G_N_ELEMENTS (stickynote_props),
&results, &nresults);
if (E2K_HTTP_STATUS_IS_SUCCESSFUL (status)) {
@@ -2165,9 +1609,7 @@ get_stickynote (E2kContext *ctx, E2kOperation *op, const gchar *uri,
}
static E2kHTTPStatus
-build_message_from_document (E2kContext *ctx, E2kOperation *op,
- const gchar *uri,
- gchar **body, gint *len)
+build_message_from_document (E2kContext *ctx, E2kOperation *op, const gchar *uri, gchar **body, gint *len)
{
E2kHTTPStatus status;
E2kResult *results;
@@ -2175,10 +1617,7 @@ build_message_from_document (E2kContext *ctx, E2kOperation *op,
GString *message;
gchar *headers;
- status = e2k_context_propfind (ctx, op, uri,
- mapi_message_props,
- n_mapi_message_props,
- &results, &nresults);
+ status = e2k_context_propfind (ctx, op, uri, mapi_message_props, G_N_ELEMENTS (mapi_message_props), &results, &nresults);
if (!E2K_HTTP_STATUS_IS_SUCCESSFUL (status))
return status;
if (!nresults)
@@ -2200,9 +1639,7 @@ build_message_from_document (E2kContext *ctx, E2kOperation *op,
}
static E2kHTTPStatus
-unmangle_delegated_meeting_request (MailStubExchange *mse, E2kOperation *op,
- const gchar *uri,
- gchar **body, gint *len)
+unmangle_delegated_meeting_request (ExchangeData *ed, E2kOperation *op, const gchar *uri, gchar **body, gint *len)
{
const gchar *prop = PR_RCVD_REPRESENTING_EMAIL_ADDRESS;
GString *message;
@@ -2217,8 +1654,7 @@ unmangle_delegated_meeting_request (MailStubExchange *mse, E2kOperation *op,
gint nresults = 0;
MailUtilDemangleType unmangle_type = MAIL_UTIL_DEMANGLE_DELGATED_MEETING;
- status = e2k_context_propfind (mse->ctx, op, uri, &prop, 1,
- &results, &nresults);
+ status = e2k_context_propfind (ed->ctx, op, uri, &prop, 1, &results, &nresults);
if (!E2K_HTTP_STATUS_IS_SUCCESSFUL (status))
return status;
if (!nresults)
@@ -2230,7 +1666,7 @@ unmangle_delegated_meeting_request (MailStubExchange *mse, E2kOperation *op,
return E2K_HTTP_OK;
}
- account = mse->account;
+ account = ed->account;
gc = exchange_account_get_global_catalog (account);
if (!gc) {
g_warning ("\nNo GC: could not unmangle meeting request");
@@ -2277,10 +1713,38 @@ unmangle_delegated_meeting_request (MailStubExchange *mse, E2kOperation *op,
return E2K_HTTP_OK;
}
+static gboolean
+is_foreign_folder (ExchangeData *ed, const gchar *folder_name, gchar **owner_email)
+{
+ EFolder *folder;
+ ExchangeHierarchy *hier;
+ gchar *path;
+
+ path = g_build_filename ("/", folder_name, NULL);
+ folder = exchange_account_get_folder (ed->account, path);
+ if (!folder) {
+ g_free (path);
+ return FALSE;
+ }
+
+ g_free (path);
+ g_object_ref (folder);
+
+ hier = e_folder_exchange_get_hierarchy (folder);
+
+ if (hier->type != EXCHANGE_HIERARCHY_FOREIGN) {
+ g_object_unref (folder);
+ return FALSE;
+ }
+
+ *owner_email = g_strdup (hier->owner_email);
+
+ g_object_unref (folder);
+ return TRUE;
+}
+
static E2kHTTPStatus
-unmangle_meeting_request_in_subscribed_inbox (MailStubExchange *mse,
- const gchar *delegator_email,
- gchar **body, gint *len)
+unmangle_meeting_request_in_subscribed_inbox (ExchangeData *ed, const gchar *delegator_email, gchar **body, gint *len)
{
GString *message;
gchar *delegator_uri, *delegator_folder_physical_uri = NULL;
@@ -2291,7 +1755,7 @@ unmangle_meeting_request_in_subscribed_inbox (MailStubExchange *mse,
EFolder *folder = NULL;
MailUtilDemangleType unmangle_type = MAIL_UTIL_DEMANGLE_MEETING_IN_SUBSCRIBED_INBOX;
- account = mse->account;
+ account = ed->account;
gc = exchange_account_get_global_catalog (account);
if (!gc) {
g_warning ("\nNo GC: could not unmangle meeting request in subscribed folder");
@@ -2336,9 +1800,7 @@ unmangle_meeting_request_in_subscribed_inbox (MailStubExchange *mse,
}
static E2kHTTPStatus
-unmangle_sender_field (MailStubExchange *mse, E2kOperation *op,
- const gchar *uri,
- gchar **body, gint *len)
+unmangle_sender_field (ExchangeData *ed, E2kOperation *op, const gchar *uri, gchar **body, gint *len)
{
const gchar *props[] = { PR_SENT_REPRESENTING_EMAIL_ADDRESS, PR_SENDER_EMAIL_ADDRESS };
GString *message;
@@ -2353,8 +1815,7 @@ unmangle_sender_field (MailStubExchange *mse, E2kOperation *op,
gint nresults = 0;
MailUtilDemangleType unmangle_type = MAIL_UTIL_DEMANGLE_SENDER_FIELD;
- status = e2k_context_propfind (mse->ctx, op, uri, props, 2,
- &results, &nresults);
+ status = e2k_context_propfind (ed->ctx, op, uri, props, 2, &results, &nresults);
if (!E2K_HTTP_STATUS_IS_SUCCESSFUL (status))
return status;
if (!nresults)
@@ -2377,7 +1838,7 @@ unmangle_sender_field (MailStubExchange *mse, E2kOperation *op,
return E2K_HTTP_OK;
}
- account = mse->account;
+ account = ed->account;
gc = exchange_account_get_global_catalog (account);
if (!gc) {
g_warning ("\nNo GC: could not unmangle sender field");
@@ -2425,73 +1886,752 @@ unmangle_sender_field (MailStubExchange *mse, E2kOperation *op,
return E2K_HTTP_OK;
}
-static gboolean
-is_foreign_folder (MailStub *stub, const gchar *folder_name, gchar **owner_email)
+static void
+get_folder_info_data (ExchangeData *ed, const gchar *top, guint32 store_flags, GPtrArray **names, GPtrArray **uris, GArray **unread, GArray **flags)
{
- MailStubExchange *mse = MAIL_STUB_EXCHANGE (stub);
- EFolder *folder;
+ GPtrArray *folders = NULL;
ExchangeHierarchy *hier;
+ EFolder *folder;
+ const gchar *type, *name, *uri, *inbox_uri = NULL, *trash_uri = NULL, *sent_items_uri = NULL;
+ gint unread_count, i, toplen = top ? strlen (top) : 0;
+ guint32 folder_flags = 0;
+ gboolean recursive, subscribed, subscription_list;
+ gint mode = -1;
+ gchar *full_path;
+
+ recursive = (store_flags & CAMEL_STORE_FOLDER_INFO_RECURSIVE);
+ subscribed = (store_flags & CAMEL_STORE_FOLDER_INFO_SUBSCRIBED);
+ subscription_list = (store_flags & CAMEL_STORE_FOLDER_INFO_SUBSCRIPTION_LIST);
+
+ mode = is_online (ed);
+ if (!subscribed && subscription_list) {
+ ExchangeAccountResult result = -1;
+
+ d(g_print ("%s(%d):%s: NOT SUBSCRIBED top = [%s]\n", __FILE__, __LINE__, __GNUC_PRETTY_FUNCTION__, top));
+ if (!toplen)
+ result = exchange_account_open_folder (ed->account, "/public");
+ if (result == EXCHANGE_ACCOUNT_FOLDER_DOES_NOT_EXIST) {
+ hier = exchange_account_get_hierarchy_by_type (ed->account, EXCHANGE_HIERARCHY_PUBLIC);
+ if (hier)
+ exchange_hierarchy_scan_subtree (hier, hier->toplevel, mode);
+ } else {
+ d(g_print ("%s(%d):%s: NOT SUBSCRIBED - open_folder returned = [%d]\n", __FILE__, __LINE__, __GNUC_PRETTY_FUNCTION__, result));
+ }
+ }
+
+ /* No need to check for recursive flag, as I will always be returning a tree, instead of a single folder info object */
+ if (toplen) {
+ d(g_print ("%s(%d):%s: NOT RECURSIVE and toplen top = [%s]\n", __FILE__, __LINE__, __GNUC_PRETTY_FUNCTION__, top));
+ full_path = g_strdup_printf ("/%s", top);
+ folders = exchange_account_get_folder_tree (ed->account, full_path);
+ g_free (full_path);
+ } else {
+ d(g_print ("%s(%d):%s calling exchange_account_get_folders \n", __FILE__, __LINE__,
+ __GNUC_PRETTY_FUNCTION__));
+ folders = exchange_account_get_folders (ed->account);
+ }
+
+ *names = g_ptr_array_new ();
+ *uris = g_ptr_array_new ();
+ *unread = g_array_new (FALSE, FALSE, sizeof (gint));
+ *flags = g_array_new (FALSE, FALSE, sizeof (gint));
+ /* Can be NULL if started in offline mode */
+ if (ed->inbox) {
+ inbox_uri = e_folder_get_physical_uri (ed->inbox);
+ }
+
+ if (ed->deleted_items) {
+ trash_uri = e_folder_get_physical_uri (ed->deleted_items);
+ }
+
+ if (ed->sent_items) {
+ sent_items_uri = e_folder_get_physical_uri (ed->sent_items);
+ }
+
+ if (folders) {
+ for (i = 0; i < folders->len; i++) {
+ folder = folders->pdata[i];
+ hier = e_folder_exchange_get_hierarchy (folder);
+ folder_flags = 0;
+
+ if (subscribed) {
+ if (hier->type != EXCHANGE_HIERARCHY_PERSONAL &&
+ hier->type != EXCHANGE_HIERARCHY_FAVORITES &&
+ hier->type != EXCHANGE_HIERARCHY_FOREIGN)
+ continue;
+ } else if (subscription_list) {
+ if (hier->type != EXCHANGE_HIERARCHY_PUBLIC)
+ continue;
+ }
+
+ type = e_folder_get_type_string (folder);
+ name = e_folder_get_name (folder);
+ uri = e_folder_get_physical_uri (folder);
+ d(g_print ("Uri: %s\n", uri));
+ d(g_print ("folder type is : %s\n", type));
+
+ if (!strcmp (type, "noselect")) {
+ unread_count = 0;
+ folder_flags = CAMEL_FOLDER_NOSELECT;
+ }
+
+ switch (hier->type) {
+ case EXCHANGE_HIERARCHY_FAVORITES:
+ /* folder_flags will be set only if the type
+ is noselect and we need to include it */
+ if (strcmp (type, "mail") && !folder_flags)
+ continue;
+ /* selectable */
+ if (!folder_flags)
+ unread_count = e_folder_get_unread_count (folder);
+ case EXCHANGE_HIERARCHY_PUBLIC:
+ if (exchange_account_is_favorite_folder (ed->account, folder)) {
+ folder_flags |= CAMEL_FOLDER_SUBSCRIBED;
+ d(printf ("marked the folder as subscribed\n"));
+ }
+ break;
+ case EXCHANGE_HIERARCHY_FOREIGN:
+ if (folder_flags & CAMEL_FOLDER_NOSELECT && ed->new_folder_id == 0) {
+ /* Rescan the hierarchy - as we don't rescan
+ foreign hierarchies anywhere for mailer and
+ only when we are starting up
+ */
+ exchange_hierarchy_scan_subtree (hier, hier->toplevel, mode);
+ }
+ case EXCHANGE_HIERARCHY_PERSONAL:
+ if (!strcmp (type, "mail")) {
+ unread_count = e_folder_get_unread_count (folder);
+ }
+ else if (!folder_flags) {
+ continue;
+ }
+ break;
+ default:
+ break;
+ }
+
+ if (inbox_uri && !strcmp (uri, inbox_uri))
+ folder_flags |= CAMEL_FOLDER_SYSTEM | CAMEL_FOLDER_TYPE_INBOX;
+
+ if (trash_uri && !strcmp (uri, trash_uri))
+ folder_flags |= CAMEL_FOLDER_SYSTEM | CAMEL_FOLDER_TYPE_TRASH;
+
+ if (sent_items_uri && !strcmp (uri, sent_items_uri))
+ folder_flags |= CAMEL_FOLDER_SYSTEM | CAMEL_FOLDER_TYPE_SENT;
+
+ if (!e_folder_exchange_get_has_subfolders (folder)) {
+ d(printf ("%s:%d:%s - %s has no subfolders", __FILE__, __LINE__, __GNUC_PRETTY_FUNCTION__,
+ name));
+ folder_flags |= CAMEL_FOLDER_NOCHILDREN;
+ }
+
+ d(g_print ("folder flags is : %d\n", folder_flags));
+
+ g_ptr_array_add (*names, g_strdup (name));
+ g_ptr_array_add (*uris, g_strdup (uri));
+ g_array_append_val (*unread, unread_count);
+ g_array_append_val (*flags, folder_flags);
+ }
+
+ g_ptr_array_free (folders, TRUE);
+ }
+}
+
+struct update_linestatus
+{
+ CamelExchangeStore *estore;
+ gint linestatus;
+ CamelException *ex;
+};
+
+static void
+folder_update_linestatus (gpointer key, gpointer value, gpointer data)
+{
+ ExchangeFolder *mfld = (ExchangeFolder *) value;
+ struct update_linestatus *ul = (struct update_linestatus *) data;
+ guint32 readonly;
+
+ g_return_if_fail (ul != NULL);
+
+ if (ul->linestatus == ONLINE_MODE) {
+ CamelFolder *folder;
+
+ get_folder_online (mfld, ul->ex);
+
+ readonly = (mfld->access & (MAPI_ACCESS_MODIFY | MAPI_ACCESS_CREATE_CONTENTS)) ? 0 : 1;
+
+ folder = get_camel_folder (mfld);
+ if (folder) {
+ camel_exchange_summary_set_readonly (folder->summary, readonly ? TRUE : FALSE);
+ }
+ } else {
+ /* FIXME: need any undo for offline */ ;
+ }
+}
+
+gboolean
+camel_exchange_utils_connect (CamelService *service,
+ const gchar *pwd,
+ guint32 *status, /* out */
+ CamelException *ex)
+{
+ ExchangeData *ed = get_data_for_service (service);
+ ExchangeAccount *account;
+ ExchangeAccountResult result;
+ E2kContext *ctx;
+ guint32 retval = 1;
+ const gchar *uri;
+ gint mode;
+
+ g_return_val_if_fail (ed != NULL, FALSE);
+ g_return_val_if_fail (status != NULL, FALSE);
+
+ mode = is_online (ed);
+
+ account = ed->account;
+ if (mode == ONLINE_MODE)
+ exchange_account_set_online (account);
+ else if (mode == OFFLINE_MODE)
+ exchange_account_set_offline (account);
+
+ ctx = exchange_account_get_context (account);
+ if (!ctx) {
+ ctx = exchange_account_connect (account, pwd, &result);
+ }
+
+ if (!ctx && mode == ONLINE_MODE) {
+ retval = 0;
+ goto end;
+ } else if (mode == OFFLINE_MODE) {
+ goto end;
+ }
+
+ ed->ctx = g_object_ref (ctx);
+
+ ed->mail_submission_uri = exchange_account_get_standard_uri (account, "sendmsg");
+ uri = exchange_account_get_standard_uri (account, "inbox");
+ ed->inbox = exchange_account_get_folder (account, uri);
+ uri = exchange_account_get_standard_uri (account, "deleteditems");
+ ed->deleted_items = exchange_account_get_folder (account, uri);
+ uri = exchange_account_get_standard_uri (account, "sentitems");
+ ed->sent_items = exchange_account_get_folder (account, uri);
+
+ /* Will be used for offline->online transition to initialize things for
+ the first time */
+
+ g_hash_table_foreach (ed->folders_by_name,
+ (GHFunc) folder_update_linestatus,
+ GINT_TO_POINTER (mode));
+ end:
+ *status = retval;
+
+ return TRUE;
+}
+
+gboolean
+camel_exchange_utils_get_folder (CamelService *service,
+ const gchar *name,
+ gboolean create,
+ GPtrArray *uids,
+ GByteArray *flags,
+ GPtrArray *hrefs,
+ guint32 high_article_num,
+ guint32 *folder_flags, /* out */
+ gchar **folder_uri, /* out */
+ gboolean *readonly, /* out */
+ CamelException *ex)
+{
+ ExchangeData *ed = get_data_for_service (service);
+ ExchangeFolder *mfld;
+ ExchangeMessage *mmsg;
+ EFolder *folder;
gchar *path;
+ const gchar *outlook_class;
+ guint32 camel_flags;
+ gint i;
+ ExchangeHierarchy *hier;
- path = g_build_filename ("/", folder_name, NULL);
- folder = exchange_account_get_folder (mse->account, path);
- if (!folder) {
+ g_return_val_if_fail (ed != NULL, FALSE);
+ g_return_val_if_fail (folder_flags != NULL, FALSE);
+ g_return_val_if_fail (folder_uri != NULL, FALSE);
+ g_return_val_if_fail (readonly != NULL, FALSE);
+
+ path = g_strdup_printf ("/%s", name);
+ folder = exchange_account_get_folder (ed->account, path);
+ if (!folder && !create) {
+ set_exception (ex, _("No such folder"));
g_free (path);
return FALSE;
+ } else if (!folder) {
+ ExchangeAccountFolderResult result;
+
+ result = exchange_account_create_folder (ed->account, path, "mail");
+ folder = exchange_account_get_folder (ed->account, path);
+ if (result != EXCHANGE_ACCOUNT_FOLDER_OK || !folder) {
+ set_exception (ex, _("Could not create folder."));
+ g_free (path);
+ return FALSE;
+ }
}
g_free (path);
+
+ mfld = g_new0 (ExchangeFolder, 1);
+ mfld->ed = ed;
+ mfld->folder = folder;
g_object_ref (folder);
+ mfld->name = e_folder_exchange_get_path (folder) + 1;
- hier = e_folder_exchange_get_hierarchy (folder);
+ if (!strcmp (e_folder_get_type_string (folder), "mail/public"))
+ mfld->type = EXCHANGE_FOLDER_POST;
+ else {
+ outlook_class = e_folder_exchange_get_outlook_class (folder);
+ if (!outlook_class)
+ mfld->type = EXCHANGE_FOLDER_OTHER;
+ else if (!g_ascii_strncasecmp (outlook_class, "IPF.Note", 8))
+ mfld->type = EXCHANGE_FOLDER_REAL;
+ else if (!g_ascii_strncasecmp (outlook_class, "IPF.Post", 8))
+ mfld->type = EXCHANGE_FOLDER_POST;
+ else if (!g_ascii_strncasecmp (outlook_class, "IPF.StickyNote", 14))
+ mfld->type = EXCHANGE_FOLDER_NOTES;
+ else
+ mfld->type = EXCHANGE_FOLDER_OTHER;
+ }
- if (hier->type != EXCHANGE_HIERARCHY_FOREIGN) {
- g_object_unref (folder);
+ mfld->messages = g_ptr_array_new ();
+ mfld->messages_by_uid = g_hash_table_new (g_str_hash, g_str_equal);
+ mfld->messages_by_href = g_hash_table_new (g_str_hash, g_str_equal);
+ for (i = 0; i < uids->len; i++) {
+ mmsg = new_message (uids->pdata[i], NULL, mfld->seq++, flags->data[i]);
+ g_ptr_array_add (mfld->messages, mmsg);
+ g_hash_table_insert (mfld->messages_by_uid, mmsg->uid, mmsg);
+
+ if (hrefs->pdata[i] && *((gchar *)hrefs->pdata[i])) {
+ mmsg->href = g_strdup (hrefs->pdata[i]);
+ g_hash_table_insert (mfld->messages_by_href, mmsg->href, mmsg);
+ }
+ if (!(mmsg->flags & CAMEL_MESSAGE_SEEN))
+ mfld->unread_count++;
+ }
+
+ mfld->high_article_num = high_article_num;
+
+ if (is_online (ed) == ONLINE_MODE) {
+ if (!get_folder_online (mfld, ex)) {
+ return FALSE;
+ }
+ }
+ g_signal_connect (mfld->folder, "changed",
+ G_CALLBACK (storage_folder_changed), mfld);
+
+ g_hash_table_insert (ed->folders_by_name, (gchar *)mfld->name, mfld);
+ folder_changed (mfld);
+
+ *readonly = ((mfld->access & (MAPI_ACCESS_MODIFY | MAPI_ACCESS_CREATE_CONTENTS)) == 0);
+
+ camel_flags = 0;
+ if (ed->account->filter_inbox && (mfld->folder == ed->inbox))
+ camel_flags |= CAMEL_FOLDER_FILTER_RECENT;
+ if (ed->account->filter_junk) {
+ if ((mfld->folder != ed->deleted_items) &&
+ ((mfld->folder == ed->inbox) ||
+ !ed->account->filter_junk_inbox_only))
+ camel_flags |= CAMEL_FOLDER_FILTER_JUNK;
+ }
+
+ hier = e_folder_exchange_get_hierarchy (mfld->folder);
+
+ *folder_flags = camel_flags;
+ *folder_uri = g_strdup (hier->source_uri);
+
+ return TRUE;
+}
+
+gboolean
+camel_exchange_utils_get_trash_name (CamelService *service,
+ gchar **trash_name, /* out */
+ CamelException *ex)
+{
+ ExchangeData *ed = get_data_for_service (service);
+
+ g_return_val_if_fail (ed != NULL, FALSE);
+ g_return_val_if_fail (trash_name != NULL, FALSE);
+
+ if (!ed->deleted_items) {
+ set_exception (ex, _("Could not open Deleted Items folder"));
return FALSE;
}
- *owner_email = g_strdup (hier->owner_email);
+ *trash_name = g_strdup (e_folder_exchange_get_path (ed->deleted_items) + 1);
+
+ return TRUE;
+}
+
+gboolean
+camel_exchange_utils_refresh_folder (CamelService *service,
+ const gchar *folder_name,
+ CamelException *ex)
+{
+ ExchangeData *ed = get_data_for_service (service);
+ ExchangeFolder *mfld;
+
+ g_return_val_if_fail (ed != NULL, FALSE);
+
+ mfld = folder_from_name (ed, folder_name, 0, ex);
+ if (!mfld) {
+ return FALSE;
+ }
+
+ refresh_folder_internal (mfld, ex);
+ sync_deletions (mfld);
+
+ return TRUE;
+}
+
+gboolean
+camel_exchange_utils_sync_count (CamelService *service,
+ const gchar *folder_name,
+ guint32 *unread_count, /* out */
+ guint32 *visible_count, /* out */
+ CamelException *ex)
+{
+ ExchangeData *ed = get_data_for_service (service);
+ ExchangeFolder *mfld;
+
+ g_return_val_if_fail (ed != NULL, FALSE);
+ g_return_val_if_fail (unread_count != NULL, FALSE);
+ g_return_val_if_fail (visible_count != NULL, FALSE);
+
+ mfld = folder_from_name (ed, folder_name, 0, ex);
+ if (mfld) {
+ *unread_count = mfld->unread_count;
+ *visible_count = mfld->messages->len;
+ } else {
+ *unread_count = 0;
+ *visible_count = 0;
+ }
+
+ return TRUE;
+}
+
+gboolean
+camel_exchange_utils_expunge_uids (CamelService *service,
+ const gchar *folder_name,
+ GPtrArray *uids,
+ CamelException *ex)
+{
+ ExchangeData *ed = get_data_for_service (service);
+ ExchangeFolder *mfld;
+ ExchangeMessage *mmsg;
+ GPtrArray *hrefs;
+ E2kResultIter *iter;
+ E2kResult *result;
+ E2kHTTPStatus status;
+ gint i, ndeleted;
+ gboolean some_error = FALSE;
+ CamelFolder *folder;
+
+ g_return_val_if_fail (ed != NULL, FALSE);
+
+ if (!uids->len)
+ return TRUE;
+
+ mfld = folder_from_name (ed, folder_name, MAPI_ACCESS_DELETE, ex);
+ if (!mfld)
+ return FALSE;
+
+ g_static_rec_mutex_lock (&ed->changed_msgs_mutex);
+ hrefs = g_ptr_array_new ();
+ for (i = 0; i < uids->len; i++) {
+ mmsg = find_message (mfld, uids->pdata[i]);
+ if (mmsg)
+ g_ptr_array_add (hrefs, strrchr (mmsg->href, '/') + 1);
+ }
+
+ if (!hrefs->len) {
+ /* Can only happen if there's a bug somewhere else, but we
+ * don't want to crash.
+ */
+ g_ptr_array_free (hrefs, TRUE);
+ g_static_rec_mutex_unlock (&ed->changed_msgs_mutex);
+ return TRUE;
+ }
+
+ folder = get_camel_folder (mfld);
+ if (folder)
+ camel_folder_freeze (folder);
+
+ iter = e_folder_exchange_bdelete_start (mfld->folder, NULL,
+ (const gchar **)hrefs->pdata,
+ hrefs->len);
+ ndeleted = 0;
+ while ((result = e2k_result_iter_next (iter))) {
+ if (result->status == E2K_HTTP_UNAUTHORIZED) {
+ some_error = TRUE;
+ continue;
+ }
+ message_removed (mfld, folder, result->href);
+ mfld->deleted_count++;
+ ndeleted++;
+
+ camel_operation_progress (NULL, ndeleted * 100 / hrefs->len);
+ }
+ status = e2k_result_iter_free (iter);
+ g_static_rec_mutex_unlock (&ed->changed_msgs_mutex);
+
+ if (folder)
+ camel_folder_thaw (folder);
+
+ if (!E2K_HTTP_STATUS_IS_SUCCESSFUL (status)) {
+ g_warning ("expunged: %d", status);
+ some_error = TRUE;
+ set_exception (ex, _("Could not empty Deleted Items folder"));
+ } else if (some_error) {
+ set_exception (ex, _("Permission denied. Could not delete certain messages."));
+ }
+
+ g_ptr_array_free (hrefs, TRUE);
+
+ return !some_error;
+}
+
+static gboolean
+test_uri (E2kContext *ctx, const gchar *test_name, gpointer messages_by_href)
+{
+ return g_hash_table_lookup (messages_by_href, test_name) == NULL;
+}
+
+gboolean
+camel_exchange_utils_append_message (CamelService *service,
+ const gchar *folder_name,
+ guint32 flags,
+ const gchar *subject,
+ const GByteArray *message,
+ gchar **new_uid, /* out */
+ CamelException *ex)
+{
+ ExchangeData *ed = get_data_for_service (service);
+ ExchangeFolder *mfld;
+ E2kHTTPStatus status;
+ gchar *ru_header = NULL, *repl_uid, *location = NULL;
+
+ g_return_val_if_fail (ed != NULL, FALSE);
+ g_return_val_if_fail (new_uid != NULL, FALSE);
+ g_return_val_if_fail (message != NULL, FALSE);
+
+ mfld = folder_from_name (ed, folder_name, MAPI_ACCESS_CREATE_CONTENTS, ex);
+ if (!mfld)
+ return FALSE;
+
+ status = e_folder_exchange_put_new (mfld->folder, NULL, subject,
+ test_uri, mfld->messages_by_href,
+ "message/rfc822", (const gchar *)message->data, message->len,
+ &location, &ru_header);
+ if (status != E2K_HTTP_CREATED) {
+ g_warning ("appended_message: %d", status);
+ set_exception (ex, status == E2K_HTTP_INSUFFICIENT_SPACE_ON_RESOURCE ?
+ _("Could not append message; mailbox is over quota") :
+ _("Could not append message"));
+ return FALSE;
+ }
+
+ if (location) {
+ if (flags & CAMEL_MESSAGE_SEEN)
+ mark_one_read (ed->ctx, location, TRUE);
+ else
+ mark_one_read (ed->ctx, location, FALSE);
+ }
+
+ if (ru_header && *ru_header == '<' && strlen (ru_header) > 3)
+ repl_uid = g_strndup (ru_header + 1, strlen (ru_header) - 2);
+ else
+ repl_uid = NULL;
+
+ *new_uid = g_strdup (repl_uid ? uidstrip (repl_uid) : "");
+
+ g_free (repl_uid);
+ g_free (ru_header);
+ g_free (location);
- g_object_unref (folder);
return TRUE;
}
static void
-get_message (MailStub *stub, const gchar *folder_name, const gchar *uid)
+change_message (ExchangeFolder *mfld, ExchangeMessage *mmsg)
+{
+ gint i;
+
+ g_static_rec_mutex_lock (&mfld->ed->changed_msgs_mutex);
+
+ for (i=0; i<mfld->changed_messages->len; i++) {
+ if (mfld->changed_messages->pdata[i] == mmsg)
+ break;
+ }
+
+ if (i == mfld->changed_messages->len) {
+ /*change_pending (mfld); !!!TODO!!! */
+ g_ptr_array_add (mfld->changed_messages, mmsg);
+ }
+ g_static_rec_mutex_unlock (&mfld->ed->changed_msgs_mutex);
+
+ if (mfld->flag_timeout)
+ g_source_remove (mfld->flag_timeout);
+ mfld->flag_timeout = g_timeout_add (1000, process_flags, mfld);
+}
+
+gboolean
+camel_exchange_utils_set_message_flags (CamelService *service,
+ const gchar *folder_name,
+ const gchar *uid,
+ guint32 flags,
+ guint32 mask,
+ CamelException *ex)
+{
+ ExchangeData *ed = get_data_for_service (service);
+ ExchangeFolder *mfld;
+ ExchangeMessage *mmsg;
+
+ g_return_val_if_fail (ed != NULL, FALSE);
+
+ mfld = folder_from_name (ed, folder_name, MAPI_ACCESS_MODIFY, ex);
+ if (!mfld)
+ return FALSE;
+
+ mmsg = find_message (mfld, uid);
+ if (!mmsg)
+ return FALSE;
+
+ /* Although we don't actually process the flag change right
+ * away, we need to update the folder's unread count to match
+ * what the user now believes it is. (We take advantage of the
+ * fact that the mailer will never delete a message without
+ * also marking it read.)
+ */
+ if (mask & CAMEL_MESSAGE_SEEN) {
+ if (((mmsg->flags ^ flags) & CAMEL_MESSAGE_SEEN) == 0) {
+ /* The user is just setting it to what it
+ * already is, so ignore it.
+ */
+ mask &= ~CAMEL_MESSAGE_SEEN;
+ } else {
+ mmsg->flags ^= CAMEL_MESSAGE_SEEN;
+ if (mmsg->flags & CAMEL_MESSAGE_SEEN)
+ mfld->unread_count--;
+ else
+ mfld->unread_count++;
+ folder_changed (mfld);
+ }
+ }
+
+ /* If the user tries to delete a message in a non-person
+ * hierarchy, we ignore it (which will cause camel to delete
+ * it the hard way next time it syncs).
+ */
+
+#if 0
+ /* If we allow camel utils to delete these messages hard way, it may
+ fail to delete a mail because of permissions, but will append
+ a mail in deleted items */
+
+ if (mask & flags & CAMEL_MESSAGE_DELETED) {
+ ExchangeHierarchy *hier;
+
+ hier = e_folder_exchange_get_hierarchy (mfld->folder);
+ if (hier->type != EXCHANGE_HIERARCHY_PERSONAL)
+ mask &= ~CAMEL_MESSAGE_DELETED;
+ }
+#endif
+
+ /* If there's nothing left to change, return. */
+ if (!mask)
+ return TRUE;
+
+ mmsg->change_flags |= (flags & mask);
+ mmsg->change_flags &= ~(~flags & mask);
+ mmsg->change_mask |= mask;
+
+ change_message (mfld, mmsg);
+
+ return TRUE;
+}
+
+gboolean
+camel_exchange_utils_set_message_tag (CamelService *service,
+ const gchar *folder_name,
+ const gchar *uid,
+ const gchar *name,
+ const gchar *value,
+ CamelException *ex)
{
- MailStubExchange *mse = MAIL_STUB_EXCHANGE (stub);
- MailStubExchangeFolder *mfld;
- MailStubExchangeMessage *mmsg;
+ ExchangeData *ed = get_data_for_service (service);
+ ExchangeFolder *mfld;
+ ExchangeMessage *mmsg;
+
+ g_return_val_if_fail (ed != NULL, FALSE);
+
+ mfld = folder_from_name (ed, folder_name, MAPI_ACCESS_MODIFY, ex);
+ if (!mfld)
+ return FALSE;
+
+ mmsg = find_message (mfld, uid);
+ if (!mmsg)
+ return FALSE;
+
+ g_datalist_set_data_full (&mmsg->tag_updates, name, g_strdup (value), g_free);
+
+ change_message (mfld, mmsg);
+
+ return TRUE;
+}
+
+gboolean
+camel_exchange_utils_get_message (CamelService *service,
+ const gchar *folder_name,
+ const gchar *uid,
+ GByteArray **message_bytes, /* out */
+ CamelException *ex)
+{
+ ExchangeData *ed = get_data_for_service (service);
+ ExchangeFolder *mfld;
+ ExchangeMessage *mmsg;
E2kHTTPStatus status;
gchar *body = NULL, *content_type = NULL, *owner_email = NULL;
gint len = 0;
+ gboolean res = FALSE;
+ CamelMessageInfo *info;
+ CamelFolder *folder;
+
+ g_return_val_if_fail (ed != NULL, FALSE);
+ g_return_val_if_fail (message_bytes != NULL, FALSE);
- mfld = folder_from_name (mse, folder_name, MAPI_ACCESS_READ, FALSE);
+ mfld = folder_from_name (ed, folder_name, MAPI_ACCESS_READ, ex);
if (!mfld)
- return;
+ return FALSE;
+
+ folder = get_camel_folder (mfld);
mmsg = find_message (mfld, uid);
if (!mmsg) {
- mail_stub_return_data (stub, CAMEL_STUB_RETVAL_REMOVED_MESSAGE,
- CAMEL_STUB_ARG_FOLDER, folder_name,
- CAMEL_STUB_ARG_STRING, uid,
- CAMEL_STUB_ARG_END);
- mail_stub_return_error (stub, _("No such message"));
- return;
+ if (folder && (info = camel_folder_summary_uid (folder->summary, uid))) {
+ camel_message_info_free (info);
+ camel_exchange_folder_remove_message (CAMEL_EXCHANGE_FOLDER (folder), uid);
+ }
+
+ set_exception (ex, _("No such message"));
+ return FALSE;
}
- if (mfld->type == MAIL_STUB_EXCHANGE_FOLDER_NOTES) {
- status = get_stickynote (mse->ctx, NULL, mmsg->href,
- &body, &len);
+ if (mfld->type == EXCHANGE_FOLDER_NOTES) {
+ status = get_stickynote (ed->ctx, NULL, mmsg->href, &body, &len);
if (!E2K_HTTP_STATUS_IS_SUCCESSFUL (status))
goto error;
content_type = g_strdup ("message/rfc822");
} else {
SoupBuffer *response;
- status = e2k_context_get (mse->ctx, NULL, mmsg->href,
- &content_type, &response);
+ status = e2k_context_get (ed->ctx, NULL, mmsg->href, &content_type, &response);
if (!E2K_HTTP_STATUS_IS_SUCCESSFUL (status))
goto error;
+
len = response->length;
body = g_strndup (response->data, response->length);
soup_buffer_free (response);
@@ -2503,9 +2643,7 @@ get_message (MailStub *stub, const gchar *folder_name, const gchar *uid)
* courtesy of mp:x67200102.
*/
if (!content_type || g_ascii_strncasecmp (content_type, "message/", 8)) {
- status = build_message_from_document (mse->ctx, NULL,
- mmsg->href,
- &body, &len);
+ status = build_message_from_document (ed->ctx, NULL, mmsg->href, &body, &len);
if (!E2K_HTTP_STATUS_IS_SUCCESSFUL (status))
goto error;
}
@@ -2513,10 +2651,8 @@ get_message (MailStub *stub, const gchar *folder_name, const gchar *uid)
/* If this is a delegated meeting request, we need to know who
* delegated it to us.
*/
- if (mmsg->flags & MAIL_STUB_MESSAGE_DELEGATED) {
- status = unmangle_delegated_meeting_request (mse, NULL,
- mmsg->href,
- &body, &len);
+ if (mmsg->flags & EXMAIL_DELEGATED) {
+ status = unmangle_delegated_meeting_request (ed, NULL, mmsg->href, &body, &len);
if (!E2K_HTTP_STATUS_IS_SUCCESSFUL (status))
goto error;
}
@@ -2524,11 +2660,8 @@ get_message (MailStub *stub, const gchar *folder_name, const gchar *uid)
/* If the message is in a subscribed inbox,
* we need to modify the message appropriately.
*/
- if (is_foreign_folder (stub, folder_name, &owner_email)) {
-
- status = unmangle_meeting_request_in_subscribed_inbox (mse,
- owner_email,
- &body, &len);
+ if (is_foreign_folder (ed, folder_name, &owner_email)) {
+ status = unmangle_meeting_request_in_subscribed_inbox (ed, owner_email, &body, &len);
if (!E2K_HTTP_STATUS_IS_SUCCESSFUL (status))
goto error;
}
@@ -2536,16 +2669,15 @@ get_message (MailStub *stub, const gchar *folder_name, const gchar *uid)
/* If there is a sender field in the meeting request/response,
* we need to know who it is.
*/
- status = unmangle_sender_field (mse, NULL,
- mmsg->href,
- &body, &len);
+ status = unmangle_sender_field (ed, NULL, mmsg->href, &body, &len);
if (!E2K_HTTP_STATUS_IS_SUCCESSFUL (status))
goto error;
- mail_stub_return_data (stub, CAMEL_STUB_RETVAL_RESPONSE,
- CAMEL_STUB_ARG_BYTEARRAY, body, len,
- CAMEL_STUB_ARG_END);
- mail_stub_return_ok (stub);
+ *message_bytes = g_byte_array_sized_new (len);
+ g_byte_array_append (*message_bytes, (const guint8 *)body, len);
+
+ res = TRUE;
+
goto cleanup;
error:
@@ -2555,22 +2687,28 @@ get_message (MailStub *stub, const gchar *folder_name, const gchar *uid)
* message may actually have gone away before the last
* time we recorded that.
*/
- message_removed (stub, mfld, mmsg->href);
- mail_stub_return_error (stub, _("Message has been deleted"));
+ message_removed (mfld, folder, mmsg->href);
+ set_exception (ex, _("Message has been deleted"));
} else
- mail_stub_return_error (stub, _("Error retrieving message"));
+ set_exception (ex, _("Error retrieving message"));
-cleanup:
+ cleanup:
g_free (body);
g_free (content_type);
g_free (owner_email);
+
+ return res;
}
-static void
-search (MailStub *stub, const gchar *folder_name, const gchar *text)
+gboolean
+camel_exchange_utils_search (CamelService *service,
+ const gchar *folder_name,
+ const gchar *text,
+ GPtrArray **found_uids, /* out */
+ CamelException *ex)
{
- MailStubExchange *mse = MAIL_STUB_EXCHANGE (stub);
- MailStubExchangeFolder *mfld;
+ ExchangeData *ed = get_data_for_service (service);
+ ExchangeFolder *mfld;
E2kRestriction *rn;
const gchar *prop, *repl_uid;
E2kResultIter *iter;
@@ -2578,47 +2716,53 @@ search (MailStub *stub, const gchar *folder_name, const gchar *text)
E2kHTTPStatus status;
GPtrArray *matches;
- mfld = folder_from_name (mse, folder_name, 0, FALSE);
+ g_return_val_if_fail (ed != NULL, FALSE);
+ g_return_val_if_fail (found_uids != NULL, FALSE);
+
+ mfld = folder_from_name (ed, folder_name, 0, ex);
if (!mfld)
- return;
+ return FALSE;
matches = g_ptr_array_new ();
prop = E2K_PR_REPL_UID;
rn = e2k_restriction_content (PR_BODY, E2K_FL_SUBSTRING, text);
- iter = e_folder_exchange_search_start (mfld->folder, NULL,
- &prop, 1, rn, NULL, TRUE);
+ iter = e_folder_exchange_search_start (mfld->folder, NULL, &prop, 1, rn, NULL, TRUE);
e2k_restriction_unref (rn);
while ((result = e2k_result_iter_next (iter))) {
- repl_uid = e2k_properties_get_prop (result->props,
- E2K_PR_REPL_UID);
+ repl_uid = e2k_properties_get_prop (result->props, E2K_PR_REPL_UID);
if (repl_uid)
- g_ptr_array_add (matches, (gchar *)uidstrip (repl_uid));
+ g_ptr_array_add (matches, g_strdup (uidstrip (repl_uid)));
}
status = e2k_result_iter_free (iter);
if (status == E2K_HTTP_UNPROCESSABLE_ENTITY) {
- mail_stub_return_error (stub, _("Mailbox does not support full-text searching"));
+ set_exception (ex, _("Mailbox does not support full-text searching"));
+
+ g_ptr_array_foreach (matches, (GFunc) g_free, NULL);
+ g_ptr_array_free (matches, TRUE);
+ matches = NULL;
} else {
- mail_stub_return_data (stub, CAMEL_STUB_RETVAL_RESPONSE,
- CAMEL_STUB_ARG_STRINGARRAY, matches,
- CAMEL_STUB_ARG_END);
- mail_stub_return_ok (stub);
+ *found_uids = matches;
}
- g_ptr_array_free (matches, TRUE);
+ return matches != NULL;
}
-static void
-transfer_messages (MailStub *stub, const gchar *source_name,
- const gchar *dest_name, GPtrArray *uids,
- gboolean delete_originals)
+gboolean
+camel_exchange_utils_transfer_messages (CamelService *service,
+ const gchar *source_name,
+ const gchar *dest_name,
+ GPtrArray *uids,
+ gboolean delete_originals,
+ GPtrArray **ret_uids, /* out */
+ CamelException *ex)
{
- MailStubExchange *mse = MAIL_STUB_EXCHANGE (stub);
- MailStubExchangeFolder *source, *dest;
- MailStubExchangeMessage *mmsg;
+ ExchangeData *ed = get_data_for_service (service);
+ ExchangeFolder *source, *dest;
+ ExchangeMessage *mmsg;
GPtrArray *hrefs, *new_uids;
GHashTable *order;
gpointer key, value;
@@ -2627,13 +2771,17 @@ transfer_messages (MailStub *stub, const gchar *source_name,
E2kHTTPStatus status;
const gchar *uid;
gint i, num;
+ CamelFolder *folder;
- source = folder_from_name (mse, source_name, delete_originals ? MAPI_ACCESS_DELETE : 0, FALSE);
+ g_return_val_if_fail (ed != NULL, FALSE);
+ g_return_val_if_fail (ret_uids != NULL, FALSE);
+
+ source = folder_from_name (ed, source_name, delete_originals ? MAPI_ACCESS_DELETE : 0, ex);
if (!source)
- return;
- dest = folder_from_name (mse, dest_name, MAPI_ACCESS_CREATE_CONTENTS, FALSE);
+ return FALSE;
+ dest = folder_from_name (ed, dest_name, MAPI_ACCESS_CREATE_CONTENTS, ex);
if (!dest)
- return;
+ return FALSE;
order = g_hash_table_new (NULL, NULL);
hrefs = g_ptr_array_new ();
@@ -2650,13 +2798,13 @@ transfer_messages (MailStub *stub, const gchar *source_name,
g_hash_table_insert (order, mmsg, GINT_TO_POINTER (i));
g_ptr_array_add (hrefs, strrchr (mmsg->href, '/') + 1);
- g_ptr_array_add (new_uids, (gpointer) "");
+ g_ptr_array_add (new_uids, g_strdup (""));
}
- if (delete_originals && hrefs->len > 1) {
- mail_stub_return_data (stub, CAMEL_STUB_RETVAL_FREEZE_FOLDER,
- CAMEL_STUB_ARG_FOLDER, source->name,
- CAMEL_STUB_ARG_END);
+ folder = get_camel_folder (source);
+
+ if (delete_originals && hrefs->len > 1 && folder) {
+ camel_folder_freeze (folder);
}
iter = e_folder_exchange_transfer_start (source->folder, NULL,
@@ -2683,47 +2831,47 @@ transfer_messages (MailStub *stub, const gchar *source_name,
if (num > new_uids->len)
continue;
- new_uids->pdata[num] = (gchar *)uidstrip (uid);
+ g_free (new_uids->pdata[num]);
+ new_uids->pdata[num] = g_strdup (uidstrip (uid));
if (delete_originals)
- message_removed (stub, source, result->href);
+ message_removed (source, folder, result->href);
}
status = e2k_result_iter_free (iter);
- if (delete_originals && hrefs->len > 1) {
- mail_stub_return_data (stub, CAMEL_STUB_RETVAL_THAW_FOLDER,
- CAMEL_STUB_ARG_FOLDER, source->name,
- CAMEL_STUB_ARG_END);
+ if (delete_originals && hrefs->len > 1 && folder) {
+ camel_folder_thaw (folder);
}
if (E2K_HTTP_STATUS_IS_SUCCESSFUL (status)) {
- mail_stub_return_data (stub, CAMEL_STUB_RETVAL_RESPONSE,
- CAMEL_STUB_ARG_STRINGARRAY, new_uids,
- CAMEL_STUB_ARG_END);
- mail_stub_return_ok (stub);
+ *ret_uids = new_uids;
} else {
g_warning ("transferred_messages: %d", status);
- mail_stub_return_error (stub, _("Unable to move/copy messages"));
+ set_exception (ex, _("Unable to move/copy messages"));
+ g_ptr_array_free (new_uids, TRUE);
+ new_uids = NULL;
}
g_ptr_array_free (hrefs, TRUE);
- g_ptr_array_free (new_uids, TRUE);
g_hash_table_destroy (order);
+
+ return new_uids != NULL;
}
static void
account_new_folder (ExchangeAccount *account, EFolder *folder, gpointer user_data)
{
- MailStub *stub = user_data;
- MailStubExchange *mse = user_data;
+ ExchangeData *ed = user_data;
ExchangeHierarchy *hier;
+ g_return_if_fail (ed != NULL);
+
if (strcmp (e_folder_get_type_string (folder), "mail") != 0 &&
strcmp (e_folder_get_type_string (folder), "mail/public") != 0)
return;
- if (mse->ignore_new_folder &&
- !strcmp (e_folder_exchange_get_path (folder), mse->ignore_new_folder))
+ if (ed->ignore_new_folder &&
+ !strcmp (e_folder_exchange_get_path (folder), ed->ignore_new_folder))
return;
hier = e_folder_exchange_get_hierarchy (folder);
@@ -2732,27 +2880,23 @@ account_new_folder (ExchangeAccount *account, EFolder *folder, gpointer user_dat
hier->type != EXCHANGE_HIERARCHY_FOREIGN)
return;
- mail_stub_return_data (stub, CAMEL_STUB_RETVAL_FOLDER_CREATED,
- CAMEL_STUB_ARG_STRING, e_folder_get_name (folder),
- CAMEL_STUB_ARG_STRING, e_folder_get_physical_uri (folder),
- CAMEL_STUB_ARG_END);
-
- mail_stub_push_changes (stub);
+ camel_exchange_store_folder_created (ed->estore, e_folder_get_name (folder), e_folder_get_physical_uri (folder));
}
static void
account_removed_folder (ExchangeAccount *account, EFolder *folder, gpointer user_data)
{
- MailStub *stub = user_data;
- MailStubExchange *mse = user_data;
+ ExchangeData *ed = user_data;
ExchangeHierarchy *hier;
+ g_return_if_fail (ed != NULL);
+
if (strcmp (e_folder_get_type_string (folder), "mail") != 0 &&
strcmp (e_folder_get_type_string (folder), "mail/public") != 0)
return;
- if (mse->ignore_removed_folder &&
- !strcmp (e_folder_exchange_get_path (folder), mse->ignore_removed_folder))
+ if (ed->ignore_removed_folder &&
+ !strcmp (e_folder_exchange_get_path (folder), ed->ignore_removed_folder))
return;
hier = e_folder_exchange_get_hierarchy (folder);
@@ -2761,224 +2905,68 @@ account_removed_folder (ExchangeAccount *account, EFolder *folder, gpointer user
hier->type != EXCHANGE_HIERARCHY_FOREIGN)
return;
- mail_stub_return_data (stub, CAMEL_STUB_RETVAL_FOLDER_DELETED,
- CAMEL_STUB_ARG_STRING, e_folder_get_name (folder),
- CAMEL_STUB_ARG_STRING, e_folder_get_physical_uri (folder),
- CAMEL_STUB_ARG_END);
-
- mail_stub_push_changes (stub);
-}
-
-static void
-get_folder_info_data (MailStub *stub, const gchar *top, guint32 store_flags,
- GPtrArray **names, GPtrArray **uris,
- GArray **unread, GArray **flags)
-{
- MailStubExchange *mse = MAIL_STUB_EXCHANGE (stub);
- GPtrArray *folders = NULL;
- ExchangeHierarchy *hier;
- EFolder *folder;
- const gchar *type, *name, *uri, *inbox_uri = NULL, *trash_uri = NULL, *sent_items_uri = NULL;
- gint unread_count, i, toplen = top ? strlen (top) : 0;
- guint32 folder_flags = 0;
- gboolean recursive, subscribed, subscription_list;
- gint mode = -1;
- gchar *full_path;
-
- recursive = (store_flags & CAMEL_STUB_STORE_FOLDER_INFO_RECURSIVE);
- subscribed = (store_flags & CAMEL_STUB_STORE_FOLDER_INFO_SUBSCRIBED);
- subscription_list = (store_flags & CAMEL_STUB_STORE_FOLDER_INFO_SUBSCRIPTION_LIST);
-
- exchange_account_is_offline (mse->account, &mode);
- if (!subscribed && subscription_list) {
- ExchangeAccountResult result = -1;
-
- d(g_print ("%s(%d):%s: NOT SUBSCRIBED top = [%s]\n", __FILE__, __LINE__, __GNUC_PRETTY_FUNCTION__, top));
- if (!toplen)
- result = exchange_account_open_folder (mse->account, "/public");
- if (result == EXCHANGE_ACCOUNT_FOLDER_DOES_NOT_EXIST) {
- hier = exchange_account_get_hierarchy_by_type (mse->account, EXCHANGE_HIERARCHY_PUBLIC);
- if (hier)
- exchange_hierarchy_scan_subtree (hier, hier->toplevel, mode);
- } else {
- d(g_print ("%s(%d):%s: NOT SUBSCRIBED - open_folder returned = [%d]\n", __FILE__, __LINE__, __GNUC_PRETTY_FUNCTION__, result));
- }
- }
-
- /* No need to check for recursive flag, as I will always be returning a tree, instead of a single folder info object */
- if (toplen) {
- d(g_print ("%s(%d):%s: NOT RECURSIVE and toplen top = [%s]\n", __FILE__, __LINE__, __GNUC_PRETTY_FUNCTION__, top));
- full_path = g_strdup_printf ("/%s", top);
- folders = exchange_account_get_folder_tree (mse->account, full_path);
- g_free (full_path);
- } else {
- d(g_print ("%s(%d):%s calling exchange_account_get_folders \n", __FILE__, __LINE__,
- __GNUC_PRETTY_FUNCTION__));
- folders = exchange_account_get_folders (mse->account);
- }
-
- *names = g_ptr_array_new ();
- *uris = g_ptr_array_new ();
- *unread = g_array_new (FALSE, FALSE, sizeof (gint));
- *flags = g_array_new (FALSE, FALSE, sizeof (gint));
- /* Can be NULL if started in offline mode */
- if (mse->inbox) {
- inbox_uri = e_folder_get_physical_uri (mse->inbox);
- }
-
- if (mse->deleted_items) {
- trash_uri = e_folder_get_physical_uri (mse->deleted_items);
- }
-
- if (mse->sent_items) {
- sent_items_uri = e_folder_get_physical_uri (mse->sent_items);
- }
-
- if (folders) {
- for (i = 0; i < folders->len; i++) {
- folder = folders->pdata[i];
- hier = e_folder_exchange_get_hierarchy (folder);
- folder_flags = 0;
-
- if (subscribed) {
- if (hier->type != EXCHANGE_HIERARCHY_PERSONAL &&
- hier->type != EXCHANGE_HIERARCHY_FAVORITES &&
- hier->type != EXCHANGE_HIERARCHY_FOREIGN)
- continue;
- } else if (subscription_list) {
- if (hier->type != EXCHANGE_HIERARCHY_PUBLIC)
- continue;
- }
-
- type = e_folder_get_type_string (folder);
- name = e_folder_get_name (folder);
- uri = e_folder_get_physical_uri (folder);
- d(g_print ("Uri: %s\n", uri));
- d(g_print ("folder type is : %s\n", type));
-
- if (!strcmp (type, "noselect")) {
- unread_count = 0;
- folder_flags = CAMEL_STUB_FOLDER_NOSELECT;
- }
-
- switch (hier->type) {
- case EXCHANGE_HIERARCHY_FAVORITES:
- /* folder_flags will be set only if the type
- is noselect and we need to include it */
- if (strcmp (type, "mail") && !folder_flags)
- continue;
- /* selectable */
- if (!folder_flags)
- unread_count = e_folder_get_unread_count (folder);
- case EXCHANGE_HIERARCHY_PUBLIC:
- if (exchange_account_is_favorite_folder (mse->account, folder)) {
- folder_flags |= CAMEL_STUB_FOLDER_SUBSCRIBED;
- d(printf ("marked the folder as subscribed\n"));
- }
- break;
- case EXCHANGE_HIERARCHY_FOREIGN:
- if (folder_flags & CAMEL_STUB_FOLDER_NOSELECT &&
- mse->new_folder_id == 0) {
- /* Rescan the hierarchy - as we don't rescan
- foreign hierarchies anywhere for mailer and
- only when we are starting up
- */
- exchange_hierarchy_scan_subtree (hier, hier->toplevel, mode);
- }
- case EXCHANGE_HIERARCHY_PERSONAL:
- if (!strcmp (type, "mail")) {
- unread_count = e_folder_get_unread_count (folder);
- }
- else if (!folder_flags) {
- continue;
- }
- break;
- default:
- break;
- }
-
- if (inbox_uri && !strcmp (uri, inbox_uri))
- folder_flags |= CAMEL_STUB_FOLDER_SYSTEM|CAMEL_STUB_FOLDER_TYPE_INBOX;
-
- if (trash_uri && !strcmp (uri, trash_uri))
- folder_flags |= CAMEL_STUB_FOLDER_SYSTEM|CAMEL_STUB_FOLDER_TYPE_TRASH;
-
- if (sent_items_uri && !strcmp (uri, sent_items_uri))
- folder_flags |= CAMEL_STUB_FOLDER_SYSTEM|CAMEL_STUB_FOLDER_TYPE_SENT;
-
- if (!e_folder_exchange_get_has_subfolders (folder)) {
- d(printf ("%s:%d:%s - %s has no subfolders", __FILE__, __LINE__, __GNUC_PRETTY_FUNCTION__,
- name));
- folder_flags |= CAMEL_STUB_FOLDER_NOCHILDREN;
- }
-
- d(g_print ("folder flags is : %d\n", folder_flags));
-
- g_ptr_array_add (*names, (gchar *)name);
- g_ptr_array_add (*uris, (gchar *)uri);
- g_array_append_val (*unread, unread_count);
- g_array_append_val (*flags, folder_flags);
- }
-
- g_ptr_array_free (folders, TRUE);
- }
+ camel_exchange_store_folder_deleted (ed->estore, e_folder_get_name (folder), e_folder_get_physical_uri (folder));
}
-static void
-get_folder_info (MailStub *stub, const gchar *top, guint32 store_flags)
+gboolean
+camel_exchange_utils_get_folder_info (CamelService *service,
+ const gchar *top,
+ guint32 store_flags,
+ GPtrArray **folder_names, /* out */
+ GPtrArray **folder_uris, /* out */
+ GArray **unread_counts, /* out */
+ GArray **folder_flags, /* out */
+ CamelException *ex)
{
- MailStubExchange *mse = MAIL_STUB_EXCHANGE (stub);
- GPtrArray *names, *uris;
- GArray *unread, *flags;
-
- get_folder_info_data (stub, top, store_flags, &names, &uris,
- &unread, &flags);
+ ExchangeData *ed = get_data_for_service (service);
- mail_stub_return_data (stub, CAMEL_STUB_RETVAL_RESPONSE,
- CAMEL_STUB_ARG_STRINGARRAY, names,
- CAMEL_STUB_ARG_STRINGARRAY, uris,
- CAMEL_STUB_ARG_UINT32ARRAY, unread,
- CAMEL_STUB_ARG_UINT32ARRAY, flags,
- CAMEL_STUB_ARG_END);
+ g_return_val_if_fail (ed != NULL, FALSE);
+ g_return_val_if_fail (folder_names != NULL, FALSE);
+ g_return_val_if_fail (folder_uris != NULL, FALSE);
+ g_return_val_if_fail (unread_counts != NULL, FALSE);
+ g_return_val_if_fail (folder_flags != NULL, FALSE);
- g_ptr_array_free (names, TRUE);
- g_ptr_array_free (uris, TRUE);
- g_array_free (unread, TRUE);
- g_array_free (flags, TRUE);
+ get_folder_info_data (ed, top, store_flags, folder_names, folder_uris, unread_counts, folder_flags);
- if (mse->new_folder_id == 0) {
- mse->new_folder_id = g_signal_connect (
- mse->account, "new_folder",
- G_CALLBACK (account_new_folder), stub);
- mse->removed_folder_id = g_signal_connect (
- mse->account, "removed_folder",
- G_CALLBACK (account_removed_folder), stub);
+ if (ed->new_folder_id == 0) {
+ ed->new_folder_id = g_signal_connect (ed->account, "new_folder", G_CALLBACK (account_new_folder), ed);
+ ed->removed_folder_id = g_signal_connect (ed->account, "removed_folder", G_CALLBACK (account_removed_folder), ed);
}
- mail_stub_return_ok (stub);
+ return TRUE;
}
-static void
-send_message (MailStub *stub, const gchar *from, GPtrArray *recipients,
- const gchar *body, gint length)
+gboolean
+camel_exchange_utils_send_message (CamelService *service,
+ const gchar *from,
+ GPtrArray *recipients,
+ const GByteArray *message,
+ CamelException *ex)
{
- MailStubExchange *mse = MAIL_STUB_EXCHANGE (stub);
+ ExchangeData *ed = get_data_for_service (service);
SoupMessage *msg;
E2kHTTPStatus status;
gchar *timestamp, *errmsg;
GString *data;
gint i;
+ gboolean res = FALSE;
- if (!mse->mail_submission_uri) {
- mail_stub_return_error (stub, _("No mail submission URI for this mailbox"));
- return;
+ /* This function is called from a transport service, thus it has no idea
+ about underlying folders and such. The check for estore != NULL is
+ necessary to be sure the transport service was called after the connect,
+ because the estore is used in other functions. */
+ g_return_val_if_fail (ed != NULL, FALSE);
+ g_return_val_if_fail (ed->estore != NULL, FALSE);
+
+ if (!ed->mail_submission_uri) {
+ set_exception (ex, _("No mail submission URI for this mailbox"));
+ return FALSE;
}
data = g_string_new (NULL);
g_string_append_printf (data, "MAIL FROM:<%s>\r\n", from);
for (i = 0; i < recipients->len; i++) {
- g_string_append_printf (data, "RCPT TO:<%s>\r\n",
- (gchar *)recipients->pdata[i]);
+ g_string_append_printf (data, "RCPT TO:<%s>\r\n", (gchar *)recipients->pdata[i]);
}
g_string_append (data, "\r\n");
@@ -2987,29 +2975,29 @@ send_message (MailStub *stub, const gchar *from, GPtrArray *recipients,
*/
timestamp = e2k_make_timestamp_rfc822 (time (NULL));
g_string_append_printf (data, "Received: from %s by %s; %s\r\n",
- g_get_host_name (), mse->account->exchange_server,
+ g_get_host_name (), ed->account->exchange_server,
timestamp);
g_free (timestamp);
- g_string_append_len (data, body, length);
+ g_string_append_len (data, (const gchar *)message->data, message->len);
- msg = e2k_soup_message_new_full (mse->ctx, mse->mail_submission_uri,
+ msg = e2k_soup_message_new_full (ed->ctx, ed->mail_submission_uri,
SOUP_METHOD_PUT, "message/rfc821",
SOUP_MEMORY_TAKE,
data->str, data->len);
g_string_free (data, FALSE);
soup_message_headers_append (msg->request_headers, "Saveinsent", "f");
- status = e2k_context_send_message (mse->ctx, NULL, msg);
- if (E2K_HTTP_STATUS_IS_SUCCESSFUL (status))
- mail_stub_return_ok (stub);
- else if (status == E2K_HTTP_NOT_FOUND)
- mail_stub_return_error (stub, _("Server won't accept mail via Exchange transport"));
- else if (status == E2K_HTTP_FORBIDDEN) {
+ status = e2k_context_send_message (ed->ctx, NULL, msg);
+ if (E2K_HTTP_STATUS_IS_SUCCESSFUL (status)) {
+ res = TRUE;
+ } else if (status == E2K_HTTP_NOT_FOUND) {
+ set_exception (ex, _("Server won't accept mail via Exchange transport"));
+ } else if (status == E2K_HTTP_FORBIDDEN) {
errmsg = g_strdup_printf (_("Your account does not have permission "
"to use <%s>\nas a From address."),
from);
- mail_stub_return_error (stub, errmsg);
+ set_exception (ex, errmsg);
g_free (errmsg);
} else if (status == E2K_HTTP_INSUFFICIENT_SPACE_ON_RESOURCE ||
status == E2K_HTTP_INTERNAL_SERVER_ERROR) {
@@ -3018,25 +3006,38 @@ send_message (MailStub *stub, const gchar *from, GPtrArray *recipients,
* changes in the future.)
*/
E2K_KEEP_PRECEDING_COMMENT_OUT_OF_PO_FILES;
- mail_stub_return_error (stub, _("Could not send message.\n"
- "This might mean that your account is over quota."));
+ set_exception (ex, _("Could not send message.\n"
+ "This might mean that your account is over quota."));
} else {
g_warning ("sent_message: %d", status);
- mail_stub_return_error (stub, _("Could not send message"));
+ set_exception (ex, _("Could not send message"));
}
+
+ return res;
}
-static void
-create_folder (MailStub *stub, const gchar *parent_name, const gchar *folder_name)
+gboolean
+camel_exchange_utils_create_folder (CamelService *service,
+ const gchar *parent_name,
+ const gchar *folder_name,
+ gchar **folder_uri, /* out */
+ guint32 *unread_count, /* out */
+ guint32 *flags, /* out */
+ CamelException *ex)
{
- MailStubExchange *mse = MAIL_STUB_EXCHANGE (stub);
+ ExchangeData *ed = get_data_for_service (service);
ExchangeAccountFolderResult result;
EFolder *folder;
gchar *path;
+ g_return_val_if_fail (ed != NULL, FALSE);
+ g_return_val_if_fail (folder_uri != NULL, FALSE);
+ g_return_val_if_fail (unread_count != NULL, FALSE);
+ g_return_val_if_fail (flags != NULL, FALSE);
+
path = g_build_filename ("/", parent_name, folder_name, NULL);
- result = exchange_account_create_folder (mse->account, path, "mail");
- folder = exchange_account_get_folder (mse->account, path);
+ result = exchange_account_create_folder (ed->account, path, "mail");
+ folder = exchange_account_get_folder (ed->account, path);
g_free (path);
switch (result) {
@@ -3045,104 +3046,121 @@ create_folder (MailStub *stub, const gchar *parent_name, const gchar *folder_nam
break;
/* fall through */
default:
- mail_stub_return_error (stub, _("Generic error"));
- return;
+ set_exception (ex, _("Generic error"));
+ return FALSE;
case EXCHANGE_ACCOUNT_FOLDER_ALREADY_EXISTS:
- mail_stub_return_error (stub, _("Folder already exists"));
- return;
+ set_exception (ex, _("Folder already exists"));
+ return FALSE;
case EXCHANGE_ACCOUNT_FOLDER_PERMISSION_DENIED:
- mail_stub_return_error (stub, _("Permission denied"));
- return;
+ set_exception (ex, _("Permission denied"));
+ return FALSE;
}
- mail_stub_return_data (stub, CAMEL_STUB_RETVAL_RESPONSE,
- CAMEL_STUB_ARG_STRING, e_folder_get_physical_uri (folder),
- CAMEL_STUB_ARG_UINT32, e_folder_get_unread_count (folder),
- CAMEL_STUB_ARG_UINT32, 0,
- CAMEL_STUB_ARG_END);
- mail_stub_return_ok (stub);
+ *folder_uri = g_strdup (e_folder_get_physical_uri (folder));
+ *unread_count = e_folder_get_unread_count (folder);
+ *flags = 0;
+
+ return TRUE;
}
-static void
-delete_folder (MailStub *stub, const gchar *folder_name)
+gboolean
+camel_exchange_utils_delete_folder (CamelService *service,
+ const gchar *folder_name,
+ CamelException *ex)
{
- MailStubExchange *mse = MAIL_STUB_EXCHANGE (stub);
+ ExchangeData *ed = get_data_for_service (service);
ExchangeAccountFolderResult result;
EFolder *folder;
gchar *path;
+ g_return_val_if_fail (ed != NULL, FALSE);
+
path = g_build_filename ("/", folder_name, NULL);
- folder = exchange_account_get_folder (mse->account, path);
+ folder = exchange_account_get_folder (ed->account, path);
if (!folder) {
- mail_stub_return_error (stub, _("Folder doesn't exist"));
+ set_exception (ex, _("Folder doesn't exist"));
g_free (path);
- return;
+ return FALSE;
}
g_object_ref (folder);
- result = exchange_account_remove_folder (mse->account, path);
+ result = exchange_account_remove_folder (ed->account, path);
g_free (path);
switch (result) {
case EXCHANGE_ACCOUNT_FOLDER_OK:
case EXCHANGE_ACCOUNT_FOLDER_DOES_NOT_EXIST:
- g_hash_table_remove (mse->folders_by_name, folder_name);
+ g_hash_table_remove (ed->folders_by_name, folder_name);
break;
case EXCHANGE_ACCOUNT_FOLDER_PERMISSION_DENIED: /* Fall through */
case EXCHANGE_ACCOUNT_FOLDER_UNSUPPORTED_OPERATION:
- mail_stub_return_error (stub, _("Permission denied"));
+ set_exception (ex, _("Permission denied"));
g_object_unref (folder);
- return;
+ return FALSE;
default:
- mail_stub_return_error (stub, _("Generic error"));
+ set_exception (ex, _("Generic error"));
g_object_unref (folder);
- return;
+ return FALSE;
}
g_object_unref (folder);
- mail_stub_return_ok (stub);
+
+ return TRUE;
}
-static void
-rename_folder (MailStub *stub, const gchar *old_name, const gchar *new_name)
+gboolean
+camel_exchange_utils_rename_folder (CamelService *service,
+ const gchar *old_name,
+ const gchar *new_name,
+ GPtrArray **folder_names, /* out */
+ GPtrArray **folder_uris, /* out */
+ GArray **unread_counts, /* out */
+ GArray **folder_flags, /* out */
+ CamelException *ex)
{
- MailStubExchange *mse = MAIL_STUB_EXCHANGE (stub);
- MailStubExchangeFolder *mfld;
+ ExchangeData *ed = get_data_for_service (service);
+ ExchangeFolder *mfld;
ExchangeAccountFolderResult result;
EFolder *folder;
gchar *old_path, *new_path;
GPtrArray *names, *uris;
GArray *unread, *flags;
- gint i = 0, j = 0, mode;
+ gint i = 0, j = 0;
gchar **folder_name;
const gchar *uri;
gchar *new_name_mod, *old_name_remove, *uri_unescaped, *old_name_mod = NULL;
+ g_return_val_if_fail (ed != NULL, FALSE);
+ g_return_val_if_fail (folder_names != NULL, FALSE);
+ g_return_val_if_fail (folder_uris != NULL, FALSE);
+ g_return_val_if_fail (unread_counts != NULL, FALSE);
+ g_return_val_if_fail (folder_flags != NULL, FALSE);
+
old_path = g_build_filename ("/", old_name, NULL);
- folder = exchange_account_get_folder (mse->account, old_path);
+ folder = exchange_account_get_folder (ed->account, old_path);
if (!folder) {
- mail_stub_return_error (stub, _("Folder doesn't exist"));
+ set_exception (ex, _("Folder doesn't exist"));
g_free (old_path);
- return;
+ return FALSE;
}
new_path = g_build_filename ("/", new_name, NULL);
- mse->ignore_removed_folder = old_path;
- mse->ignore_new_folder = new_path;
- result = exchange_account_xfer_folder (mse->account, old_path, new_path, TRUE);
- folder = exchange_account_get_folder (mse->account, new_path);
- mse->ignore_new_folder = mse->ignore_removed_folder = NULL;
+ ed->ignore_removed_folder = old_path;
+ ed->ignore_new_folder = new_path;
+ result = exchange_account_xfer_folder (ed->account, old_path, new_path, TRUE);
+ folder = exchange_account_get_folder (ed->account, new_path);
+ ed->ignore_new_folder = ed->ignore_removed_folder = NULL;
g_free (old_path);
g_free (new_path);
switch (result) {
case EXCHANGE_ACCOUNT_FOLDER_OK:
- mfld = g_hash_table_lookup (mse->folders_by_name, old_name);
+ mfld = g_hash_table_lookup (ed->folders_by_name, old_name);
if (!mfld)
break;
@@ -3150,25 +3168,23 @@ rename_folder (MailStub *stub, const gchar *old_name, const gchar *new_name)
mfld->folder = g_object_ref (folder);
mfld->name = e_folder_exchange_get_path (folder) + 1;
- g_hash_table_steal (mse->folders_by_name, old_name);
- g_hash_table_insert (mse->folders_by_name, (gchar *)mfld->name, mfld);
+ g_hash_table_steal (ed->folders_by_name, old_name);
+ g_hash_table_insert (ed->folders_by_name, (gchar *)mfld->name, mfld);
- get_folder_info_data (stub, new_name, CAMEL_STUB_STORE_FOLDER_INFO_SUBSCRIBED,
- &names, &uris, &unread, &flags);
+ get_folder_info_data (ed, new_name, CAMEL_STORE_FOLDER_INFO_SUBSCRIBED, &names, &uris, &unread, &flags);
g_hash_table_remove_all (mfld->messages_by_href);
for (i = 0; i < mfld->messages->len; i++) {
- MailStubExchangeMessage *mmsg;
+ ExchangeMessage *mmsg;
mmsg = mfld->messages->pdata[i];
g_free (mmsg->href);
mmsg->href = NULL;
}
- exchange_component_is_offline (global_exchange_component, &mode);
- if (mode == ONLINE_MODE) {
- if (!get_folder_online (mfld, TRUE)) {
- return;
+ if (is_online (ed) == ONLINE_MODE) {
+ if (!get_folder_online (mfld, ex)) {
+ return FALSE;
}
}
@@ -3194,9 +3210,9 @@ rename_folder (MailStub *stub, const gchar *old_name, const gchar *new_name)
old_name_remove = g_build_filename (old_name, "/", folder_name[1], NULL);
- mfld = g_hash_table_lookup (mse->folders_by_name, old_name_remove);
+ mfld = g_hash_table_lookup (ed->folders_by_name, old_name_remove);
- /* If the lookup for the MailStubExchangeFolder doesn't succeed then do
+ /* If the lookup for the ExchangeFolder doesn't succeed then do
not modify the corresponding entry in the hash table*/
if (!mfld) {
g_free (old_name_remove);
@@ -3206,103 +3222,98 @@ rename_folder (MailStub *stub, const gchar *old_name, const gchar *new_name)
new_path = g_build_filename ("/", new_name_mod, folder_name[1], NULL);
old_path = g_build_filename ("/", old_name_remove, NULL);
- mse->ignore_removed_folder = old_path;
- mse->ignore_new_folder = new_path;
- result = exchange_account_xfer_folder (mse->account, old_path, new_path, TRUE);
- folder = exchange_account_get_folder (mse->account, new_path);
- mse->ignore_new_folder = mse->ignore_removed_folder = NULL;
+ ed->ignore_removed_folder = old_path;
+ ed->ignore_new_folder = new_path;
+ result = exchange_account_xfer_folder (ed->account, old_path, new_path, TRUE);
+ folder = exchange_account_get_folder (ed->account, new_path);
+ ed->ignore_new_folder = ed->ignore_removed_folder = NULL;
g_object_unref (mfld->folder);
mfld->folder = g_object_ref (folder);
mfld->name = e_folder_exchange_get_path (folder) + 1;
- g_hash_table_steal (mse->folders_by_name, old_name_remove);
- g_hash_table_insert (mse->folders_by_name, (gchar *)mfld->name, mfld);
+ g_hash_table_steal (ed->folders_by_name, old_name_remove);
+ g_hash_table_insert (ed->folders_by_name, (gchar *)mfld->name, mfld);
g_hash_table_remove_all (mfld->messages_by_href);
for (j = 0; j < mfld->messages->len; j++) {
- MailStubExchangeMessage *mmsg;
+ ExchangeMessage *mmsg;
mmsg = mfld->messages->pdata[j];
g_free (mmsg->href);
mmsg->href = NULL;
}
- exchange_component_is_offline (global_exchange_component, &mode);
- if (mode == ONLINE_MODE) {
- if (!get_folder_online (mfld, TRUE)) {
- return;
+ if (is_online (ed) == ONLINE_MODE) {
+ if (!get_folder_online (mfld, ex)) {
+ return FALSE;
}
}
g_free (old_path);
g_free (new_path);
-cont_free: g_free (new_name_mod);
+ cont_free: g_free (new_name_mod);
g_free (uri_unescaped);
g_strfreev (folder_name);
}
- mail_stub_return_data (stub, CAMEL_STUB_RETVAL_RESPONSE,
- CAMEL_STUB_ARG_STRINGARRAY, names,
- CAMEL_STUB_ARG_STRINGARRAY, uris,
- CAMEL_STUB_ARG_UINT32ARRAY, unread,
- CAMEL_STUB_ARG_UINT32ARRAY, flags,
- CAMEL_STUB_ARG_END);
-
- g_ptr_array_free (names, TRUE);
- g_ptr_array_free (uris, TRUE);
- g_array_free (unread, TRUE);
- g_array_free (flags, TRUE);
+ *folder_names = names;
+ *folder_uris = uris;
+ *unread_counts = unread;
+ *folder_flags = flags;
break;
case EXCHANGE_ACCOUNT_FOLDER_DOES_NOT_EXIST:
- mail_stub_return_error (stub, _("Folder doesn't exist"));
- return;
+ set_exception (ex, _("Folder doesn't exist"));
+ return FALSE;
case EXCHANGE_ACCOUNT_FOLDER_PERMISSION_DENIED:
- mail_stub_return_error (stub, _("Permission denied"));
- return;
+ set_exception (ex, _("Permission denied"));
+ return FALSE;
default:
- mail_stub_return_error (stub, _("Generic error"));
- return;
+ set_exception (ex, _("Generic error"));
+ return FALSE;
}
- mail_stub_return_ok (stub);
+ return TRUE;
}
-static void
-subscribe_folder (MailStub *stub, const gchar *folder_name)
+gboolean
+camel_exchange_utils_subscribe_folder (CamelService *service,
+ const gchar *folder_name,
+ CamelException *ex)
{
- MailStubExchange *mse = MAIL_STUB_EXCHANGE (stub);
+ ExchangeData *ed = get_data_for_service (service);
ExchangeAccountFolderResult result;
EFolder *folder;
gchar *path;
+ g_return_val_if_fail (ed != NULL, FALSE);
+
path = g_build_filename ("/", folder_name, NULL);
- folder = exchange_account_get_folder (mse->account, path);
+ folder = exchange_account_get_folder (ed->account, path);
if (!folder) {
- mail_stub_return_error (stub, _("Folder doesn't exist"));
+ set_exception (ex, _("Folder doesn't exist"));
g_free (path);
- return;
+ return FALSE;
}
g_free (path);
g_object_ref (folder);
if (e_folder_exchange_get_hierarchy (folder)->type != EXCHANGE_HIERARCHY_PUBLIC) {
g_object_unref (folder);
- mail_stub_return_ok (stub);
- return;
+ return TRUE;
}
if (!strcmp (e_folder_get_type_string (folder), "noselect")) {
g_object_unref (folder);
- mail_stub_return_ok (stub);
- return;
+ return TRUE;
}
- result = exchange_account_add_favorite (mse->account, folder);
+ result = exchange_account_add_favorite (ed->account, folder);
+ g_object_unref (folder);
switch (result) {
case EXCHANGE_ACCOUNT_FOLDER_OK:
@@ -3310,35 +3321,35 @@ subscribe_folder (MailStub *stub, const gchar *folder_name)
break;
case EXCHANGE_ACCOUNT_FOLDER_PERMISSION_DENIED:
- mail_stub_return_error (stub, _("Permission denied"));
- g_object_unref (folder);
- return;
+ set_exception (ex, _("Permission denied"));
+ return FALSE;
default:
- mail_stub_return_error (stub, _("Generic error"));
- g_object_unref (folder);
- return;
+ set_exception (ex, _("Generic error"));
+ return FALSE;
}
- g_object_unref (folder);
- mail_stub_return_ok (stub);
+ return TRUE;
}
-static void
-unsubscribe_folder (MailStub *stub, const gchar *folder_name)
+gboolean
+camel_exchange_utils_unsubscribe_folder (CamelService *service,
+ const gchar *folder_name,
+ CamelException *ex)
{
- MailStubExchange *mse = MAIL_STUB_EXCHANGE (stub);
+ ExchangeData *ed = get_data_for_service (service);
ExchangeAccountFolderResult result;
EFolder *folder;
gchar *path, *pub_name;
- d(printf ("unsubscribe folder : %s\n", folder_name));
+ g_return_val_if_fail (ed != NULL, FALSE);
+
path = g_build_filename ("/", folder_name, NULL);
- folder = exchange_account_get_folder (mse->account, path);
+ folder = exchange_account_get_folder (ed->account, path);
if (!folder) {
- mail_stub_return_error (stub, _("Folder doesn't exist"));
+ set_exception (ex, _("Folder doesn't exist"));
g_free (path);
- return;
+ return FALSE;
}
g_free (path);
g_object_ref (folder);
@@ -3346,221 +3357,79 @@ unsubscribe_folder (MailStub *stub, const gchar *folder_name)
/* if (e_folder_exchange_get_hierarchy (folder)->type != EXCHANGE_HIERARCHY_FAVORITES) {
Should use above check, but the internal uri is the same for both
public and favorite hierarchies and any of them can be used for the check */
- if (!exchange_account_is_favorite_folder (mse->account, folder)) {
+ if (!exchange_account_is_favorite_folder (ed->account, folder)) {
g_object_unref (folder);
- mail_stub_return_ok (stub);
- return;
+ return TRUE;
}
g_object_unref (folder);
pub_name = strrchr (folder_name, '/');
path = g_build_filename ("/favorites", pub_name, NULL);
- folder = exchange_account_get_folder (mse->account, path);
+ folder = exchange_account_get_folder (ed->account, path);
if (!folder) {
- mail_stub_return_error (stub, _("Folder doesn't exist"));
+ set_exception (ex, _("Folder doesn't exist"));
g_free (path);
- return;
+ return FALSE;
}
g_object_ref (folder);
- result = exchange_account_remove_favorite (mse->account, folder);
+ result = exchange_account_remove_favorite (ed->account, folder);
switch (result) {
case EXCHANGE_ACCOUNT_FOLDER_OK:
case EXCHANGE_ACCOUNT_FOLDER_DOES_NOT_EXIST:
- g_hash_table_remove (mse->folders_by_name, path + 1);
+ g_hash_table_remove (ed->folders_by_name, path + 1);
break;
case EXCHANGE_ACCOUNT_FOLDER_PERMISSION_DENIED:
- mail_stub_return_error (stub, _("Permission denied"));
+ set_exception (ex, _("Permission denied"));
g_object_unref (folder);
g_free (path);
- return;
+ return FALSE;
default:
- mail_stub_return_error (stub, _("Generic error"));
+ set_exception (ex, _("Generic error"));
g_object_unref (folder);
g_free (path);
- return;
+ return FALSE;
}
g_object_unref (folder);
g_free (path);
- mail_stub_return_ok (stub);
+
+ return TRUE;
}
-static void
-is_subscribed_folder (MailStub *stub, const gchar *folder_name)
+gboolean
+camel_exchange_utils_is_subscribed_folder (CamelService *service,
+ const gchar *folder_name,
+ gboolean *is_subscribed, /* out */
+ CamelException *ex)
{
- MailStubExchange *mse = MAIL_STUB_EXCHANGE (stub);
+ ExchangeData *ed = get_data_for_service (service);
EFolder *folder;
gchar *path;
- guint32 is_subscribed = 0;
+
+ g_return_val_if_fail (ed != NULL, FALSE);
+ g_return_val_if_fail (is_subscribed != NULL, FALSE);
+
+ *is_subscribed = FALSE;
path = g_build_filename ("/", folder_name, NULL);
- folder = exchange_account_get_folder (mse->account, path);
+ folder = exchange_account_get_folder (ed->account, path);
if (!folder) {
g_free (path);
- mail_stub_return_data (stub, CAMEL_STUB_RETVAL_RESPONSE,
- CAMEL_STUB_ARG_UINT32, is_subscribed,
- CAMEL_STUB_ARG_END);
- mail_stub_return_ok (stub);
- return;
+ return TRUE;
}
g_free (path);
g_object_ref (folder);
- if (exchange_account_is_favorite_folder (mse->account, folder))
- is_subscribed = 1;
+ if (exchange_account_is_favorite_folder (ed->account, folder))
+ *is_subscribed = TRUE;
g_object_unref (folder);
- mail_stub_return_data (stub, CAMEL_STUB_RETVAL_RESPONSE,
- CAMEL_STUB_ARG_UINT32, is_subscribed,
- CAMEL_STUB_ARG_END);
- mail_stub_return_ok (stub);
-}
-
-static void
-stub_connect (MailStub *stub, gchar *pwd)
-{
- MailStubExchange *mse = MAIL_STUB_EXCHANGE (stub);
- ExchangeAccount *account;
- ExchangeAccountResult result;
- E2kContext *ctx;
- guint32 retval = 1;
- const gchar *uri;
- gint mode;
-
- exchange_component_is_offline (global_exchange_component, &mode);
-
- account = mse->account;
- if (mode == ONLINE_MODE)
- exchange_account_set_online (account);
- else if (mode == OFFLINE_MODE)
- exchange_account_set_offline (account);
-
- ctx = exchange_account_get_context (account);
- if (!ctx) {
- ctx = exchange_account_connect (account, pwd, &result);
- }
-
- if (!ctx && mode == ONLINE_MODE) {
- retval = 0;
- goto end;
- } else if (mode == OFFLINE_MODE) {
- goto end;
- }
-
- mse->ctx = g_object_ref (ctx);
-
- mse->mail_submission_uri = exchange_account_get_standard_uri (account, "sendmsg");
- uri = exchange_account_get_standard_uri (account, "inbox");
- mse->inbox = exchange_account_get_folder (account, uri);
- uri = exchange_account_get_standard_uri (account, "deleteditems");
- mse->deleted_items = exchange_account_get_folder (account, uri);
- uri = exchange_account_get_standard_uri (account, "sentitems");
- mse->sent_items = exchange_account_get_folder (account, uri);
-
- /* Will be used for offline->online transition to initialize things for
- the first time */
-
- g_hash_table_foreach (mse->folders_by_name,
- (GHFunc) folder_update_linestatus,
- GINT_TO_POINTER (mode));
-end:
- mail_stub_return_data (stub, CAMEL_STUB_RETVAL_RESPONSE,
- CAMEL_STUB_ARG_UINT32, retval,
- CAMEL_STUB_ARG_END);
-
- mail_stub_return_ok (stub);
-}
-
-#if 0
-static void
-linestatus_listener (ExchangeComponent *component,
- gint linestatus,
- gpointer data)
-{
- MailStubExchange *mse = MAIL_STUB_EXCHANGE (data);
- ExchangeAccount *account = mse->account;
- const gchar *uri;
-
- if (linestatus == ONLINE_MODE && mse->ctx == NULL) {
- mse->ctx = exchange_account_get_context (account);
- g_object_ref (mse->ctx);
-
- mse->mail_submission_uri = exchange_account_get_standard_uri (account, "sendmsg");
- uri = exchange_account_get_standard_uri (account, "inbox");
- mse->inbox = exchange_account_get_folder (account, uri);
- uri = exchange_account_get_standard_uri (account, "deleteditems");
- mse->deleted_items = exchange_account_get_folder (account, uri);
- g_hash_table_foreach (mse->folders_by_name,
- (GHFunc) folder_update_linestatus,
- GINT_TO_POINTER (linestatus));
-
- g_signal_handler_disconnect (G_OBJECT (component),
- offline_listener_handler_id);
- offline_listener_handler_id = 0;
- } else if (mse->ctx != NULL) {
- g_signal_handler_disconnect (G_OBJECT (component),
- offline_listener_handler_id);
- offline_listener_handler_id = 0;
- }
-}
-
-#endif
-
-static void
-folder_update_linestatus (gpointer key, gpointer value, gpointer data)
-{
- MailStubExchangeFolder *mfld = (MailStubExchangeFolder *) value;
- MailStub *stub = MAIL_STUB (mfld->mse);
- gint linestatus = GPOINTER_TO_INT (data);
- guint32 readonly;
-
- if (linestatus == ONLINE_MODE) {
- get_folder_online (mfld, TRUE);
- readonly = (mfld->access & (MAPI_ACCESS_MODIFY | MAPI_ACCESS_CREATE_CONTENTS)) ? 0 : 1;
- mail_stub_return_data (stub, CAMEL_STUB_RETVAL_FOLDER_SET_READONLY,
- CAMEL_STUB_ARG_FOLDER, mfld->name,
- CAMEL_STUB_ARG_UINT32, readonly,
- CAMEL_STUB_ARG_END);
- }
- else {
- /* FIXME: need any undo for offline */ ;
- }
-}
-
-/**
- * mail_stub_exchange_new:
- * @account: the #ExchangeAccount this stub is for
- * @cmd_fd: command socket file descriptor
- * @status_fd: status socket file descriptor
- *
- * Creates a new #MailStubExchange for @account, communicating over
- * @cmd_fd and @status_fd.
- *
- * Return value: the new stub
- **/
-MailStub *
-mail_stub_exchange_new (ExchangeAccount *account, gint cmd_fd, gint status_fd)
-{
- MailStubExchange *mse;
- MailStub *stub;
-
- stub = g_object_new (MAIL_TYPE_STUB_EXCHANGE, NULL);
- g_object_ref (stub);
- mail_stub_construct (stub, cmd_fd, status_fd);
-
- mse = (MailStubExchange *)stub;
- mse->account = account;
-
- /* offline_listener_handler_id = g_signal_connect (G_OBJECT (global_exchange_component),
- "linestatus-changed",
- G_CALLBACK (linestatus_listener), mse); */
- return stub;
+ return TRUE;
}
-
diff --git a/camel/camel-exchange-utils.h b/camel/camel-exchange-utils.h
new file mode 100644
index 0000000..be22166
--- /dev/null
+++ b/camel/camel-exchange-utils.h
@@ -0,0 +1,141 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+/* Copyright (C) 2001-2004 Novell, Inc. */
+
+#ifndef CAMEL_EXCHANGE_UTILS_H
+#define CAMEL_EXCHANGE_UTILS_H
+
+#include <camel/camel-service.h>
+#include <camel/camel-exception.h>
+
+G_BEGIN_DECLS
+
+gboolean camel_exchange_utils_connect (CamelService *service,
+ const gchar *pwd,
+ guint32 *status, /* out */
+ CamelException *ex);
+
+gboolean camel_exchange_utils_get_folder (CamelService *service,
+ const gchar *name,
+ gboolean create,
+ GPtrArray *uids,
+ GByteArray *flags,
+ GPtrArray *hrefs,
+ guint32 high_article_num,
+ guint32 *folder_flags, /* out */
+ gchar **folder_uri, /* out */
+ gboolean *readonly, /* out */
+ CamelException *ex);
+
+gboolean camel_exchange_utils_get_trash_name (CamelService *service,
+ gchar **trash_name, /* out */
+ CamelException *ex);
+
+gboolean camel_exchange_utils_refresh_folder (CamelService *service,
+ const gchar *folder_name,
+ CamelException *ex);
+
+gboolean camel_exchange_utils_sync_count (CamelService *service,
+ const gchar *folder_name,
+ guint32 *unread_count, /* out */
+ guint32 *visible_count, /* out */
+ CamelException *ex);
+
+gboolean camel_exchange_utils_expunge_uids (CamelService *service,
+ const gchar *folder_name,
+ GPtrArray *uids,
+ CamelException *ex);
+
+gboolean camel_exchange_utils_append_message (CamelService *service,
+ const gchar *folder_name,
+ guint32 flags,
+ const gchar *subject,
+ const GByteArray *message,
+ gchar **new_uid, /* out */
+ CamelException *ex);
+
+gboolean camel_exchange_utils_set_message_flags (CamelService *service,
+ const gchar *folder_name,
+ const gchar *uid,
+ guint32 flags,
+ guint32 mask,
+ CamelException *ex);
+
+gboolean camel_exchange_utils_set_message_tag (CamelService *service,
+ const gchar *folder_name,
+ const gchar *uid,
+ const gchar *name,
+ const gchar *value,
+ CamelException *ex);
+
+gboolean camel_exchange_utils_get_message (CamelService *service,
+ const gchar *folder_name,
+ const gchar *uid,
+ GByteArray **message_bytes, /* out */
+ CamelException *ex);
+
+gboolean camel_exchange_utils_search (CamelService *service,
+ const gchar *folder_name,
+ const gchar *text,
+ GPtrArray **found_uids, /* out */
+ CamelException *ex);
+
+gboolean camel_exchange_utils_transfer_messages (CamelService *service,
+ const gchar *source_name,
+ const gchar *dest_name,
+ GPtrArray *uids,
+ gboolean delete_originals,
+ GPtrArray **ret_uids, /* out */
+ CamelException *ex);
+
+gboolean camel_exchange_utils_get_folder_info (CamelService *service,
+ const gchar *top,
+ guint32 store_flags,
+ GPtrArray **folder_names, /* out */
+ GPtrArray **folder_uris, /* out */
+ GArray **unread_counts, /* out */
+ GArray **folder_flags, /* out */
+ CamelException *ex);
+
+gboolean camel_exchange_utils_send_message (CamelService *service,
+ const gchar *from,
+ GPtrArray *recipients,
+ const GByteArray *message,
+ CamelException *ex);
+
+gboolean camel_exchange_utils_create_folder (CamelService *service,
+ const gchar *parent_name,
+ const gchar *folder_name,
+ gchar **folder_uri, /* out */
+ guint32 *unread_count, /* out */
+ guint32 *flags, /* out */
+ CamelException *ex);
+
+gboolean camel_exchange_utils_delete_folder (CamelService *service,
+ const gchar *folder_name,
+ CamelException *ex);
+
+gboolean camel_exchange_utils_rename_folder (CamelService *service,
+ const gchar *old_name,
+ const gchar *new_name,
+ GPtrArray **folder_names, /* out */
+ GPtrArray **folder_uris, /* out */
+ GArray **unread_counts, /* out */
+ GArray **folder_flags, /* out */
+ CamelException *ex);
+
+gboolean camel_exchange_utils_subscribe_folder (CamelService *service,
+ const gchar *folder_name,
+ CamelException *ex);
+
+gboolean camel_exchange_utils_unsubscribe_folder (CamelService *service,
+ const gchar *folder_name,
+ CamelException *ex);
+
+gboolean camel_exchange_utils_is_subscribed_folder (CamelService *service,
+ const gchar *folder_name,
+ gboolean *is_subscribed, /* out */
+ CamelException *ex);
+
+G_END_DECLS
+
+#endif /* CAMEL_EXCHANGE_UTILS_H */
diff --git a/mail/mail-utils.c b/camel/mail-utils.c
similarity index 97%
rename from mail/mail-utils.c
rename to camel/mail-utils.c
index 26e81da..4505378 100644
--- a/mail/mail-utils.c
+++ b/camel/mail-utils.c
@@ -22,7 +22,6 @@
#endif
#include "mail-utils.h"
-#include "mail-stub.h"
#include <e2k-propnames.h>
#include <e2k-utils.h>
#include <mapi.h>
@@ -31,6 +30,7 @@
#include <stdlib.h>
#include <string.h>
+#include <camel/camel-folder-summary.h>
#include <libedataserver/e-data-server-util.h>
#include <e-util/e-html-utils.h>
#include <e-util/e-util.h>
@@ -123,32 +123,32 @@ mail_util_props_to_camel_flags (E2kProperties *props, gboolean obey_read_flag)
prop = e2k_properties_get_prop (props, E2K_PR_HTTPMAIL_READ);
if ((prop && atoi (prop)) || !obey_read_flag)
- flags |= MAIL_STUB_MESSAGE_SEEN;
+ flags |= CAMEL_MESSAGE_SEEN;
prop = e2k_properties_get_prop (props, E2K_PR_HTTPMAIL_HAS_ATTACHMENT);
if (prop && atoi (prop))
- flags |= MAIL_STUB_MESSAGE_ATTACHMENTS;
+ flags |= CAMEL_MESSAGE_ATTACHMENTS;
prop = e2k_properties_get_prop (props, PR_ACTION_FLAG);
if (prop) {
val = atoi (prop);
if (val == MAPI_ACTION_FLAG_REPLIED_TO_SENDER)
- flags |= MAIL_STUB_MESSAGE_ANSWERED;
+ flags |= CAMEL_MESSAGE_ANSWERED;
else if (val == MAPI_ACTION_FLAG_REPLIED_TO_ALL) {
- flags |= (MAIL_STUB_MESSAGE_ANSWERED |
- MAIL_STUB_MESSAGE_ANSWERED_ALL);
+ flags |= (CAMEL_MESSAGE_ANSWERED |
+ CAMEL_MESSAGE_ANSWERED_ALL);
}
}
prop = e2k_properties_get_prop (props, PR_DELEGATED_BY_RULE);
if (prop && atoi (prop))
- flags |= MAIL_STUB_MESSAGE_DELEGATED;
+ flags |= EXMAIL_DELEGATED;
prop = e2k_properties_get_prop (props, PR_IMPORTANCE);
if (prop) {
val = atoi (prop);
if (val == MAPI_IMPORTANCE_HIGH)
- flags |= MAIL_STUB_MESSAGE_FLAGGED;
+ flags |= CAMEL_MESSAGE_FLAGGED;
}
return flags;
diff --git a/mail/mail-utils.h b/camel/mail-utils.h
similarity index 90%
rename from mail/mail-utils.h
rename to camel/mail-utils.h
index 15fc1b2..588485f 100644
--- a/mail/mail-utils.h
+++ b/camel/mail-utils.h
@@ -4,8 +4,12 @@
#ifndef __MAIL_UTILS_H__
#define __MAIL_UTILS_H__
+#include <camel/camel-folder-summary.h>
+
#include "e2k-properties.h"
+#define EXMAIL_DELEGATED CAMEL_MESSAGE_FOLDER_FLAGGED
+
G_BEGIN_DECLS
typedef enum {
diff --git a/configure.ac b/configure.ac
index 9258041..e7003c0 100644
--- a/configure.ac
+++ b/configure.ac
@@ -4,7 +4,7 @@ AC_PREREQ(2.52)
m4_define([eex_version], [2.29.1])
AC_INIT(evolution-exchange, [eex_version], http://bugzilla.gnome.org/enter_bug.cgi?product=Evolution%20Exchange)
-AC_CONFIG_SRCDIR(storage)
+AC_CONFIG_SRCDIR(camel)
AM_INIT_AUTOMAKE(AC_PACKAGE_NAME, AC_PACKAGE_VERSION)
# Required Package Versions
@@ -375,10 +375,9 @@ AC_OUTPUT([
Makefile
evolution-exchange-zip
camel/Makefile
-mail/Makefile
addressbook/Makefile
calendar/Makefile
-storage/Makefile
+tools/Makefile
docs/Makefile
docs/reference/Makefile
po/Makefile.in
diff --git a/po/POTFILES.in b/po/POTFILES.in
index 4095e2d..d9a9de1 100644
--- a/po/POTFILES.in
+++ b/po/POTFILES.in
@@ -10,14 +10,9 @@ camel/camel-exchange-journal.c
camel/camel-exchange-provider.c
camel/camel-exchange-store.c
camel/camel-exchange-transport.c
-camel/camel-stub.c
-mail/mail-stub-exchange.c
-storage/GNOME_Evolution_Exchange_Storage.server.in.in
-storage/exchange-autoconfig-wizard.c
-storage/exchange-component.c
-storage/exchange-config-listener.c
-storage/exchange-migrate.c
-storage/exchange-storage.c
-storage/main.c
-storage/ximian-connector-setup.c
-storage/ximian-connector.xml
+camel/camel-exchange-utils.c
+camel/mail-utils.c
+tools/exchange-autoconfig-wizard.c
+tools/exchange-share-config-listener.c
+tools/ximian-connector-setup.c
+tools/ximian-connector.xml
diff --git a/po/POTFILES.skip b/po/POTFILES.skip
index b6f5188..e69de29 100644
--- a/po/POTFILES.skip
+++ b/po/POTFILES.skip
@@ -1,5 +0,0 @@
-storage/exchange-delegates-user.c
-storage/exchange-delegates.c
-storage/exchange-permissions-dialog.c
-storage/xc-backend-view.c
-storage/xc-commands.c
diff --git a/tools/Makefile.am b/tools/Makefile.am
new file mode 100644
index 0000000..6118cf2
--- /dev/null
+++ b/tools/Makefile.am
@@ -0,0 +1,78 @@
+AM_CPPFLAGS = \
+ -I$(top_srcdir) \
+ -I$(top_srcdir)/camel \
+ -DG_LOG_DOMAIN=\"evolution-exchange-storage\" \
+ $(LIBEXCHANGE_CFLAGS) \
+ $(EXCHANGE_STORAGE_CFLAGS) \
+ $(LDAP_CFLAGS) \
+ -DPREFIX=\"$(prefix)\" \
+ -DSYSCONFDIR=\""$(sysconfdir)"\" \
+ -DDATADIR=\""$(datadir)"\" \
+ -DLIBDIR=\""$(datadir)"\" \
+ -DCONNECTOR_IMAGESDIR=\""$(imagesdir)"\" \
+ -DCONNECTOR_UIDIR=\""$(uidir)"\" \
+ -DCONNECTOR_LOCALEDIR=\""$(localedir)\""
+
+noinst_PROGRAMS = \
+ exchange-connector-setup
+# migr-test
+
+noinst_LTLIBRARIES = libevolution-exchange-shared.la
+
+libevolution_exchange_shared_la_SOURCES = \
+ exchange-share-config-listener.h \
+ exchange-share-config-listener.c
+
+libevolution_exchange_shared_la_LIBADD = \
+ $(EXCHANGE_STORAGE_LIBS) \
+ $(LIBEXCHANGE_LIBS)
+
+libevolution_exchange_shared_la_LDFLAGS = $(NO_UNDEFINED)
+
+exchange_connector_setup_SOURCES = \
+ ximian-connector-setup.c \
+ exchange-autoconfig-wizard.h \
+ exchange-autoconfig-wizard.c
+
+exchange_connector_setup_LDADD = \
+ $(LDAP_LIBS) \
+ $(EXCHANGE_STORAGE_LIBS) \
+ $(LIBEXCHANGE_LIBS)
+
+install-exec-local: exchange-connector-setup
+ $(mkinstalldirs) $(DESTDIR)$(bindir)
+ $(LIBTOOL) --mode=install $(INSTALL_PROGRAM) exchange-connector-setup $(DESTDIR)$(bindir)/exchange-connector-setup-$(BASE_VERSION)
+
+uninstall-local:
+ rm -rf $(DESTDIR)$(bindir)/exchange-connector-setup-$(BASE_VERSION)
+
+#migr_test_SOURCES = \
+# migr-test.c \
+# exchange-config-listener.c \
+# exchange-config-listener.h \
+# exchange-migrate.c \
+# exchange-migrate.h
+#
+#migr_test_LDADD = \
+# $(LDAP_LIBS) \
+# $(EXCHANGE_STORAGE_LIBS) \
+# $(LIBEXCHANGE_LIBS)
+#
+
+imagesdir = $(CONNECTOR_DATADIR)/images
+images_DATA = \
+ connector.png \
+ connector-mini.png \
+ exchange-delegates-48.png \
+ exchange-oof-48.png
+
+uidir = $(CONNECTOR_DATADIR)/ui
+ui_DATA = ximian-connector.xml
+
+#DISTCLEANFILES =
+
+EXTRA_DIST = \
+ $(images_DATA) \
+ $(ui_DATA)
+
+-include $(top_srcdir)/git.mk
diff --git a/storage/connector-mini.png b/tools/connector-mini.png
similarity index 100%
rename from storage/connector-mini.png
rename to tools/connector-mini.png
diff --git a/storage/connector.png b/tools/connector.png
similarity index 100%
rename from storage/connector.png
rename to tools/connector.png
diff --git a/storage/exchange-autoconfig-wizard.c b/tools/exchange-autoconfig-wizard.c
similarity index 99%
rename from storage/exchange-autoconfig-wizard.c
rename to tools/exchange-autoconfig-wizard.c
index 43cb98b..4929d8c 100644
--- a/storage/exchange-autoconfig-wizard.c
+++ b/tools/exchange-autoconfig-wizard.c
@@ -37,8 +37,6 @@
#include <gconf/gconf-client.h>
#include <gtk/gtk.h>
-#include "exchange-storage.h"
-
#ifdef G_OS_WIN32
#undef CONNECTOR_IMAGESDIR
diff --git a/storage/exchange-autoconfig-wizard.h b/tools/exchange-autoconfig-wizard.h
similarity index 100%
rename from storage/exchange-autoconfig-wizard.h
rename to tools/exchange-autoconfig-wizard.h
diff --git a/storage/exchange-delegates-48.png b/tools/exchange-delegates-48.png
similarity index 100%
rename from storage/exchange-delegates-48.png
rename to tools/exchange-delegates-48.png
diff --git a/storage/exchange-oof-48.png b/tools/exchange-oof-48.png
similarity index 100%
rename from storage/exchange-oof-48.png
rename to tools/exchange-oof-48.png
diff --git a/storage/exchange-config-listener.c b/tools/exchange-share-config-listener.c
similarity index 80%
rename from storage/exchange-config-listener.c
rename to tools/exchange-share-config-listener.c
index 2c336ac..499841d 100644
--- a/storage/exchange-config-listener.c
+++ b/tools/exchange-share-config-listener.c
@@ -17,7 +17,7 @@
* Boston, MA 02111-1307, USA.
*/
-/* ExchangeConfigListener: a class that listens to the config database
+/* ExchangeShareConfigListener: a class that listens to the config database
* and handles creating the ExchangeAccount object and making sure that
* default folders are updated as needed.
*/
@@ -48,13 +48,10 @@
#include <e-util/e-dialog-utils.h>
-#include "mail-stub-listener.h"
+#include "exchange-share-config-listener.h"
-#include "exchange-config-listener.h"
-
-struct _ExchangeConfigListenerPrivate {
+struct _ExchangeShareConfigListenerPrivate {
GConfClient *gconf;
- guint idle_id;
gchar *configured_uri, *configured_name;
EAccount *configured_account;
@@ -81,6 +78,8 @@ static guint signals [LAST_SIGNAL] = { 0 };
#define CONF_KEY_SELECTED_CAL_SOURCES "/apps/evolution/calendar/display/selected_calendars"
#define CONF_KEY_SELECTED_TASKS_SOURCES "/apps/evolution/calendar/tasks/selected_tasks"
+static GStaticMutex ecl_mutex = G_STATIC_MUTEX_INIT;
+
static EAccountListClass *parent_class = NULL;
static void dispose (GObject *object);
@@ -117,7 +116,7 @@ class_init (GObjectClass *object_class)
g_signal_new ("exchange_account_created",
G_OBJECT_CLASS_TYPE (object_class),
G_SIGNAL_RUN_LAST,
- G_STRUCT_OFFSET (ExchangeConfigListenerClass, exchange_account_created),
+ G_STRUCT_OFFSET (ExchangeShareConfigListenerClass, exchange_account_created),
NULL, NULL,
g_cclosure_marshal_VOID__POINTER,
G_TYPE_NONE, 1,
@@ -126,7 +125,7 @@ class_init (GObjectClass *object_class)
g_signal_new ("exchange_account_removed",
G_OBJECT_CLASS_TYPE (object_class),
G_SIGNAL_RUN_LAST,
- G_STRUCT_OFFSET (ExchangeConfigListenerClass, exchange_account_removed),
+ G_STRUCT_OFFSET (ExchangeShareConfigListenerClass, exchange_account_removed),
NULL, NULL,
g_cclosure_marshal_VOID__POINTER,
G_TYPE_NONE, 1,
@@ -136,22 +135,17 @@ class_init (GObjectClass *object_class)
static void
init (GObject *object)
{
- ExchangeConfigListener *config_listener =
- EXCHANGE_CONFIG_LISTENER (object);
+ ExchangeShareConfigListener *config_listener =
+ EXCHANGE_SHARE_CONFIG_LISTENER (object);
- config_listener->priv = g_new0 (ExchangeConfigListenerPrivate, 1);
+ config_listener->priv = g_new0 (ExchangeShareConfigListenerPrivate, 1);
}
static void
dispose (GObject *object)
{
- ExchangeConfigListener *config_listener =
- EXCHANGE_CONFIG_LISTENER (object);
-
- if (config_listener->priv->idle_id) {
- g_source_remove (config_listener->priv->idle_id);
- config_listener->priv->idle_id = 0;
- }
+ ExchangeShareConfigListener *config_listener =
+ EXCHANGE_SHARE_CONFIG_LISTENER (object);
if (config_listener->priv->gconf) {
g_object_unref (config_listener->priv->gconf);
@@ -164,8 +158,8 @@ dispose (GObject *object)
static void
finalize (GObject *object)
{
- ExchangeConfigListener *config_listener =
- EXCHANGE_CONFIG_LISTENER (object);
+ ExchangeShareConfigListener *config_listener =
+ EXCHANGE_SHARE_CONFIG_LISTENER (object);
g_free (config_listener->priv->configured_name);
g_free (config_listener->priv->configured_uri);
@@ -174,7 +168,7 @@ finalize (GObject *object)
G_OBJECT_CLASS (parent_class)->finalize (object);
}
-E2K_MAKE_TYPE (exchange_config_listener, ExchangeConfigListener, class_init, init, PARENT_TYPE)
+E2K_MAKE_TYPE (exchange_share_config_listener, ExchangeShareConfigListener, class_init, init, PARENT_TYPE)
#define EVOLUTION_URI_PREFIX "evolution:/"
#define EVOLUTION_URI_PREFIX_LEN (sizeof (EVOLUTION_URI_PREFIX) - 1)
@@ -358,7 +352,7 @@ migrate_account_esource (EAccount *account,
}
void
-exchange_config_listener_migrate_esources (ExchangeConfigListener *config_listener)
+exchange_share_config_listener_migrate_esources (ExchangeShareConfigListener *config_listener)
{
EAccount *account;
@@ -374,13 +368,13 @@ exchange_config_listener_migrate_esources (ExchangeConfigListener *config_listen
static void
account_added (EAccountList *account_list, EAccount *account)
{
- ExchangeConfigListener *config_listener;
+ ExchangeShareConfigListener *config_listener;
ExchangeAccount *exchange_account;
if (!is_active_exchange_account (account))
return;
- config_listener = EXCHANGE_CONFIG_LISTENER (account_list);
+ config_listener = EXCHANGE_SHARE_CONFIG_LISTENER (account_list);
if (config_listener->priv->configured_account) {
/* Multiple accounts configured. */
return;
@@ -404,7 +398,7 @@ account_added (EAccountList *account_list, EAccount *account)
g_signal_emit (config_listener, signals[EXCHANGE_ACCOUNT_CREATED], 0,
exchange_account);
- exchange_config_listener_migrate_esources (config_listener);
+ exchange_share_config_listener_migrate_esources (config_listener);
}
struct account_update_data {
@@ -417,7 +411,7 @@ configured_account_destroyed (gpointer user_data, GObject *where_account_was)
{
struct account_update_data *aud = user_data;
- if (!EXCHANGE_CONFIG_LISTENER (aud->account_list)->priv->configured_account)
+ if (!EXCHANGE_SHARE_CONFIG_LISTENER (aud->account_list)->priv->configured_account)
account_added (aud->account_list, aud->account);
g_object_unref (aud->account_list);
@@ -485,9 +479,9 @@ end:
static void
account_changed (EAccountList *account_list, EAccount *account)
{
- ExchangeConfigListener *config_listener =
- EXCHANGE_CONFIG_LISTENER (account_list);
- ExchangeConfigListenerPrivate *priv = config_listener->priv;
+ ExchangeShareConfigListener *config_listener =
+ EXCHANGE_SHARE_CONFIG_LISTENER (account_list);
+ ExchangeShareConfigListenerPrivate *priv = config_listener->priv;
if (account != config_listener->priv->configured_account) {
if (!is_active_exchange_account (account))
@@ -569,9 +563,9 @@ account_changed (EAccountList *account_list, EAccount *account)
static void
account_removed (EAccountList *account_list, EAccount *account)
{
- ExchangeConfigListener *config_listener =
- EXCHANGE_CONFIG_LISTENER (account_list);
- ExchangeConfigListenerPrivate *priv = config_listener->priv;
+ ExchangeShareConfigListener *config_listener =
+ EXCHANGE_SHARE_CONFIG_LISTENER (account_list);
+ ExchangeShareConfigListenerPrivate *priv = config_listener->priv;
if (account != priv->configured_account)
return;
@@ -594,21 +588,10 @@ account_removed (EAccountList *account_list, EAccount *account)
}
}
-static gboolean
-idle_construct (gpointer data)
-{
- ExchangeConfigListener *config_listener = data;
-
- config_listener->priv->idle_id = 0;
- e_account_list_construct (E_ACCOUNT_LIST (config_listener),
- config_listener->priv->gconf);
- return FALSE;
-}
-
/**
- * exchange_config_listener_new:
+ * exchange_share_config_listener_new:
*
- * This creates and returns a new #ExchangeConfigListener, which
+ * This creates and returns a new #ExchangeShareConfigListener, which
* monitors GConf and creates and (theoretically) destroys accounts
* accordingly. It will emit an %account_created signal when a new
* account is created (or shortly after the listener itself is created
@@ -621,24 +604,24 @@ idle_construct (gpointer data)
*
* Return value: the new config listener.
**/
-ExchangeConfigListener *
-exchange_config_listener_new (void)
+ExchangeShareConfigListener *
+exchange_share_config_listener_new (void)
{
- ExchangeConfigListener *config_listener;
+ ExchangeShareConfigListener *config_listener;
- config_listener = g_object_new (EXCHANGE_TYPE_CONFIG_LISTENER, NULL);
+ config_listener = g_object_new (EXCHANGE_TYPE_SHARE_CONFIG_LISTENER, NULL);
config_listener->priv->gconf = gconf_client_get_default ();
- config_listener->priv->idle_id =
- g_idle_add (idle_construct, config_listener);
+ e_account_list_construct (E_ACCOUNT_LIST (config_listener),
+ config_listener->priv->gconf);
return config_listener;
}
GSList *
-exchange_config_listener_get_accounts (ExchangeConfigListener *config_listener)
+exchange_share_config_listener_get_accounts (ExchangeShareConfigListener *config_listener)
{
- g_return_val_if_fail (EXCHANGE_IS_CONFIG_LISTENER (config_listener), NULL);
+ g_return_val_if_fail (EXCHANGE_IS_SHARE_CONFIG_LISTENER (config_listener), NULL);
if (config_listener->priv->exchange_account)
return g_slist_append (NULL, config_listener->priv->exchange_account);
@@ -690,3 +673,111 @@ exchange_camel_urls_is_equal (const gchar *url1, const gchar *url2)
camel_url_free (curl2);
return TRUE;
}
+
+struct create_excl_struct
+{
+ ExchangeShareConfigListener **excl;
+ GMutex *mutex;
+ GCond *done;
+};
+
+static gboolean
+create_excl_in_main_thread (gpointer data)
+{
+ struct create_excl_struct *ces = (struct create_excl_struct *) data;
+
+ g_return_val_if_fail (data != NULL, FALSE);
+
+ g_mutex_lock (ces->mutex);
+
+ *ces->excl = exchange_share_config_listener_new ();
+ g_cond_signal (ces->done);
+
+ g_mutex_unlock (ces->mutex);
+
+ return FALSE;
+}
+
+ExchangeShareConfigListener *
+exchange_share_config_listener_get_global (void)
+{
+ static ExchangeShareConfigListener *excl = NULL;
+
+ g_static_mutex_lock (&ecl_mutex);
+ if (!excl) {
+ if (!g_main_context_is_owner (g_main_context_default ())) {
+ /* it is called from a thread, do the creation in a main thread;
+ every other call will wait until it is done */
+ struct create_excl_struct ces;
+
+ ces.excl = !
+ ces.mutex = g_mutex_new ();
+ ces.done = g_cond_new ();
+
+ g_mutex_lock (ces.mutex);
+ g_timeout_add (1, create_excl_in_main_thread, &ces);
+ g_cond_wait (ces.done, ces.mutex);
+ g_mutex_unlock (ces.mutex);
+
+ g_mutex_free (ces.mutex);
+ g_cond_free (ces.done);
+ } else {
+ excl = exchange_share_config_listener_new ();
+ }
+ }
+ g_static_mutex_unlock (&ecl_mutex);
+
+ return excl;
+}
+
+ExchangeAccount *
+exchange_share_config_listener_get_account_for_uri (ExchangeShareConfigListener *excl, const gchar *uri)
+{
+ GSList *accounts, *a;
+ ExchangeAccount *res = NULL;
+
+ g_return_val_if_fail (uri != NULL, NULL);
+
+ if (!excl)
+ excl = exchange_share_config_listener_get_global ();
+
+ g_return_val_if_fail (excl != NULL, NULL);
+
+ accounts = exchange_share_config_listener_get_accounts (excl);
+
+ /* FIXME the hack to return at least something */
+ if (g_slist_length (accounts) == 1) {
+ res = accounts->data;
+ g_slist_free (accounts);
+ return res;
+ }
+
+ for (a = accounts; a; a = a->next) {
+ ExchangeAccount *account = a->data;
+
+ g_return_val_if_fail (account != NULL, NULL);
+
+ /* Kludge for while we don't support multiple accounts */
+ if (!uri) {
+ res = account;
+ break;
+ }
+
+ if (exchange_account_get_folder (account, uri)) {
+ res = account;
+ break;
+ } else {
+ g_static_mutex_lock (&ecl_mutex);
+ exchange_account_rescan_tree (account);
+ g_static_mutex_unlock (&ecl_mutex);
+ if (exchange_account_get_folder (account, uri)) {
+ res = account;
+ break;
+ }
+ }
+ }
+
+ g_slist_free (accounts);
+
+ return res;
+}
diff --git a/tools/exchange-share-config-listener.h b/tools/exchange-share-config-listener.h
new file mode 100644
index 0000000..30d4745
--- /dev/null
+++ b/tools/exchange-share-config-listener.h
@@ -0,0 +1,69 @@
+/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */
+/* Copyright (C) 2001-2004 Novell, Inc. */
+
+#ifndef __EXCHANGE_SHARE_CONFIG_LISTENER_H__
+#define __EXCHANGE_SHARE_CONFIG_LISTENER_H__
+
+#include <exchange-types.h>
+#include <exchange-constants.h>
+#include <libedataserver/e-account-list.h>
+#include <libedataserver/e-source-list.h>
+#include <libedataserver/e-source-group.h>
+
+G_BEGIN_DECLS
+
+#define EXCHANGE_TYPE_SHARE_CONFIG_LISTENER (exchange_share_config_listener_get_type ())
+#define EXCHANGE_SHARE_CONFIG_LISTENER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), EXCHANGE_TYPE_SHARE_CONFIG_LISTENER, ExchangeShareConfigListener))
+#define EXCHANGE_SHARE_CONFIG_LISTENER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), EXCHANGE_TYPE_SHARE_CONFIG_LISTENER, ExchangeShareConfigListenerClass))
+#define EXCHANGE_IS_SHARE_CONFIG_LISTENER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), EXCHANGE_TYPE_SHARE_CONFIG_LISTENER))
+#define EXCHANGE_IS_SHARE_CONFIG_LISTENER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((obj), EXCHANGE_TYPE_SHARE_CONFIG_LISTENER))
+
+typedef struct _ExchangeShareConfigListener ExchangeShareConfigListener;
+typedef struct _ExchangeShareConfigListenerPrivate ExchangeShareConfigListenerPrivate;
+typedef struct _ExchangeShareConfigListenerClass ExchangeShareConfigListenerClass;
+
+struct _ExchangeShareConfigListener {
+ EAccountList parent;
+
+ ExchangeShareConfigListenerPrivate *priv;
+};
+
+struct _ExchangeShareConfigListenerClass {
+ EAccountListClass parent_class;
+
+ /* signals */
+ void (*exchange_account_created) (ExchangeShareConfigListener *,
+ ExchangeAccount *);
+ void (*exchange_account_removed) (ExchangeShareConfigListener *,
+ ExchangeAccount *);
+};
+
+#if 0
+typedef enum {
+ EXCHANGE_CALENDAR_FOLDER,
+ EXCHANGE_TASKS_FOLDER,
+ EXCHANGE_CONTACTS_FOLDER
+}FolderType;
+#endif
+
+#define CONF_KEY_CAL "/apps/evolution/calendar/sources"
+#define CONF_KEY_TASKS "/apps/evolution/tasks/sources"
+#define CONF_KEY_CONTACTS "/apps/evolution/addressbook/sources"
+#define EXCHANGE_URI_PREFIX "exchange://"
+
+GType exchange_share_config_listener_get_type (void);
+ExchangeShareConfigListener *exchange_share_config_listener_new (void);
+ExchangeShareConfigListener *exchange_share_config_listener_get_global (void);
+
+GSList *exchange_share_config_listener_get_accounts (ExchangeShareConfigListener *config_listener);
+
+void exchange_share_config_listener_migrate_esources (ExchangeShareConfigListener *config_listener);
+
+/*void add_folder_esource (ExchangeAccount *account, FolderType folder_type, const gchar *folder_name, const gchar *physical_uri);
+void remove_folder_esource (ExchangeAccount *account, FolderType folder_type, const gchar *physical_uri);*/
+
+ExchangeAccount *exchange_share_config_listener_get_account_for_uri (ExchangeShareConfigListener *excl, const gchar *uri);
+
+G_END_DECLS
+
+#endif /* __EXCHANGE_SHARE_CONFIG_LISTENER_H__ */
diff --git a/storage/migr-test.c b/tools/migr-test.c
similarity index 100%
rename from storage/migr-test.c
rename to tools/migr-test.c
diff --git a/storage/ximian-connector-setup.c b/tools/ximian-connector-setup.c
similarity index 100%
rename from storage/ximian-connector-setup.c
rename to tools/ximian-connector-setup.c
diff --git a/storage/ximian-connector.xml b/tools/ximian-connector.xml
similarity index 100%
rename from storage/ximian-connector.xml
rename to tools/ximian-connector.xml
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]