evolution-data-server r9266 - in trunk/camel: . providers providers/imap
- From: pchen svn gnome org
- To: svn-commits-list gnome org
- Subject: evolution-data-server r9266 - in trunk/camel: . providers providers/imap
- Date: Tue, 5 Aug 2008 08:42:36 +0000 (UTC)
Author: pchen
Date: Tue Aug 5 08:42:35 2008
New Revision: 9266
URL: http://svn.gnome.org/viewvc/evolution-data-server?rev=9266&view=rev
Log:
2008-08-05 Chenthill Palanisamy <pchenthill novell com>
Fixes part of #533823
* camel-offline-store.c:
* (camel_offline_store_get_network_state),
(camel_offline_store_set_network_state): set the network state
to online before calling camel_service_connect as the providers
depend on that.
* camel-offline-store.h:
* providers/Makefile.am: Disco->Offline migration code.
Added:
trunk/camel/providers/imap/camel-imap-journal.c
trunk/camel/providers/imap/camel-imap-journal.h
Modified:
trunk/camel/ChangeLog
trunk/camel/camel-offline-store.c
trunk/camel/camel-offline-store.h
trunk/camel/providers/Makefile.am
trunk/camel/providers/imap/ChangeLog
trunk/camel/providers/imap/Makefile.am
trunk/camel/providers/imap/camel-imap-command.c
trunk/camel/providers/imap/camel-imap-folder.c
trunk/camel/providers/imap/camel-imap-folder.h
trunk/camel/providers/imap/camel-imap-store.c
trunk/camel/providers/imap/camel-imap-store.h
Modified: trunk/camel/camel-offline-store.c
==============================================================================
--- trunk/camel/camel-offline-store.c (original)
+++ trunk/camel/camel-offline-store.c Tue Aug 5 08:42:35 2008
@@ -102,6 +102,19 @@
CAMEL_OFFLINE_STORE_NETWORK_AVAIL : CAMEL_OFFLINE_STORE_NETWORK_UNAVAIL;
}
+/**
+ * camel_offline_store_get_network_state:
+ * @store: a #CamelOfflineStore object
+ * @ex: a #CamelException
+ *
+ * Return the network state either #CAMEL_OFFLINE_STORE_NETWORK_AVAIL
+ * or #CAMEL_OFFLINE_STORE_NETWORK_UNAVAIL.
+ **/
+int
+camel_offline_store_get_network_state (CamelOfflineStore *store, CamelException *ex)
+{
+ return store->state;
+}
/**
* camel_offline_store_set_network_state:
@@ -156,9 +169,12 @@
if (!camel_service_disconnect (CAMEL_SERVICE (store), network_state, ex))
return;
} else {
+ store->state = state;
/* network unavailable -> network available */
- if (!camel_service_connect (CAMEL_SERVICE (store), ex))
+ if (!camel_service_connect (CAMEL_SERVICE (store), ex)) {
+ store->state = CAMEL_OFFLINE_STORE_NETWORK_UNAVAIL;
return;
+ }
}
store->state = state;
Modified: trunk/camel/camel-offline-store.h
==============================================================================
--- trunk/camel/camel-offline-store.h (original)
+++ trunk/camel/camel-offline-store.h Tue Aug 5 08:42:35 2008
@@ -64,6 +64,7 @@
void camel_offline_store_set_network_state (CamelOfflineStore *store, int state, CamelException *ex);
+int camel_offline_store_get_network_state (CamelOfflineStore *store, CamelException *ex);
void camel_offline_store_prepare_for_offline (CamelOfflineStore *store, CamelException *ex);
Modified: trunk/camel/providers/Makefile.am
==============================================================================
--- trunk/camel/providers/Makefile.am (original)
+++ trunk/camel/providers/Makefile.am Tue Aug 5 08:42:35 2008
@@ -4,10 +4,6 @@
NNTP_DIR=nntp
endif
-if ENABLE_HULA
-HULA_DIR=hula
-endif
-
if ENABLE_IMAPP
IMAPP_DIR=imapp
endif
Modified: trunk/camel/providers/imap/Makefile.am
==============================================================================
--- trunk/camel/providers/imap/Makefile.am (original)
+++ trunk/camel/providers/imap/Makefile.am Tue Aug 5 08:42:35 2008
@@ -23,6 +23,7 @@
camel-imap-store.c \
camel-imap-store-summary.c \
camel-imap-summary.c \
+ camel-imap-journal.c \
camel-imap-utils.c \
camel-imap-wrapper.c
@@ -34,6 +35,7 @@
camel-imap-store.h \
camel-imap-store-summary.h \
camel-imap-summary.h \
+ camel-imap-journal.h \
camel-imap-types.h \
camel-imap-utils.h \
camel-imap-wrapper.h \
Modified: trunk/camel/providers/imap/camel-imap-command.c
==============================================================================
--- trunk/camel/providers/imap/camel-imap-command.c (original)
+++ trunk/camel/providers/imap/camel-imap-command.c Tue Aug 5 08:42:35 2008
@@ -389,10 +389,10 @@
CAMEL_SERVICE_REC_LOCK (store, connect_lock);
response = g_new0 (CamelImapResponse, 1);
- if (store->current_folder && camel_disco_store_status (CAMEL_DISCO_STORE (store)) != CAMEL_DISCO_STORE_RESYNCING) {
+/*FIXME if (store->current_folder && camel_disco_store_status (CAMEL_DISCO_STORE (store)) != CAMEL_DISCO_STORE_RESYNCING) {
response->folder = store->current_folder;
camel_object_ref (CAMEL_OBJECT (response->folder));
- }
+ } */
response->untagged = g_ptr_array_new ();
while ((type = camel_imap_command_response (store, &respbuf, ex))
Modified: trunk/camel/providers/imap/camel-imap-folder.c
==============================================================================
--- trunk/camel/providers/imap/camel-imap-folder.c (original)
+++ trunk/camel/providers/imap/camel-imap-folder.c Tue Aug 5 08:42:35 2008
@@ -41,7 +41,7 @@
#include "camel-data-wrapper.h"
#include "camel-debug.h"
-#include "camel-disco-diary.h"
+#include "camel-imap-journal.h"
#include "camel-exception.h"
#include "camel-file-utils.h"
#include "camel-mime-filter-crlf.h"
@@ -82,7 +82,7 @@
#define CF_CLASS(o) (CAMEL_FOLDER_CLASS (CAMEL_OBJECT_GET_CLASS(o)))
-static CamelDiscoFolderClass *disco_folder_class = NULL;
+static CamelOfflineFolderClass *offline_folder_class = NULL;
static CamelProperty imap_property_list[] = {
{ CAMEL_IMAP_FOLDER_CHECK_FOLDER, "check_folder", N_("Always check for new mail in this folder") },
@@ -94,12 +94,12 @@
static void imap_rescan (CamelFolder *folder, int exists, CamelException *ex);
static void imap_refresh_info (CamelFolder *folder, CamelException *ex);
-static void imap_sync_online (CamelFolder *folder, CamelException *ex);
static void imap_sync_offline (CamelFolder *folder, CamelException *ex);
+static void imap_sync (CamelFolder *folder, gboolean expunge, CamelException *ex);
static void imap_expunge_uids_online (CamelFolder *folder, GPtrArray *uids, CamelException *ex);
static void imap_expunge_uids_offline (CamelFolder *folder, GPtrArray *uids, CamelException *ex);
-static void imap_expunge_uids_resyncing (CamelFolder *folder, GPtrArray *uids, CamelException *ex);
-static void imap_cache_message (CamelDiscoFolder *disco_folder, const char *uid, CamelException *ex);
+static void imap_expunge (CamelFolder *folder, CamelException *ex);
+//static void imap_cache_message (CamelDiscoFolder *disco_folder, const char *uid, CamelException *ex);
static void imap_rename (CamelFolder *folder, const char *new);
/* message manipulation */
@@ -111,9 +111,6 @@
static void imap_append_offline (CamelFolder *folder, CamelMimeMessage *message,
const CamelMessageInfo *info, char **appended_uid,
CamelException *ex);
-static void imap_append_resyncing (CamelFolder *folder, CamelMimeMessage *message,
- const CamelMessageInfo *info, char **appended_uid,
- CamelException *ex);
static void imap_transfer_online (CamelFolder *source, GPtrArray *uids,
CamelFolder *dest, GPtrArray **transferred_uids,
@@ -123,10 +120,6 @@
CamelFolder *dest, GPtrArray **transferred_uids,
gboolean delete_originals,
CamelException *ex);
-static void imap_transfer_resyncing (CamelFolder *source, GPtrArray *uids,
- CamelFolder *dest, GPtrArray **transferred_uids,
- gboolean delete_originals,
- CamelException *ex);
/* searching */
static GPtrArray *imap_search_by_expression (CamelFolder *folder, const char *expression, CamelException *ex);
@@ -152,9 +145,8 @@
camel_imap_folder_class_init (CamelImapFolderClass *camel_imap_folder_class)
{
CamelFolderClass *camel_folder_class = CAMEL_FOLDER_CLASS (camel_imap_folder_class);
- CamelDiscoFolderClass *camel_disco_folder_class = CAMEL_DISCO_FOLDER_CLASS (camel_imap_folder_class);
- disco_folder_class = CAMEL_DISCO_FOLDER_CLASS (camel_type_get_global_classfuncs (camel_disco_folder_get_type ()));
+ offline_folder_class = CAMEL_OFFLINE_FOLDER_CLASS (camel_type_get_global_classfuncs (camel_offline_folder_get_type ()));
/* virtual method overload */
((CamelObjectClass *)camel_imap_folder_class)->getv = imap_getv;
@@ -167,24 +159,11 @@
camel_folder_class->search_free = imap_search_free;
camel_folder_class->thaw = imap_thaw;
camel_folder_class->get_quota_info = imap_get_quota_info;
-
- camel_disco_folder_class->refresh_info_online = imap_refresh_info;
- camel_disco_folder_class->sync_online = imap_sync_online;
- camel_disco_folder_class->sync_offline = imap_sync_offline;
- /* We don't sync flags at resync time: the online code will
- * deal with it eventually.
- */
- camel_disco_folder_class->sync_resyncing = imap_sync_offline;
- camel_disco_folder_class->expunge_uids_online = imap_expunge_uids_online;
- camel_disco_folder_class->expunge_uids_offline = imap_expunge_uids_offline;
- camel_disco_folder_class->expunge_uids_resyncing = imap_expunge_uids_resyncing;
- camel_disco_folder_class->append_online = imap_append_online;
- camel_disco_folder_class->append_offline = imap_append_offline;
- camel_disco_folder_class->append_resyncing = imap_append_resyncing;
- camel_disco_folder_class->transfer_online = imap_transfer_online;
- camel_disco_folder_class->transfer_offline = imap_transfer_offline;
- camel_disco_folder_class->transfer_resyncing = imap_transfer_resyncing;
- camel_disco_folder_class->cache_message = imap_cache_message;
+ camel_folder_class->refresh_info = imap_refresh_info;
+ camel_folder_class->expunge = imap_expunge;
+ camel_folder_class->sync= imap_sync;
+ camel_folder_class->append_message = imap_append_online;
+ camel_folder_class->transfer_messages_to = imap_transfer_online;
}
static void
@@ -205,6 +184,7 @@
g_static_rec_mutex_init(&imap_folder->priv->cache_lock);
#endif
+ imap_folder->journal = NULL;
imap_folder->need_rescan = TRUE;
}
@@ -216,7 +196,7 @@
if (camel_imap_folder_type == CAMEL_INVALID_TYPE) {
int i;
- parent_class = camel_disco_folder_get_type();
+ parent_class = camel_offline_folder_get_type();
camel_imap_folder_type =
camel_type_register (parent_class, "CamelImapFolder",
sizeof (CamelImapFolder),
@@ -242,7 +222,7 @@
CamelFolder *folder;
CamelImapFolder *imap_folder;
const char *short_name;
- char *summary_file, *state_file;
+ char *summary_file, *state_file, *path;
if (g_mkdir_with_parents (folder_dir, S_IRWXU) != 0) {
camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM,
@@ -270,13 +250,17 @@
return NULL;
}
+ imap_folder = CAMEL_IMAP_FOLDER (folder);
+ path = g_strdup_printf ("%s/journal", folder_dir);
+ imap_folder->journal = camel_imap_journal_new (imap_folder, path);
+ g_free (path);
+
/* set/load persistent state */
state_file = g_strdup_printf ("%s/cmeta", folder_dir);
camel_object_set(folder, NULL, CAMEL_OBJECT_STATE_FILE, state_file, NULL);
g_free(state_file);
camel_object_state_read(folder);
- imap_folder = CAMEL_IMAP_FOLDER (folder);
imap_folder->cache = camel_imap_message_cache_new (folder_dir, folder->summary, ex);
if (!imap_folder->cache) {
camel_object_unref (CAMEL_OBJECT (folder));
@@ -294,6 +278,9 @@
}
imap_folder->search = camel_imap_search_new(folder_dir);
+ camel_offline_journal_replay (imap_folder->journal, ex);
+ camel_imap_journal_close_folders ((CamelIMAPJournal *)imap_folder->journal);
+ camel_offline_journal_write (CAMEL_IMAP_FOLDER (folder)->journal, ex);
return folder;
}
@@ -346,16 +333,17 @@
if (camel_strstrcase (response->status, "OK [READ-ONLY]"))
imap_folder->read_only = TRUE;
- if (camel_disco_store_status (CAMEL_DISCO_STORE (folder->parent_store)) == CAMEL_DISCO_STORE_RESYNCING) {
+/*FIXME what to do here.
+ if (camel_disco_store_status (CAMEL_DISCO_STORE (folder->parent_store)) == CAMEL_DISCO_STORE_RESYNCING) {
if (validity != imap_summary->validity) {
camel_exception_setv (ex, CAMEL_EXCEPTION_FOLDER_SUMMARY_INVALID,
_("Folder was destroyed and recreated on server."));
return;
}
- /* FIXME: find missing UIDs ? */
+ FIXME: find missing UIDs ?
return;
- }
+ } */
if (!imap_summary->validity)
imap_summary->validity = validity;
@@ -445,6 +433,12 @@
g_static_mutex_free(&imap_folder->priv->search_lock);
g_static_rec_mutex_free(&imap_folder->priv->cache_lock);
#endif
+
+ if (imap_folder->journal) {
+ camel_offline_journal_write (imap_folder->journal, NULL);
+ camel_object_unref (imap_folder->journal);
+ }
+
g_free(imap_folder->priv);
}
@@ -559,7 +553,7 @@
g_free(summary_path);
g_free(folder_dir);
- ((CamelFolderClass *)disco_folder_class)->rename(folder, new);
+ ((CamelFolderClass *)offline_folder_class)->rename(folder, new);
}
/* called with connect_lock locked */
@@ -644,7 +638,7 @@
int check_rescan = -1;
extern int camel_application_is_exiting;
- if (camel_disco_store_status (CAMEL_DISCO_STORE (imap_store)) == CAMEL_DISCO_STORE_OFFLINE)
+ if (CAMEL_OFFLINE_STORE (imap_store)->state == CAMEL_OFFLINE_STORE_NETWORK_UNAVAIL)
return;
if (camel_folder_is_frozen (folder)) {
@@ -706,7 +700,7 @@
if (check_rescan && !camel_application_is_exiting && !camel_exception_is_set (ex)) {
if (check_rescan == -1) {
- guint32 total, unread, server_total=0, server_unread=0;
+ guint32 total, unread = 0, server_total = 0, server_unread = 0;
check_rescan = 0;
@@ -726,8 +720,12 @@
done:
CAMEL_SERVICE_REC_UNLOCK (imap_store, connect_lock);
+ camel_offline_journal_replay (CAMEL_IMAP_FOLDER (folder)->journal, ex);
+ camel_imap_journal_close_folders ((CamelIMAPJournal *) CAMEL_IMAP_FOLDER (folder)->journal);
+ camel_offline_journal_write (CAMEL_IMAP_FOLDER (folder)->journal, ex);
+
camel_folder_summary_save_to_db (folder->summary, ex);
- camel_store_summary_save((CamelStoreSummary *)((CamelImapStore *)folder->parent_store)->summary);
+ camel_store_summary_save ((CamelStoreSummary *)((CamelImapStore *)folder->parent_store)->summary);
}
static void
@@ -1276,7 +1274,7 @@
}
static void
-imap_sync_online (CamelFolder *folder, CamelException *ex)
+imap_sync (CamelFolder *folder, gboolean expunge, CamelException *ex)
{
CamelImapStore *store = CAMEL_IMAP_STORE (folder->parent_store);
CamelImapMessageInfo *info;
@@ -1286,7 +1284,12 @@
char *set, *flaglist, *uid;
int i, j, max;
- if (folder->permanent_flags == 0) {
+ if (folder->permanent_flags == 0 || CAMEL_OFFLINE_STORE (store)->state == CAMEL_OFFLINE_STORE_NETWORK_UNAVAIL) {
+ if (expunge) {
+ imap_expunge (folder, ex);
+ if (camel_exception_is_set (ex))
+ return;
+ }
imap_sync_offline (folder, ex);
return;
}
@@ -1402,6 +1405,13 @@
CAMEL_SERVICE_REC_LOCK (store, connect_lock);
}
+ if (expunge)
+ imap_expunge (folder, ex);
+
+ camel_offline_journal_replay (CAMEL_IMAP_FOLDER (folder)->journal, ex);
+ camel_imap_journal_close_folders ((CamelIMAPJournal *) CAMEL_IMAP_FOLDER (folder)->journal);
+ camel_offline_journal_write (CAMEL_IMAP_FOLDER (folder)->journal, ex);
+
g_ptr_array_foreach (summary, (GFunc) camel_pstring_free, NULL);
g_ptr_array_free (summary, TRUE);
@@ -1446,8 +1456,8 @@
}
camel_folder_summary_save_to_db (folder->summary, ex);
- camel_disco_diary_log (CAMEL_DISCO_STORE (folder->parent_store)->diary,
- CAMEL_DISCO_DIARY_FOLDER_EXPUNGE, folder, uids);
+ camel_imap_journal_log (CAMEL_IMAP_FOLDER (folder)->journal,
+ CAMEL_IMAP_JOURNAL_ENTRY_EXPUNGE, uids);
camel_object_trigger_event (CAMEL_OBJECT (folder), "folder_changed", changes);
camel_folder_change_info_free (changes);
@@ -1517,6 +1527,33 @@
}
static void
+imap_expunge (CamelFolder *folder, CamelException *ex)
+{
+ CamelImapStore *store = CAMEL_IMAP_STORE (folder->parent_store);
+ GPtrArray *uids;
+ int i, count;
+ CamelMessageInfo *info;
+
+ uids = g_ptr_array_new ();
+ count = camel_folder_summary_count (folder->summary);
+ for (i = 0; i < count; i++) {
+ info = camel_folder_summary_index (folder->summary, i);
+ if (camel_message_info_flags(info) & CAMEL_MESSAGE_DELETED)
+ g_ptr_array_add (uids, g_strdup (camel_message_info_uid (info)));
+ camel_message_info_free(info);
+ }
+
+ if (CAMEL_OFFLINE_STORE (store)->state == CAMEL_OFFLINE_STORE_NETWORK_AVAIL)
+ imap_expunge_uids_online (folder, uids, ex);
+ else
+ imap_expunge_uids_offline (folder, uids, ex);
+
+ for (i = 0; i < uids->len; i++)
+ g_free (uids->pdata[i]);
+ g_ptr_array_free (uids, TRUE);
+}
+
+void
imap_expunge_uids_resyncing (CamelFolder *folder, GPtrArray *uids, CamelException *ex)
{
CamelImapFolder *imap_folder = CAMEL_IMAP_FOLDER (folder);
@@ -1704,7 +1741,6 @@
const CamelMessageInfo *info, char **appended_uid,
CamelException *ex)
{
- CamelImapStore *imap_store = CAMEL_IMAP_STORE (folder->parent_store);
CamelImapMessageCache *cache = CAMEL_IMAP_FOLDER (folder)->cache;
CamelFolderChangeInfo *changes;
char *uid;
@@ -1723,8 +1759,8 @@
changes);
camel_folder_change_info_free (changes);
- camel_disco_diary_log (CAMEL_DISCO_STORE (imap_store)->diary,
- CAMEL_DISCO_DIARY_FOLDER_APPEND, folder, uid);
+ camel_imap_journal_log (CAMEL_IMAP_FOLDER (folder)->journal,
+ CAMEL_IMAP_JOURNAL_ENTRY_APPEND, uid);
if (appended_uid)
*appended_uid = uid;
else
@@ -1841,6 +1877,11 @@
char *uid;
int count;
+ if (CAMEL_OFFLINE_STORE (store)->state == CAMEL_OFFLINE_STORE_NETWORK_UNAVAIL) {
+ imap_append_offline (folder, message, info, appended_uid, ex);
+ return;
+ }
+
count = camel_folder_summary_count (folder->summary);
response = do_append (folder, message, info, &uid, ex);
if (!response) {
@@ -1875,7 +1916,7 @@
CAMEL_SERVICE_REC_UNLOCK (store, connect_lock);
}
-static void
+void
imap_append_resyncing (CamelFolder *folder, CamelMimeMessage *message,
const CamelMessageInfo *info, char **appended_uid,
CamelException *ex)
@@ -1883,7 +1924,7 @@
CamelImapStore *store = CAMEL_IMAP_STORE (folder->parent_store);
CamelImapResponse *response;
char *uid;
-
+
response = do_append (folder, message, info, &uid, ex);
if (!response)
return;
@@ -1973,10 +2014,9 @@
camel_object_trigger_event (CAMEL_OBJECT (dest), "folder_changed", changes);
camel_folder_change_info_free (changes);
-
- camel_disco_diary_log (CAMEL_DISCO_STORE (store)->diary,
- CAMEL_DISCO_DIARY_FOLDER_TRANSFER,
- source, dest, uids, delete_originals);
+
+ camel_imap_journal_log (CAMEL_IMAP_FOLDER (source)->journal, CAMEL_IMAP_JOURNAL_ENTRY_TRANSFER, dest,
+ uids, delete_originals, ex);
}
static void
@@ -2189,8 +2229,13 @@
CamelImapStore *store = CAMEL_IMAP_STORE (source->parent_store);
int count;
+ if (CAMEL_OFFLINE_STORE (store)->state == CAMEL_OFFLINE_STORE_NETWORK_UNAVAIL) {
+ imap_transfer_offline (source, uids, dest, transferred_uids, delete_originals, ex);
+ return;
+ }
+
/* Sync message flags if needed. */
- imap_sync_online (source, ex);
+ imap_sync (source, FALSE, ex);
if (camel_exception_is_set (ex))
return;
@@ -2213,12 +2258,11 @@
*transferred_uids = NULL;
}
-static void
+void
imap_transfer_resyncing (CamelFolder *source, GPtrArray *uids,
CamelFolder *dest, GPtrArray **transferred_uids,
gboolean delete_originals, CamelException *ex)
{
- CamelDiscoDiary *diary = CAMEL_DISCO_STORE (source->parent_store)->diary;
GPtrArray *realuids;
int first, i;
const char *uid;
@@ -2227,23 +2271,23 @@
qsort (uids->pdata, uids->len, sizeof (void *), uid_compar);
- /* This is trickier than append_resyncing, because some of
+ /*This is trickier than append_resyncing, because some of
* the messages we are copying may have been copied or
* appended into @source while we were offline, in which case
* if we don't have UIDPLUS, we won't know their real UIDs,
- * so we'll have to append them rather than copying.
- */
+ * so we'll have to append them rather than copying. */
+
realuids = g_ptr_array_new ();
i = 0;
while (i < uids->len && !camel_exception_is_set (ex)) {
- /* Skip past real UIDs */
+ /* Skip past real UIDs */
for (first = i; i < uids->len; i++) {
uid = uids->pdata[i];
if (!isdigit ((unsigned char)*uid)) {
- uid = camel_disco_diary_uidmap_lookup (diary, uid);
+ uid = camel_imap_journal_uidmap_lookup ((CamelIMAPJournal *) CAMEL_IMAP_FOLDER (source)->journal, uid);
if (!uid)
break;
}
@@ -2285,7 +2329,7 @@
/* FIXME */
if (transferred_uids)
*transferred_uids = NULL;
-}
+}
static GPtrArray *
imap_search_by_expression (CamelFolder *folder, const char *expression, CamelException *ex)
@@ -2801,6 +2845,7 @@
return msg;
}
+/* FIXME Remove it after confirming
static void
imap_cache_message (CamelDiscoFolder *disco_folder, const char *uid,
CamelException *ex)
@@ -2812,6 +2857,7 @@
if (stream)
camel_object_unref (CAMEL_OBJECT (stream));
}
+*/
/* We pretend that a FLAGS or RFC822.SIZE response is always exactly
* 20 bytes long, and a BODY[HEADERS] response is always 2000 bytes
@@ -3430,7 +3476,7 @@
{
CamelImapFolder *imap_folder;
- CAMEL_FOLDER_CLASS (disco_folder_class)->thaw (folder);
+ CAMEL_FOLDER_CLASS (offline_folder_class)->thaw (folder);
if (camel_folder_is_frozen (folder))
return;
@@ -3688,7 +3734,7 @@
CamelImapResponse *response;
CamelFolderQuotaInfo *res = NULL, *last = NULL;
- if (camel_disco_store_status (CAMEL_DISCO_STORE (imap_store)) == CAMEL_DISCO_STORE_OFFLINE)
+ if (CAMEL_OFFLINE_STORE (imap_store)->state == CAMEL_OFFLINE_STORE_NETWORK_UNAVAIL)
return NULL;
CAMEL_SERVICE_REC_LOCK (imap_store, connect_lock);
Modified: trunk/camel/providers/imap/camel-imap-folder.h
==============================================================================
--- trunk/camel/providers/imap/camel-imap-folder.h (original)
+++ trunk/camel/providers/imap/camel-imap-folder.h Tue Aug 5 08:42:35 2008
@@ -28,8 +28,9 @@
#define CAMEL_IMAP_FOLDER_H 1
#include "camel-imap-types.h"
-#include <camel/camel-disco-folder.h>
+#include <camel/camel-offline-folder.h>
#include <camel/camel-folder-search.h>
+#include <camel/camel-offline-journal.h>
#define CAMEL_IMAP_FOLDER_TYPE (camel_imap_folder_get_type ())
#define CAMEL_IMAP_FOLDER(obj) (CAMEL_CHECK_CAST((obj), CAMEL_IMAP_FOLDER_TYPE, CamelImapFolder))
@@ -38,9 +39,11 @@
G_BEGIN_DECLS
+struct _CamelIMAP4Journal;
+
enum {
- CAMEL_IMAP_FOLDER_ARG_CHECK_FOLDER = CAMEL_DISCO_FOLDER_ARG_LAST,
- CAMEL_IMAP_FOLDER_ARG_LAST = CAMEL_DISCO_FOLDER_ARG_LAST + 0x100
+ CAMEL_IMAP_FOLDER_ARG_CHECK_FOLDER = CAMEL_OFFLINE_FOLDER_ARG_LAST,
+ CAMEL_IMAP_FOLDER_ARG_LAST = CAMEL_OFFLINE_FOLDER_ARG_LAST + 0x100
};
enum {
@@ -51,12 +54,13 @@
typedef struct _CamelImapFolderPrivate CamelImapFolderPrivate;
struct _CamelImapFolder {
- CamelDiscoFolder parent_object;
+ CamelOfflineFolder parent_object;
CamelImapFolderPrivate *priv;
CamelFolderSearch *search;
CamelImapMessageCache *cache;
+ CamelOfflineJournal *journal;
unsigned int need_rescan:1;
unsigned int need_refresh:1;
@@ -65,7 +69,7 @@
};
struct _CamelImapFolderClass {
- CamelDiscoFolderClass parent_class;
+ CamelOfflineFolderClass parent_class;
/* Virtual methods */
@@ -90,6 +94,16 @@
const char *section_text,
gboolean cache_only,
CamelException *ex);
+void
+imap_append_resyncing (CamelFolder *folder, CamelMimeMessage *message,
+ const CamelMessageInfo *info, char **appended_uid,
+ CamelException *ex);
+void
+imap_transfer_resyncing (CamelFolder *source, GPtrArray *uids,
+ CamelFolder *dest, GPtrArray **transferred_uids,
+ gboolean delete_originals, CamelException *ex);
+void
+imap_expunge_uids_resyncing (CamelFolder *folder, GPtrArray *uids, CamelException *ex);
/* Standard Camel function */
CamelType camel_imap_folder_get_type (void);
Added: trunk/camel/providers/imap/camel-imap-journal.c
==============================================================================
--- (empty file)
+++ trunk/camel/providers/imap/camel-imap-journal.c Tue Aug 5 08:42:35 2008
@@ -0,0 +1,474 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+/*
+ * Authors :
+ * Chenthill Palanisamy <pchenthill novell com>
+ *
+ * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of version 2 of the GNU Lesser General Public
+ * License as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <stdio.h>
+#include <string.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <ctype.h>
+
+#include <glib/gi18n-lib.h>
+
+#include <camel/camel-folder-summary.h>
+#include <camel/camel-data-cache.h>
+#include <camel/camel-file-utils.h>
+#include <camel/camel-folder.h>
+#include <camel/camel-store.h>
+#include <camel/camel-session.h>
+
+#include "camel-imap-journal.h"
+#include "camel-imap-folder.h"
+
+#define d(x) x
+
+static void camel_imap_journal_class_init (CamelIMAPJournalClass *klass);
+static void camel_imap_journal_init (CamelIMAPJournal *journal, CamelIMAPJournalClass *klass);
+static void camel_imap_journal_finalize (CamelObject *object);
+
+static void imap_entry_free (CamelOfflineJournal *journal, EDListNode *entry);
+static EDListNode *imap_entry_load (CamelOfflineJournal *journal, FILE *in);
+static int imap_entry_write (CamelOfflineJournal *journal, EDListNode *entry, FILE *out);
+static int imap_entry_play (CamelOfflineJournal *journal, EDListNode *entry, CamelException *ex);
+static void unref_folder (gpointer key, gpointer value, gpointer data);
+static void free_uids (GPtrArray *array);
+static void close_folder (gpointer name, gpointer folder, gpointer data);
+
+static CamelOfflineJournalClass *parent_class = NULL;
+
+
+CamelType
+camel_imap_journal_get_type (void)
+{
+ static CamelType type = 0;
+
+ if (!type) {
+ type = camel_type_register (camel_offline_journal_get_type (),
+ "CamelIMAPJournal",
+ sizeof (CamelIMAPJournal),
+ sizeof (CamelIMAPJournalClass),
+ (CamelObjectClassInitFunc) camel_imap_journal_class_init,
+ NULL,
+ (CamelObjectInitFunc) camel_imap_journal_init,
+ (CamelObjectFinalizeFunc) camel_imap_journal_finalize);
+ }
+
+ return type;
+}
+
+static void
+camel_imap_journal_class_init (CamelIMAPJournalClass *klass)
+{
+ CamelOfflineJournalClass *journal_class = (CamelOfflineJournalClass *) klass;
+
+ parent_class = (CamelOfflineJournalClass *) camel_type_get_global_classfuncs (CAMEL_TYPE_OFFLINE_JOURNAL);
+
+ journal_class->entry_free = imap_entry_free;
+ journal_class->entry_load = imap_entry_load;
+ journal_class->entry_write = imap_entry_write;
+ journal_class->entry_play = imap_entry_play;
+}
+
+static void
+camel_imap_journal_init (CamelIMAPJournal *journal, CamelIMAPJournalClass *klass)
+{
+ journal->folders = g_hash_table_new (g_str_hash, g_str_equal);
+ journal->uidmap = g_hash_table_new (g_str_hash, g_str_equal);
+}
+
+static void
+free_uid (gpointer key, gpointer value, gpointer data)
+{
+ g_free (key);
+ g_free (value);
+}
+
+static void
+camel_imap_journal_finalize (CamelObject *object)
+{
+ CamelIMAPJournal *journal = (CamelIMAPJournal *) object;
+
+ if (journal->folders) {
+ g_hash_table_foreach (journal->folders, unref_folder, NULL);
+ g_hash_table_destroy (journal->folders);
+ journal->folders = NULL;
+ }
+ if (journal->uidmap) {
+ g_hash_table_foreach (journal->uidmap, free_uid, NULL);
+ g_hash_table_destroy (journal->uidmap);
+ }
+}
+
+static void
+unref_folder (gpointer key, gpointer value, gpointer data)
+{
+ camel_object_unref (value);
+}
+
+static void
+imap_entry_free (CamelOfflineJournal *journal, EDListNode *entry)
+{
+ CamelIMAPJournalEntry *imap_entry = (CamelIMAPJournalEntry *) entry;
+
+ switch (imap_entry->type) {
+ case CAMEL_IMAP_JOURNAL_ENTRY_EXPUNGE:
+ free_uids (imap_entry->uids);
+ break;
+ case CAMEL_IMAP_JOURNAL_ENTRY_APPEND:
+ g_free (imap_entry->append_uid);
+ break;
+ case CAMEL_IMAP_JOURNAL_ENTRY_TRANSFER:
+ free_uids (imap_entry->uids);
+ g_free (imap_entry->dest_folder_name);
+ break;
+ }
+ g_free (imap_entry);
+}
+
+static void
+free_uids (GPtrArray *array)
+{
+ while (array->len--)
+ g_free (array->pdata[array->len]);
+ g_ptr_array_free (array, TRUE);
+}
+
+static GPtrArray *
+decode_uids (FILE *file)
+{
+ GPtrArray *uids;
+ char *uid;
+ guint32 i;
+
+ if (camel_file_util_decode_uint32 (file, &i) == -1)
+ return NULL;
+ uids = g_ptr_array_new ();
+ while (i--) {
+ if (camel_file_util_decode_string (file, &uid) == -1) {
+ free_uids (uids);
+ return NULL;
+ }
+ g_ptr_array_add (uids, uid);
+ }
+
+ return uids;
+}
+
+static EDListNode *
+imap_entry_load (CamelOfflineJournal *journal, FILE *in)
+{
+ CamelIMAPJournalEntry *entry;
+
+
+ d(g_print ("CHEN DEBUG: Loading to the journal \n"));
+
+ entry = g_malloc0 (sizeof (CamelIMAPJournalEntry));
+
+ if (camel_file_util_decode_uint32 (in, &entry->type) == -1)
+ goto exception;
+
+ switch (entry->type) {
+ case CAMEL_IMAP_JOURNAL_ENTRY_EXPUNGE:
+ entry->uids = decode_uids (in);
+ if (!entry->uids)
+ goto exception;
+ case CAMEL_IMAP_JOURNAL_ENTRY_APPEND:
+ if (camel_file_util_decode_string (in, &entry->append_uid) == -1)
+ goto exception;
+
+ break;
+ case CAMEL_IMAP_JOURNAL_ENTRY_TRANSFER:
+ if (camel_file_util_decode_string (in, &entry->dest_folder_name) == -1)
+ goto exception;
+ entry->uids = decode_uids (in);
+ if (!entry->uids)
+ goto exception;
+ if (camel_file_util_decode_uint32 (in, &entry->move) == -1)
+ goto exception;
+ break;
+ default:
+ goto exception;
+ }
+
+ d(g_print ("CHEN DEBUG: Atlast got one entry \n"));
+ return (EDListNode *) entry;
+
+ exception:
+ switch (entry->type) {
+ case CAMEL_IMAP_JOURNAL_ENTRY_APPEND:
+ g_free (entry->append_uid);
+ break;
+ default:
+ break;
+ }
+
+ g_free (entry);
+
+ return NULL;
+}
+
+static int
+encode_uids (FILE *file, GPtrArray *uids)
+{
+ int i, status;
+
+ status = camel_file_util_encode_uint32 (file, uids->len);
+ for (i = 0; status != -1 && i < uids->len; i++)
+ status = camel_file_util_encode_string (file, uids->pdata[i]);
+ return status;
+}
+
+static int
+imap_entry_write (CamelOfflineJournal *journal, EDListNode *entry, FILE *out)
+{
+ CamelIMAPJournalEntry *imap_entry = (CamelIMAPJournalEntry *) entry;
+ GPtrArray *uids = NULL;
+
+ if (camel_file_util_encode_uint32 (out, imap_entry->type) == -1)
+ return -1;
+
+ d(g_print ("CHEN DEBUG: Writing to the journal \n"));
+ switch (imap_entry->type) {
+ case CAMEL_IMAP_JOURNAL_ENTRY_EXPUNGE:
+ uids = imap_entry->uids;
+
+ if (encode_uids (out, uids))
+ return -1;
+ case CAMEL_IMAP_JOURNAL_ENTRY_APPEND:
+ if (camel_file_util_encode_string (out, imap_entry->append_uid))
+ return -1;
+
+ break;
+ case CAMEL_IMAP_JOURNAL_ENTRY_TRANSFER:
+ if (camel_file_util_encode_string (out, imap_entry->dest_folder_name))
+ return -1;
+ if (encode_uids (out, imap_entry->uids))
+ return -1;
+ if (camel_file_util_encode_uint32 (out, imap_entry->move))
+ return -1;
+ break;
+ default:
+ g_assert_not_reached ();
+ }
+
+ /* FIXME show error message */
+ return 0;
+}
+
+static CamelFolder *
+journal_decode_folder (CamelIMAPJournal *journal, const char *name)
+{
+ CamelFolder *folder;
+
+ folder = g_hash_table_lookup (journal->folders, name);
+ if (!folder) {
+ CamelException ex;
+ char *msg;
+
+ camel_exception_init (&ex);
+ folder = camel_store_get_folder (CAMEL_STORE (CAMEL_OFFLINE_JOURNAL (journal)->folder->parent_store),
+ name, 0, &ex);
+ if (folder)
+ g_hash_table_insert (journal->folders, name, folder);
+ else {
+ msg = g_strdup_printf (_("Could not open '%s':\n%s\nChanges made to this folder will not be resynchronized."),
+ name, camel_exception_get_description (&ex));
+ camel_exception_clear (&ex);
+ camel_session_alert_user (camel_service_get_session (CAMEL_SERVICE (CAMEL_OFFLINE_JOURNAL (journal)->folder->parent_store)),
+ CAMEL_SESSION_ALERT_WARNING,
+ msg, FALSE);
+ g_free (msg);
+ }
+ }
+
+ return folder;
+}
+
+int
+imap_entry_play (CamelOfflineJournal *journal, EDListNode *entry, CamelException *ex)
+{
+ CamelIMAPJournalEntry *imap_entry = (CamelIMAPJournalEntry *) entry;
+
+ d(g_print ("CHEN DEBUG: PLaying to the journal \n"));
+
+ switch (imap_entry->type) {
+ case CAMEL_IMAP_JOURNAL_ENTRY_EXPUNGE:
+ imap_expunge_uids_resyncing (journal->folder, imap_entry->uids, ex);
+ return 0;
+ case CAMEL_IMAP_JOURNAL_ENTRY_APPEND:
+ {
+ char *ret_uid = NULL;
+ CamelMimeMessage *message;
+ CamelMessageInfo *info;
+
+ message = camel_folder_get_message (journal->folder, imap_entry->append_uid, NULL);
+ if (!message)
+ return -1;
+
+ info = camel_folder_get_message_info (journal->folder, imap_entry->append_uid);
+ imap_append_resyncing (journal->folder, message, info, &ret_uid, ex);
+ camel_folder_free_message_info (journal->folder, info);
+
+ if (ret_uid) {
+ camel_imap_journal_uidmap_add ((CamelIMAPJournal *)journal, imap_entry->append_uid, ret_uid);
+ g_free (ret_uid);
+ }
+
+ return 0;
+ }
+ case CAMEL_IMAP_JOURNAL_ENTRY_TRANSFER:
+ {
+ CamelFolder *destination;
+ GPtrArray *ret_uids;
+ int i;
+
+ destination = journal_decode_folder ((CamelIMAPJournal *)journal, imap_entry->dest_folder_name);
+ if (!destination) {
+ d(g_print ("Destination folder not found \n"));
+ return -1;
+ }
+
+ camel_exception_clear (ex);
+ imap_transfer_resyncing (journal->folder, imap_entry->uids, destination, &ret_uids, imap_entry->move, ex);
+
+ if (camel_exception_is_set (ex)) {
+ d(g_print ("Exception set: %s \n", camel_exception_get_description (ex)));
+ return -1;
+ }
+
+ if (ret_uids) {
+ for (i = 0; i < imap_entry->uids->len; i++) {
+ if (!ret_uids->pdata[i])
+ continue;
+ camel_imap_journal_uidmap_add ((CamelIMAPJournal *)journal, imap_entry->uids->pdata[i], ret_uids->pdata[i]);
+ g_free (ret_uids->pdata[i]);
+ }
+ g_ptr_array_free (ret_uids, TRUE);
+ }
+ d(g_print ("Replay success \n"));
+ return 0;
+ }
+ default:
+ g_assert_not_reached ();
+ return -1;
+ }
+}
+
+CamelOfflineJournal *
+camel_imap_journal_new (CamelImapFolder *folder, const char *filename)
+{
+ CamelOfflineJournal *journal;
+
+ g_return_val_if_fail (CAMEL_IS_IMAP_FOLDER (folder), NULL);
+
+ d(g_print ("Creating the journal \n"));
+ journal = (CamelOfflineJournal *) camel_object_new (camel_imap_journal_get_type ());
+ camel_offline_journal_construct (journal, (CamelFolder *) folder, filename);
+
+ return journal;
+}
+
+void
+camel_imap_journal_log (CamelOfflineJournal *journal, CamelOfflineAction action, ...)
+{
+ CamelIMAPJournalEntry *entry;
+ va_list ap;
+
+ if (!journal)
+ return;
+
+ entry = g_new0 (CamelIMAPJournalEntry, 1);
+ entry->type = action;
+
+ d(g_print ("logging the journal \n"));
+
+ va_start (ap, action);
+ switch (entry->type) {
+ case CAMEL_IMAP_JOURNAL_ENTRY_EXPUNGE:
+ {
+ GPtrArray *uids = va_arg (ap, GPtrArray *);
+
+ entry->uids = uids;
+ break;
+ }
+ case CAMEL_IMAP_JOURNAL_ENTRY_APPEND:
+ {
+ char *uid = va_arg (ap, char *);
+ entry->append_uid = uid;
+ break;
+ }
+ case CAMEL_IMAP_JOURNAL_ENTRY_TRANSFER:
+ {
+ CamelFolder *dest = va_arg (ap, CamelFolder *);
+
+ entry->uids = va_arg (ap, GPtrArray *);
+ entry->move = va_arg (ap, gboolean);
+ entry->dest_folder_name = g_strdup (dest->full_name);
+ break;
+ }
+ }
+
+ va_end (ap);
+
+ e_dlist_addtail (&journal->queue, (EDListNode *) entry);
+ camel_offline_journal_write (journal, NULL);
+}
+
+static void
+close_folder (gpointer name, gpointer folder, gpointer data)
+{
+ g_free (name);
+ camel_folder_sync (folder, FALSE, NULL);
+ camel_object_unref (folder);
+}
+
+void
+camel_imap_journal_close_folders (CamelIMAPJournal *journal)
+{
+
+ if (!journal->folders)
+ return;
+
+ g_hash_table_foreach (journal->folders, close_folder, journal);
+ g_hash_table_remove_all (journal->folders);
+}
+
+void
+camel_imap_journal_uidmap_add (CamelIMAPJournal *journal, const char *old_uid,
+ const char *new_uid)
+{
+ g_hash_table_insert (journal->uidmap, g_strdup (old_uid),
+ g_strdup (new_uid));
+}
+
+const char *
+camel_imap_journal_uidmap_lookup (CamelIMAPJournal *journal, const char *uid)
+{
+ return g_hash_table_lookup (journal->uidmap, uid);
+}
Added: trunk/camel/providers/imap/camel-imap-journal.h
==============================================================================
--- (empty file)
+++ trunk/camel/providers/imap/camel-imap-journal.h Tue Aug 5 08:42:35 2008
@@ -0,0 +1,90 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+/*
+ * Authors :
+ * Chenthill Palanisamy <pchenthill novell com>
+ *
+ * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of version 2 of the GNU Lesser General Public
+ * License as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef __CAMEL_IMAP_JOURNAL_H__
+#define __CAMEL_IMAP_JOURNAL_H__
+
+#include <stdarg.h>
+
+#include <glib.h>
+
+#include <camel/camel-offline-journal.h>
+#include <camel/camel-mime-message.h>
+
+#define CAMEL_TYPE_IMAP_JOURNAL (camel_imap_journal_get_type ())
+#define CAMEL_IMAP_JOURNAL(obj) (CAMEL_CHECK_CAST ((obj), CAMEL_TYPE_IMAP_JOURNAL, CamelIMAPJournal))
+#define CAMEL_IMAP_JOURNAL_CLASS(klass) (CAMEL_CHECK_CLASS_CAST ((klass), CAMEL_TYPE_IMAP_JOURNAL, CamelIMAPJournalClass))
+#define CAMEL_IS_IMAP_JOURNAL(obj) (CAMEL_CHECK_TYPE ((obj), CAMEL_TYPE_IMAP_JOURNAL))
+#define CAMEL_IS_IMAP_JOURNAL_CLASS(klass) (CAMEL_CHECK_CLASS_TYPE ((klass), CAMEL_TYPE_IMAP_JOURNAL))
+#define CAMEL_IMAP_JOURNAL_GET_CLASS(obj) (CAMEL_CHECK_GET_CLASS ((obj), CAMEL_TYPE_IMAP_JOURNAL, CamelIMAPJournalClass))
+
+G_BEGIN_DECLS
+
+typedef struct _CamelIMAPJournal CamelIMAPJournal;
+typedef struct _CamelIMAPJournalClass CamelIMAPJournalClass;
+typedef struct _CamelIMAPJournalEntry CamelIMAPJournalEntry;
+
+struct _CamelImapFolder;
+
+typedef enum {
+ CAMEL_IMAP_JOURNAL_ENTRY_EXPUNGE,
+ CAMEL_IMAP_JOURNAL_ENTRY_APPEND,
+ CAMEL_IMAP_JOURNAL_ENTRY_TRANSFER
+} CamelOfflineAction;
+
+struct _CamelIMAPJournalEntry {
+ EDListNode node;
+
+ CamelOfflineAction type;
+
+ GPtrArray *uids;
+
+ char *append_uid;
+ char *dest_folder_name;
+ gboolean move;
+};
+
+struct _CamelIMAPJournal {
+ CamelOfflineJournal parent_object;
+
+ GHashTable *folders;
+ GHashTable *uidmap;
+};
+
+struct _CamelIMAPJournalClass {
+ CamelOfflineJournalClass parent_class;
+
+};
+
+
+CamelType camel_imap_journal_get_type (void);
+
+CamelOfflineJournal *camel_imap_journal_new (struct _CamelImapFolder *folder, const char *filename);
+void camel_imap_journal_log (CamelOfflineJournal *journal, CamelOfflineAction action, ...);
+void camel_imap_journal_uidmap_add (CamelIMAPJournal *journal, const char *old_uid, const char *n_uid);
+const char *camel_imap_journal_uidmap_lookup (CamelIMAPJournal *journal, const char *uid);
+void camel_imap_journal_close_folders (CamelIMAPJournal *journal);
+
+G_END_DECLS
+
+#endif /* __CAMEL_IMAP_JOURNAL_H__ */
Modified: trunk/camel/providers/imap/camel-imap-store.c
==============================================================================
--- trunk/camel/providers/imap/camel-imap-store.c (original)
+++ trunk/camel/providers/imap/camel-imap-store.c Tue Aug 5 08:42:35 2008
@@ -37,7 +37,6 @@
#include <glib/gstdio.h>
#include "camel/camel-debug.h"
-#include "camel/camel-disco-diary.h"
#include "camel/camel-exception.h"
#include "camel/camel-file-utils.h"
#include "camel/camel-folder.h"
@@ -77,7 +76,7 @@
#define strtok_r(s,sep,lasts) (*(lasts)=strtok((s),(sep)))
#endif
-static CamelDiscoStoreClass *parent_class = NULL;
+static CamelOfflineStoreClass *parent_class = NULL;
static char imap_tag_prefix = 'A';
@@ -90,31 +89,16 @@
static char *imap_get_name (CamelService *service, gboolean brief);
-static gboolean can_work_offline (CamelDiscoStore *disco_store);
-static gboolean imap_connect_online (CamelService *service, CamelException *ex);
-static gboolean imap_connect_offline (CamelService *service, CamelException *ex);
-static gboolean imap_disconnect_online (CamelService *service, gboolean clean, CamelException *ex);
-static gboolean imap_disconnect_offline (CamelService *service, gboolean clean, CamelException *ex);
static void imap_noop (CamelStore *store, CamelException *ex);
static CamelFolder *imap_get_junk(CamelStore *store, CamelException *ex);
static CamelFolder *imap_get_trash(CamelStore *store, CamelException *ex);
static GList *query_auth_types (CamelService *service, CamelException *ex);
static guint hash_folder_name (gconstpointer key);
static gint compare_folder_name (gconstpointer a, gconstpointer b);
-static CamelFolder *get_folder_online (CamelStore *store, const char *folder_name, guint32 flags, CamelException *ex);
-static CamelFolder *get_folder_offline (CamelStore *store, const char *folder_name, guint32 flags, CamelException *ex);
static CamelFolderInfo *create_folder (CamelStore *store, const char *parent_name, const char *folder_name, CamelException *ex);
static void delete_folder (CamelStore *store, const char *folder_name, CamelException *ex);
static void rename_folder (CamelStore *store, const char *old_name, const char *new_name, CamelException *ex);
-static CamelFolderInfo *get_folder_info_online (CamelStore *store,
- const char *top,
- guint32 flags,
- CamelException *ex);
-static CamelFolderInfo *get_folder_info_offline (CamelStore *store,
- const char *top,
- guint32 flags,
- CamelException *ex);
static gboolean folder_subscribed (CamelStore *store, const char *folder_name);
static void subscribe_folder (CamelStore *store, const char *folder_name,
CamelException *ex);
@@ -129,6 +113,12 @@
static void imap_set_server_level (CamelImapStore *store);
static gboolean imap_can_refresh_folder (CamelStore *store, CamelFolderInfo *info, CamelException *ex);
+static gboolean imap_connect (CamelService *service, CamelException *ex);
+static gboolean imap_disconnect (CamelService *service, gboolean clean, CamelException *ex);
+static CamelFolder * get_folder (CamelStore *store, const char *folder_name, guint32 flags, CamelException *ex);
+static CamelFolderInfo * get_folder_info (CamelStore *store, const char *top, guint32 flags, CamelException *ex);
+static CamelFolder * get_folder_offline (CamelStore *store, const char *folder_name, guint32 flags, CamelException *ex);
+static CamelFolderInfo * get_folder_info_offline (CamelStore *store, const char *top, guint32 flags, CamelException *ex);
static void
camel_imap_store_class_init (CamelImapStoreClass *camel_imap_store_class)
@@ -139,10 +129,8 @@
CAMEL_SERVICE_CLASS (camel_imap_store_class);
CamelStoreClass *camel_store_class =
CAMEL_STORE_CLASS (camel_imap_store_class);
- CamelDiscoStoreClass *camel_disco_store_class =
- CAMEL_DISCO_STORE_CLASS (camel_imap_store_class);
- parent_class = CAMEL_DISCO_STORE_CLASS (camel_type_get_global_classfuncs (camel_disco_store_get_type ()));
+ parent_class = CAMEL_OFFLINE_STORE_CLASS (camel_type_get_global_classfuncs (camel_offline_store_get_type ()));
/* virtual method overload */
camel_object_class->setv = imap_setv;
@@ -151,12 +139,16 @@
camel_service_class->construct = construct;
camel_service_class->query_auth_types = query_auth_types;
camel_service_class->get_name = imap_get_name;
+ camel_service_class->connect = imap_connect;
+ camel_service_class->disconnect = imap_disconnect;
camel_store_class->hash_folder_name = hash_folder_name;
camel_store_class->compare_folder_name = compare_folder_name;
+ camel_store_class->get_folder = get_folder;
camel_store_class->create_folder = create_folder;
camel_store_class->delete_folder = delete_folder;
camel_store_class->rename_folder = rename_folder;
+ camel_store_class->get_folder_info = get_folder_info;
camel_store_class->free_folder_info = camel_store_free_folder_info_full;
camel_store_class->folder_subscribed = folder_subscribed;
camel_store_class->subscribe_folder = subscribe_folder;
@@ -165,18 +157,6 @@
camel_store_class->get_trash = imap_get_trash;
camel_store_class->get_junk = imap_get_junk;
camel_store_class->can_refresh_folder = imap_can_refresh_folder;
-
- camel_disco_store_class->can_work_offline = can_work_offline;
- camel_disco_store_class->connect_online = imap_connect_online;
- camel_disco_store_class->connect_offline = imap_connect_offline;
- camel_disco_store_class->disconnect_online = imap_disconnect_online;
- camel_disco_store_class->disconnect_offline = imap_disconnect_offline;
- camel_disco_store_class->get_folder_online = get_folder_online;
- camel_disco_store_class->get_folder_offline = get_folder_offline;
- camel_disco_store_class->get_folder_resyncing = get_folder_online;
- camel_disco_store_class->get_folder_info_online = get_folder_info_online;
- camel_disco_store_class->get_folder_info_offline = get_folder_info_offline;
- camel_disco_store_class->get_folder_info_resyncing = get_folder_info_online;
}
static gboolean
@@ -190,7 +170,6 @@
camel_imap_store_finalize (CamelObject *object)
{
CamelImapStore *imap_store = CAMEL_IMAP_STORE (object);
- CamelDiscoStore *disco = CAMEL_DISCO_STORE (object);
/* This frees current_folder, folders, authtypes, streams, and namespace. */
camel_service_disconnect((CamelService *)imap_store, TRUE, NULL);
@@ -205,11 +184,6 @@
if (imap_store->storage_path)
g_free (imap_store->storage_path);
- if (disco->diary) {
- camel_object_unref (disco->diary);
- disco->diary = NULL;
- }
-
g_free (imap_store->namespace);
imap_store->namespace = NULL;
@@ -242,7 +216,7 @@
if (camel_imap_store_type == CAMEL_INVALID_TYPE) {
camel_imap_store_type =
- camel_type_register (CAMEL_DISCO_STORE_TYPE,
+ camel_type_register (camel_offline_store_get_type (),
"CamelImapStore",
sizeof (CamelImapStore),
sizeof (CamelImapStoreClass),
@@ -262,8 +236,7 @@
{
CamelImapStore *imap_store = CAMEL_IMAP_STORE (service);
CamelStore *store = CAMEL_STORE (service);
- CamelDiscoStore *disco_store = CAMEL_DISCO_STORE (service);
- char *tmp, *path;
+ char *tmp;
CamelURL *summary_url;
CAMEL_SERVICE_CLASS (parent_class)->construct (service, session, provider, url, ex);
@@ -310,12 +283,6 @@
imap_store->custom_headers = g_strdup(camel_url_get_param (url, "imap_custom_headers"));
}
-
- /* setup journal*/
- path = g_strdup_printf ("%s/journal", imap_store->storage_path);
- disco_store->diary = camel_disco_diary_new (disco_store, path, ex);
- g_free (path);
-
/* setup/load the store summary */
tmp = alloca(strlen(imap_store->storage_path)+32);
sprintf(tmp, "%s/.ev-store-summary", imap_store->storage_path);
@@ -505,7 +472,7 @@
static void
parse_capability(CamelImapStore *store, char *capa)
{
- char *lasts;
+ char *lasts = NULL;
int i;
for (capa = strtok_r (capa, " ", &lasts); capa; capa = strtok_r (NULL, " ", &lasts)) {
@@ -1030,8 +997,11 @@
GList *sasl_types, *t, *next;
gboolean connected;
- if (!camel_disco_store_check_online (CAMEL_DISCO_STORE (store), ex))
+ if (CAMEL_OFFLINE_STORE (store)->state == CAMEL_OFFLINE_STORE_NETWORK_UNAVAIL) {
+ camel_exception_set (ex, CAMEL_EXCEPTION_SERVICE_UNAVAILABLE,
+ _("You must be working online to complete this operation"));
return NULL;
+ }
CAMEL_SERVICE_REC_LOCK (store, connect_lock);
connected = store->istream != NULL && store->connected;
@@ -1422,15 +1392,7 @@
}
static gboolean
-can_work_offline (CamelDiscoStore *disco_store)
-{
- CamelImapStore *store = CAMEL_IMAP_STORE (disco_store);
-
- return camel_store_summary_count((CamelStoreSummary *)store->summary) != 0;
-}
-
-static gboolean
-imap_connect_online (CamelService *service, CamelException *ex)
+imap_connect (CamelService *service, CamelException *ex)
{
CamelImapStore *store = CAMEL_IMAP_STORE (service);
CamelImapResponse *response;
@@ -1439,6 +1401,9 @@
size_t len;
CamelImapStoreNamespace *ns;
+ if (((CamelOfflineStore *) store)->state == CAMEL_OFFLINE_STORE_NETWORK_UNAVAIL)
+ return TRUE;
+
CAMEL_SERVICE_REC_LOCK (store, connect_lock);
if (!connect_to_server_wrapper (service, ex) ||
!imap_auth_loop (service, ex)) {
@@ -1573,23 +1538,17 @@
}
static gboolean
-imap_connect_offline (CamelService *service, CamelException *ex)
+imap_disconnect (CamelService *service, gboolean clean, CamelException *ex)
{
CamelImapStore *store = CAMEL_IMAP_STORE (service);
- CamelDiscoStore *disco_store = CAMEL_DISCO_STORE (service);
- if (!disco_store->diary)
- return FALSE;
- store->connected = !camel_exception_is_set (ex);
+ if (CAMEL_OFFLINE_STORE (store)->state == CAMEL_OFFLINE_STORE_NETWORK_AVAIL && clean) {
+ CamelImapResponse *response;
- return store->connected;
-}
-
-static gboolean
-imap_disconnect_offline (CamelService *service, gboolean clean, CamelException *ex)
-{
- CamelImapStore *store = CAMEL_IMAP_STORE (service);
+ response = camel_imap_command (store, NULL, NULL, "LOGOUT");
+ camel_imap_response_free (store, response);
+ }
if (store->istream) {
camel_stream_close(store->istream);
@@ -1625,23 +1584,6 @@
}
static gboolean
-imap_disconnect_online (CamelService *service, gboolean clean, CamelException *ex)
-{
- CamelImapStore *store = CAMEL_IMAP_STORE (service);
- CamelImapResponse *response;
-
- if (store->connected && clean) {
- response = camel_imap_command (store, NULL, NULL, "LOGOUT");
- camel_imap_response_free (store, response);
- }
-
- imap_disconnect_offline (service, clean, ex);
-
- return TRUE;
-}
-
-
-static gboolean
imap_summary_is_dirty (CamelFolderSummary *summary)
{
CamelImapMessageInfo *info;
@@ -1850,7 +1792,7 @@
}
static CamelFolder *
-get_folder_online (CamelStore *store, const char *folder_name, guint32 flags, CamelException *ex)
+get_folder (CamelStore *store, const char *folder_name, guint32 flags, CamelException *ex)
{
CamelImapStore *imap_store = CAMEL_IMAP_STORE (store);
CamelImapResponse *response;
@@ -1862,6 +1804,13 @@
new_folder = get_folder_offline(store, folder_name, flags, ex);
if (new_folder)
return new_folder;
+
+ if (CAMEL_OFFLINE_STORE (store)->state == CAMEL_OFFLINE_STORE_NETWORK_UNAVAIL) {
+ camel_exception_set (ex, CAMEL_EXCEPTION_SERVICE_UNAVAILABLE,
+ _("You must be working online to complete this operation"));
+ return NULL;
+ }
+
camel_exception_clear(ex);
CAMEL_SERVICE_REC_LOCK(imap_store, connect_lock);
@@ -2272,8 +2221,12 @@
int i = 0, flags;
const char *c;
- if (!camel_disco_store_check_online (CAMEL_DISCO_STORE (store), ex))
+ if (CAMEL_OFFLINE_STORE (store)->state == CAMEL_OFFLINE_STORE_NETWORK_UNAVAIL) {
+ camel_exception_set (ex, CAMEL_EXCEPTION_SERVICE_UNAVAILABLE,
+ _("You must be working online to complete this operation"));
return NULL;
+ }
+
if (!parent_name)
parent_name = "";
@@ -2708,7 +2661,7 @@
};
static CamelFolderInfo *
-get_folder_info_online (CamelStore *store, const char *top, guint32 flags, CamelException *ex)
+get_folder_info (CamelStore *store, const char *top, guint32 flags, CamelException *ex)
{
CamelImapStore *imap_store = CAMEL_IMAP_STORE (store);
CamelFolderInfo *tree = NULL;
@@ -2723,6 +2676,11 @@
if (camel_debug("imap:folder_info"))
printf("get folder info online\n");
+ if (CAMEL_OFFLINE_STORE (store)->state == CAMEL_OFFLINE_STORE_NETWORK_UNAVAIL) {
+ tree = get_folder_info_offline (store, top, flags, ex);
+ return tree;
+ }
+
if ((flags & CAMEL_STORE_FOLDER_INFO_SUBSCRIBED)
&& camel_store_summary_count((CamelStoreSummary *)imap_store->summary) > 0) {
time_t now;
@@ -3021,9 +2979,9 @@
did connect anyway ... */
if (store->istream != NULL
- || (camel_disco_store_check_online((CamelDiscoStore *)store, ex)
+ || (((CAMEL_OFFLINE_STORE (store)->state == CAMEL_OFFLINE_STORE_NETWORK_AVAIL)
&& camel_service_connect((CamelService *)store, ex)
- && store->istream != NULL))
+ && store->istream != NULL)))
return TRUE;
if (!camel_exception_is_set(ex))
Modified: trunk/camel/providers/imap/camel-imap-store.h
==============================================================================
--- trunk/camel/providers/imap/camel-imap-store.h (original)
+++ trunk/camel/providers/imap/camel-imap-store.h Tue Aug 5 08:42:35 2008
@@ -26,7 +26,7 @@
#define CAMEL_IMAP_STORE_H 1
#include "camel-imap-types.h"
-#include <camel/camel-disco-store.h>
+#include <camel/camel-offline-store.h>
#include <sys/time.h>
#ifdef ENABLE_THREADS
@@ -60,7 +60,7 @@
G_BEGIN_DECLS
enum {
- CAMEL_IMAP_STORE_ARG_FIRST = CAMEL_DISCO_STORE_ARG_FIRST + 100,
+ CAMEL_IMAP_STORE_ARG_FIRST = CAMEL_OFFLINE_STORE_ARG_FIRST + 100,
CAMEL_IMAP_STORE_ARG_NAMESPACE,
CAMEL_IMAP_STORE_ARG_OVERRIDE_NAMESPACE,
CAMEL_IMAP_STORE_ARG_CHECK_ALL,
@@ -115,7 +115,7 @@
#define IMAP_FETCH_MINIMAL_HEADERS 3
struct _CamelImapStore {
- CamelDiscoStore parent_object;
+ CamelOfflineStore parent_object;
CamelStream *istream;
CamelStream *ostream;
@@ -150,7 +150,7 @@
};
typedef struct {
- CamelDiscoStoreClass parent_class;
+ CamelOfflineStoreClass parent_class;
} CamelImapStoreClass;
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]