evolution-data-server r9266 - in trunk/camel: . providers providers/imap



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]