Re: [Tracker] Preview patch for Modest support in tracker



Hi there,

After this version of the patch IMAP, Maildir and POP accounts of
tinymail based E-mail clients like Modest should start getting indexed
correctly.

I also disabled the "find_attachment" function for the Modest support,
as on most devices you don't want to decode+write thousands of
attachments in /tmp (for example on the Nokia devices, /tmp is afaik a
memdisk -> not a good idea to write +15M sized attachments over there).


On Tue, 2008-04-08 at 16:53 +0200, Philip Van Hoof wrote:
> Some things are still ugly here and there, especially thing related to
> MIME parsing.
> 
> But this one is actually working. Just copy $HOME/.modest from your
> Nokia N800/N810 device to your desktop's $HOME, and run the patched
> trackerd to test this.
> 
> Right now it assumes existence of a bin called modest-open, which is not
> yet build by the current Modest package. There's a test application in
> Modest's source code that already does what this modest-open will do.
> 
> I noticed that if the mail is locally downloaded, that its attachments
> are stored in /tmp. On a Nokia device this wont be a good idea,
> since /tmp is afaik a memdisk and attachments can be quite big. But then
> again, this patch is a work in progress.
> 
> 
> _______________________________________________
> tracker-list mailing list
> tracker-list gnome org
> http://mail.gnome.org/mailman/listinfo/tracker-list
-- 
Philip Van Hoof, freelance software developer
home: me at pvanhoof dot be 
gnome: pvanhoof at gnome dot org 
http://pvanhoof.be/blog
http://codeminded.be



Index: python/deskbar-handler/tracker-module.py
===================================================================
--- python/deskbar-handler/tracker-module.py	(revision 1250)
+++ python/deskbar-handler/tracker-module.py	(working copy)
@@ -112,6 +112,7 @@
 		'action': { # more actions for different MUAs
 			'key': 'mua', # see TrackerLiveSearchAction.action for a demo
 			'Evolution/Email':    'evolution %(uri)s',
+			'Modest/Email':    'modest-open %(uri)s',
 			'Thunderbird/Email':  'thunderbird -viewtracker %(uri)s',
 			'KMail/Email':        'kmail --view %(uri)s',
 		},
Index: python/deskbar-handler/tracker-handler.py
===================================================================
--- python/deskbar-handler/tracker-handler.py	(revision 1250)
+++ python/deskbar-handler/tracker-handler.py	(working copy)
@@ -49,6 +49,7 @@
 		'action': { # more actions for different MUAs
 			'key': 'mua', # see TrackerLiveSearchMatch.action for a demo
 			'Evolution/Email':    'evolution %(uri)s',
+			'Modest/Email':    'modest-open %(uri)s',
 			'Thunderbird/Email':  'thunderbird -viewtracker %(uri)s',
 			'KMail/Email':        'kmail --view %(uri)s',
 		},
Index: src/trackerd/tracker-db-email.c
===================================================================
--- src/trackerd/tracker-db-email.c	(revision 1250)
+++ src/trackerd/tracker-db-email.c	(working copy)
@@ -65,7 +65,7 @@
                                 const gchar     *filename,
                                 const gchar     *uri_prefix)
 {
-	gchar *types[5] = {"MBOX", "IMAP", "IMAP4", "MAIL_TYPE_MAILDIR", "MAIL_TYPE_MH"};
+	gchar *types[6] = {"MBOX", "IMAP", "IMAP4", "MAIL_TYPE_MAILDIR", "MAIL_TYPE_MH", "MAIL_TYPE_POP"};
 
 	gchar *str_mail_app = tracker_int_to_str (mail_app);
 	gchar *str_mail_type = tracker_int_to_str (mail_type);
@@ -393,6 +393,8 @@
 {
        if (app == MAIL_APP_EVOLUTION) {
                return g_strdup ("EvolutionEmails");
+       } else if (app == MAIL_APP_MODEST) {
+               return g_strdup ("ModestEmails");
        } else if (app == MAIL_APP_KMAIL) {
                return g_strdup ("KMailEmails");
        } else if (app == MAIL_APP_THUNDERBIRD) {
@@ -410,6 +412,8 @@
 {
        if (app == MAIL_APP_EVOLUTION) {
                return g_strdup ("Evolution/Email");
+       } else if (app == MAIL_APP_MODEST) {
+               return g_strdup ("Modest/Email");
        } else if (app == MAIL_APP_KMAIL) {
                return g_strdup ("KMail/Email");
        } else if (app == MAIL_APP_THUNDERBIRD) {
@@ -427,6 +431,8 @@
 {
        if (app == MAIL_APP_EVOLUTION) {
                return g_strdup ("EvolutionAttachments");
+       } else if (app == MAIL_APP_MODEST) {
+               return g_strdup ("ModestAttachments");
        } else if (app == MAIL_APP_KMAIL) {
                return g_strdup ("KMailAttachments");
        } else if (app == MAIL_APP_THUNDERBIRD) {
@@ -458,7 +464,7 @@
 
 
 gboolean
-tracker_db_email_save_email (DBConnection *db_con, MailMessage *mm)
+tracker_db_email_save_email (DBConnection *db_con, MailMessage *mm, MailApplication mail_app)
 {
        	gint  mbox_id, type_id, id, len;
 	gchar *service, *attachment_service, *mime;
@@ -523,10 +529,9 @@
 	} else {
 		mbox_id = 0;
 		mm->offset =0;
-                service = g_strdup ("EvolutionEmails");
-                mime = g_strdup ("Evolution/Email");
-                attachment_service = g_strdup ("EvolutionAttachments");
-
+                service = get_service_name (mail_app);
+                mime = get_mime (mail_app);
+                attachment_service = get_attachment_service_name (mail_app);
 	}
 
 	type_id = tracker_get_id_for_service (service);
Index: src/trackerd/tracker-db-email.h
===================================================================
--- src/trackerd/tracker-db-email.h	(revision 1250)
+++ src/trackerd/tracker-db-email.h	(working copy)
@@ -28,7 +28,7 @@
 off_t	  tracker_db_email_get_last_mbox_offset  (DBConnection *db_con, const gchar *mail_file_path);
 void	  tracker_db_email_update_mbox_offset    (DBConnection *db_con, MailFile *mf);
 gboolean  tracker_db_email_is_up_to_date         (DBConnection *db_con, const gchar *uri, guint32 *id);
-gboolean  tracker_db_email_save_email	         (DBConnection *db_con, MailMessage *mm);
+gboolean  tracker_db_email_save_email	         (DBConnection *db_con, MailMessage *mm, MailApplication mail_app);
 gboolean  tracker_db_email_is_saved_email_file   (DBConnection *db_con, const gchar *uri);
 void	  tracker_db_email_update_email	         (DBConnection *db_con, MailMessage *mm);
 gboolean  tracker_db_email_delete_email_file     (DBConnection *db_con, const gchar *uri);
Index: src/trackerd/tracker-email-utils.c
===================================================================
--- src/trackerd/tracker-email-utils.c	(revision 1250)
+++ src/trackerd/tracker-email-utils.c	(working copy)
@@ -86,13 +86,13 @@
 	g_return_val_if_fail (path, FALSE);
 
 	mail_msg = email_parse_mail_message_by_path (mail_app, path,
-                                                     read_mail_helper, read_mail_user_data);
+                                                     read_mail_helper, read_mail_user_data, NULL);
 
 	if (!mail_msg) {
 		return FALSE;
 	}
 
-	tracker_db_email_save_email (db_con, mail_msg);
+	tracker_db_email_save_email (db_con, mail_msg, mail_app);
 
 	email_free_mail_message (mail_msg);
 
@@ -123,7 +123,7 @@
 	tracker->mbox_count++;
 	tracker_dbus_send_index_progress_signal ("Emails", path);
 
-	while ((mail_msg = email_mail_file_parse_next (mf, read_mail_helper, read_mail_user_data))) {
+	while ((mail_msg = email_mail_file_parse_next (mf, read_mail_helper, read_mail_user_data, NULL))) {
 
 		if (!tracker->is_running) {
 			email_free_mail_message (mail_msg);
@@ -154,7 +154,7 @@
 			deleted++;
 		}
 
-		tracker_db_email_save_email (db_con, mail_msg);
+		tracker_db_email_save_email (db_con, mail_msg, mail_app);
 		tracker_db_email_update_mbox_offset (db_con, mf);
 
 		email_free_mail_message (mail_msg);
@@ -426,6 +426,10 @@
 
 	/* we do not free parent_mail_file of course... */
 
+	if (mail_msg->uid) {
+		g_free (mail_msg->uid);
+	}
+
 	if (mail_msg->path) {
 		g_free (mail_msg->path);
 	}
@@ -493,7 +497,7 @@
 
 
 MailMessage *
-email_mail_file_parse_next (MailFile *mf, ReadMailHelperFct read_mail_helper, gpointer read_mail_user_data)
+email_mail_file_parse_next (MailFile *mf, ReadMailHelperFct read_mail_helper, gpointer read_mail_user_data, FindAttachmentsHelperFct find_attachments_helper)
 {
 	MailMessage  *mail_msg;
 	guint64      msg_offset;
@@ -543,14 +547,17 @@
 	mail_msg->content_type = g_strdup (is_html ? "text/html" : "text/plain");
 
 	if (read_mail_helper) {
-                (*read_mail_helper) (g_m_message, mail_msg, read_mail_user_data);
+		(*read_mail_helper) (g_m_message, mail_msg, read_mail_user_data);
 	}
 
 	mail_msg->attachments = NULL;
 
 	/* find then save attachments in sys tmp directory of Tracker and save entries in MailMessage struct */
-	g_mime_message_foreach_part (g_m_message, find_attachment, mail_msg);
+	if (find_attachments_helper == NULL) 
+		find_attachments_helper = find_attachment;
 
+	g_mime_message_foreach_part (g_m_message, find_attachments_helper, mail_msg);
+
 	g_object_unref (g_m_message);
 
 	return mail_msg;
@@ -559,7 +566,7 @@
 
 MailMessage *
 email_parse_mail_message_by_path (MailApplication mail_app, const gchar *path,
-                                  ReadMailHelperFct read_mail_helper, gpointer read_mail_user_data)
+                                  ReadMailHelperFct read_mail_helper, gpointer read_mail_user_data, FindAttachmentsHelperFct find_attachments_helper)
 {
 	MailFile    *mf;
 	MailMessage *mail_msg;
@@ -571,7 +578,7 @@
                 return NULL;
         }
 
-	mail_msg = email_mail_file_parse_next (mf, read_mail_helper, read_mail_user_data);
+	mail_msg = email_mail_file_parse_next (mf, read_mail_helper, read_mail_user_data, find_attachments_helper);
 
 	if (mail_msg) {
 		mail_msg->path = g_strdup (path);
Index: src/trackerd/tracker-email.c
===================================================================
--- src/trackerd/tracker-email.c	(revision 1250)
+++ src/trackerd/tracker-email.c	(working copy)
@@ -77,7 +77,7 @@
 	if (!g_module_symbol (module, "tracker_email_index_file", (gpointer *) &func))
 		return FALSE;
 
-	return (func) (db_con, info);
+	return (func) (db_con->emails, info);
 }
 
 gboolean
Index: src/trackerd/tracker-email-utils.h
===================================================================
--- src/trackerd/tracker-email-utils.h	(revision 1250)
+++ src/trackerd/tracker-email-utils.h	(working copy)
@@ -31,6 +31,7 @@
 	MAIL_APP_KMAIL,
 	MAIL_APP_THUNDERBIRD,
         MAIL_APP_THUNDERBIRD_FEED,
+	MAIL_APP_MODEST,
 	MAIL_APP_UNKNOWN
 } MailApplication;
 
@@ -41,7 +42,8 @@
 	MAIL_TYPE_IMAP,
 	MAIL_TYPE_IMAP4,
 	MAIL_TYPE_MAILDIR,
-	MAIL_TYPE_MH
+	MAIL_TYPE_MH,
+	MAIL_TYPE_POP,
 } MailType;
 
 
@@ -119,13 +121,15 @@
 	gchar		*content_type;		/* text/plain or text/html etc. */
 	gchar		*body;
 	GSList		*attachments;		/* names of attachments */
-	MailStore	*store;	
+	MailStore	*store;
+	gchar		*uid;
 } MailMessage;
 
 
 void		email_watch_directory				(const gchar *dir, const gchar *service);
 void		email_watch_directories				(const GSList *dirs, const gchar *service);
 
+typedef void ( * FindAttachmentsHelperFct) (GMimeObject *obj, gpointer data);
 typedef void (* ReadMailHelperFct) (GMimeMessage *g_m_message, MailMessage *msg, gpointer read_mail_user_data);
 typedef gchar* (* MakeURIHelperFct) (MailMessage *msg, gpointer read_mail_user_data);
 
@@ -154,10 +158,12 @@
 
 MailFile *	email_open_mail_file_at_offset			(MailApplication mail_app, const char *path, off_t offset, gboolean scan_from_for_mbox);
 void		email_free_mail_file				(MailFile *mf);
-MailMessage *	email_mail_file_parse_next			(MailFile *mf, ReadMailHelperFct read_mail_helper, gpointer read_mail_user_data);
+MailMessage *	email_mail_file_parse_next			(MailFile *mf, ReadMailHelperFct read_mail_helper, gpointer read_mail_user_data,
+                                                                 FindAttachmentsHelperFct find_attachments_helper);
 
 MailMessage *	email_parse_mail_message_by_path                (MailApplication mail_app, const gchar *path,
-                                                                 ReadMailHelperFct read_mail_helper, gpointer read_mail_user_data);
+                                                                 ReadMailHelperFct read_mail_helper, gpointer read_mail_user_data,
+                                                                 FindAttachmentsHelperFct find_attachments_helper);
 
 MimeInfos *	email_allocate_mime_infos			(void);
 void		email_free_mime_infos				(MimeInfos *infos);
Index: src/trackerd/tracker-email-thunderbird.c
===================================================================
--- src/trackerd/tracker-email-thunderbird.c	(revision 1250)
+++ src/trackerd/tracker-email-thunderbird.c	(working copy)
@@ -178,7 +178,7 @@
             
         if (mail_msg->parent_mail_file->mail_app == MAIL_APP_THUNDERBIRD ) {
 //           || mail_msg->parent_mail_file->mail_app == MAIL_APP_THUNDERBIRD_FEED) {
-                tracker_db_email_save_email (db_con, mail_msg);
+                tracker_db_email_save_email (db_con, mail_msg, mail_app);
                 email_free_mail_file(mail_msg->parent_mail_file);
                 email_free_mail_message (mail_msg);
                 return TRUE;
Index: src/trackerd/tracker-dbus-search.c
===================================================================
--- src/trackerd/tracker-dbus-search.c	(revision 1250)
+++ src/trackerd/tracker-dbus-search.c	(working copy)
@@ -103,7 +103,8 @@
 		service_array[1] = tracker_get_id_for_service ("EvolutionEmails");
 		service_array[2] = tracker_get_id_for_service ("KMailEmails");
 		service_array[3] = tracker_get_id_for_service ("ThunderbirdEmails");
-		service_count = 4;
+		service_array[4] = tracker_get_id_for_service ("ModestEmails");
+		service_count = 5;
 
  	} else if (strcmp (service, "Conversations") == 0) {
 		service_array[1] = tracker_get_id_for_service ("GaimConversations");
Index: src/trackerd/tracker-email-evolution.c
===================================================================
--- src/trackerd/tracker-email-evolution.c	(revision 1250)
+++ src/trackerd/tracker-email-evolution.c	(working copy)
@@ -1401,7 +1401,7 @@
 				if (!(*save_ondisk_mail) (db_con, mail_msg)) {
 					tracker_log ("WARNING: Message, or message parts, could not be found locally - if you are using IMAP make sure you have selected the \"copy folder content locally for offline operation\" option in Evolution");
 					/* we do not have all infos but we still save them */
-					if (!tracker_db_email_save_email (db_con, mail_msg)) {
+					if (!tracker_db_email_save_email (db_con, mail_msg, MAIL_APP_EVOLUTION)) {
 						tracker_log ("Failed to save email");
 					}
 				}
@@ -2308,7 +2308,7 @@
 			tracker_log ("... Treatment of mail parts of \"%s\" finished", mail_msg->uri);
 
 			if (ret) {
-				tracker_db_email_save_email (db_con, mail_msg);
+				tracker_db_email_save_email (db_con, mail_msg, MAIL_APP_EVOLUTION);
 			}
 		} else {
                         tracker_log ("...Indexing of mail parts failed");
@@ -2337,7 +2337,7 @@
 		MailMessage *mail_msg_on_disk = NULL;
 
 		mail_msg_on_disk = email_parse_mail_message_by_path (MAIL_APP_EVOLUTION,
-                                                                     mail_msg->path, NULL, NULL);
+				mail_msg->path, NULL, NULL, NULL);
 
 		if (mail_msg_on_disk && mail_msg_on_disk->parent_mail_file) {
 
@@ -2345,9 +2345,9 @@
 			mail_msg_on_disk->uri = g_strdup (mail_msg->uri);
 			mail_msg_on_disk->store = mail_msg->store;
 
-			tracker_db_email_save_email (db_con, mail_msg_on_disk);
+			tracker_db_email_save_email (db_con, mail_msg_on_disk, MAIL_APP_EVOLUTION);
 
-                        email_free_mail_file (mail_msg_on_disk->parent_mail_file);
+			email_free_mail_file (mail_msg_on_disk->parent_mail_file);
 			email_free_mail_message (mail_msg_on_disk);
 
 			return TRUE;
@@ -2652,7 +2652,7 @@
 	gint i = sizeof (type) - 1;			\
 	gint v = EOF;					\
 							\
-        while (i >= 0 && (v = fgetc (in)) != EOF) {	\
+	while (i >= 0 && (v = fgetc (in)) != EOF) {	\
 		save |= ((type)v) << (i * 8);		\
 		i--;					\
 	}						\
Index: src/trackerd/tracker-email-modest.c
===================================================================
--- src/trackerd/tracker-email-modest.c	(revision 0)
+++ src/trackerd/tracker-email-modest.c	(revision 0)
@@ -0,0 +1,1867 @@
+/* Tracker
+ * routines for emails with Modest
+ * Copyright (C) 2008, Philip Van Hoof (pvanhoof gnome org)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef _GNU_SOURCE
+#define _GNU_SOURCE
+#endif
+
+#include <libtracker-common/tracker-log.h>
+#include <libtracker-common/tracker-config.h>
+
+#include <fcntl.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
+#include <glib/gstdio.h>
+#include <dirent.h>
+
+#include "tracker-email-modest.h"
+#include "tracker-email-utils.h"
+#include "tracker-db-email.h"
+#include "tracker-cache.h"
+#include "tracker-dbus.h"
+#include "tracker-watch.h"
+
+
+#define MODEST_MAIL_DIR_S ".modest/cache/mail"
+#define MODEST_LOCAL_MAIL_DIR_S ".modest/local_folders"
+
+
+typedef struct {
+	gchar		*mail_dir;	/* something like "/home/laurent.modest/mail" */
+	GSList		*imap_dirs;	/* list of IMAP directories */
+	GSList		*pop_dirs;	/* list of POP directories */
+	GSList		*maildir_dirs;	/* list of maildir directories */
+} ModestConfig;
+
+
+enum {
+	MODEST_MESSAGE_ANSWERED     = 1 << 0,
+	MODEST_MESSAGE_DELETED      = 1 << 1,
+	MODEST_MESSAGE_DRAFT        = 1 << 2,
+	MODEST_MESSAGE_FLAGGED      = 1 << 3,
+	MODEST_MESSAGE_SEEN         = 1 << 4,
+	MODEST_MESSAGE_ATTACHMENTS  = 1 << 5,
+	MODEST_MESSAGE_CACHED       = 1 << 6,
+	MODEST_MESSAGE_PARTIAL      = 1 << 7,
+	MODEST_MESSAGE_EXPUNGED     = 1 << 8,
+	MODEST_MESSAGE_HIGH_PRIORITY = 0<<9|1<<10,
+	MODEST_MESSAGE_NORMAL_PRIORITY = 0<<9|0<<10,
+	MODEST_MESSAGE_LOW_PRIORITY = 1<<9|0<<10,
+	MODEST_MESSAGE_SUSPENDED = 1<<11
+};
+
+typedef struct {
+	gchar            *path;                 /* path the summary file */
+	FILE             *f;                    /* opened file descriptor for the file */
+} SummaryFile;
+
+typedef struct {
+	gint32		version;
+	gboolean	legacy;
+	gint32		flags;
+	gint32		nextuid;
+	time_t		time;
+	gint32		saved_count;
+	gint32		unread_count;
+	gint32		deleted_count;
+	gint32		junk_count;
+	gchar 		*uri_prefix;
+} SummaryFileHeader;
+
+/* Some infos are only accessible throw a deep code path but we need to retreive them. */
+typedef struct {
+	gchar		*mail_uid;
+} ModestAdHocInfos;
+
+
+extern Tracker		*tracker;
+
+static ModestConfig	*modest_config = NULL;
+
+
+static gboolean	load_modest_config			(ModestConfig **conf);
+static void	free_modest_config			(ModestConfig *conf);
+
+
+static gboolean	is_in_dir_pop				(const gchar *dir);
+static gboolean	is_in_dir_imap				(const gchar *dir);
+static gboolean	is_in_dir_maildir			(const gchar *dir);
+
+typedef gboolean (* LoadSummaryFileMetaHeaderFct) (SummaryFile *summary, SummaryFileHeader *header);
+typedef gboolean (* LoadMailMessageFct) (SummaryFile *summary, MailMessage **mail_msg);
+typedef gboolean (* SkipMailMessageFct) (SummaryFile *summary);
+typedef gboolean (* SaveOnDiskMailMessageFct) (DBConnection *db_con, MailMessage *msg);
+
+static void	index_mail_messages_by_summary_file	(DBConnection *db_con, MailType mail_type,
+							 const gchar *summary_file_path,
+							 LoadSummaryFileMetaHeaderFct load_meta_header,
+							 LoadMailMessageFct load_mail,
+							 SkipMailMessageFct skip_mail,
+							 SaveOnDiskMailMessageFct save_ondisk_mail);
+
+static gboolean	open_summary_file			(const gchar *path, SummaryFile **summary);
+static void	free_summary_file			(SummaryFile *summary);
+
+static gboolean	load_summary_file_header		(SummaryFile *summary, SummaryFileHeader **header);
+static void	free_summary_file_header		(SummaryFileHeader *header);
+static gboolean	load_summary_file_meta_header_for_pop	(SummaryFile *summary, SummaryFileHeader *header);
+static gboolean	load_summary_file_meta_header_for_maildir (SummaryFile *summary, SummaryFileHeader *header);
+static gboolean	load_summary_file_meta_header_for_imap	(SummaryFile *summary, SummaryFileHeader *header);
+
+static gboolean	load_mail_message_for_imap		(SummaryFile *summary, MailMessage **mail_msg);
+static gboolean	load_mail_message_for_pop		(SummaryFile *summary, MailMessage **mail_msg);
+static gboolean	load_mail_message_for_maildir		(SummaryFile *summary, MailMessage **mail_msg);
+static gboolean	do_load_mail_message_for_imap		(SummaryFile *summary, MailMessage **mail_msg, gboolean do_skipping_of_content_info);
+static gboolean	do_load_mail_message_for_pop		(SummaryFile *summary, MailMessage **mail_msg, gboolean do_skipping_of_content_info);
+static gboolean	do_load_mail_message_for_maildir		(SummaryFile *summary, MailMessage **mail_msg, gboolean do_skipping_of_content_info);
+
+static gboolean	load_mail_message			(SummaryFile *summary, MailMessage *mail_msg);
+
+static gboolean	skip_mail_message_for_imap		(SummaryFile *summary);
+static gboolean	skip_mail_message_for_pop		(SummaryFile *summary);
+static gboolean	skip_mail_message_for_maildir		(SummaryFile *summary);
+
+static gboolean	do_skip_mail_message_for_maildir	(SummaryFile *summary, gboolean do_skipping_of_content_info);
+static gboolean	do_skip_mail_message_for_pop		(SummaryFile *summary, gboolean do_skipping_of_content_info);
+static gboolean	do_skip_mail_message_for_imap		(SummaryFile *summary, gboolean do_skipping_of_content_info);
+
+static gboolean	skip_mail_message			(SummaryFile *summary);
+
+static gboolean	skip_loading_content_info		(SummaryFile *summary);
+static gboolean	do_skip_loading_content_info		(SummaryFile *summary);
+
+static gboolean	save_ondisk_email_message_for_imap	(DBConnection *db_con, MailMessage *mail_msg);
+static gboolean	save_ondisk_email_message_for_pop	(DBConnection *db_con, MailMessage *mail_msg);
+static gboolean	save_ondisk_email_message_for_maildir	(DBConnection *db_con, MailMessage *mail_msg);
+static gboolean	do_save_ondisk_email_message_generic	(DBConnection *db_con, MailMessage *mail_msg);
+static gboolean	do_save_ondisk_email_message		(DBConnection *db_con, MailMessage *mail_msg);
+
+static GSList *	add_persons_from_internet_address_list_string_parsing	(GSList *list, const gchar *s);
+
+static inline gboolean	decode_gint32		(FILE *f, gint32 *n);
+static inline gboolean	skip_gint32_decoding	(FILE *f);
+static inline gboolean	decode_guint32		(FILE *f, guint32 *n);
+static inline gboolean	skip_guint32_decoding	(FILE *f);
+static inline gboolean	decode_time_t		(FILE *f, time_t *t);
+static inline gboolean	skip_time_t_decoding	(FILE *f);
+static inline gboolean	decode_off_t		(FILE *f, off_t *t);
+static inline gboolean	skip_off_t_decoding	(FILE *f);
+static inline gboolean	decode_string		(FILE *f, gchar **str);
+static inline gboolean	skip_string_decoding	(FILE *f);
+static inline gboolean	skip_token_decoding	(FILE *f);
+
+static void  check_summary_file (DBConnection *db_con, const gchar *filename, MailStore *store);
+
+
+static gboolean
+modest_module_is_running (void)
+{
+	return modest_config != NULL;
+}
+ 
+
+/********************************************************************************************
+ Public functions
+*********************************************************************************************/
+
+gboolean
+tracker_email_init (void)
+{
+	ModestConfig *conf;
+
+	if (modest_config) {
+		return TRUE;
+	}
+
+	conf = NULL;
+
+	if (load_modest_config (&conf)) {
+		modest_config = conf;
+	}
+
+	return modest_module_is_running ();
+}
+
+
+
+gboolean
+tracker_email_finalize (void)
+{
+	if (!modest_config) {
+		return TRUE;
+	}
+
+	free_modest_config (modest_config);
+	modest_config = NULL;
+
+	return !modest_module_is_running ();
+}
+
+static void
+free_modest_config (ModestConfig *conf)
+{
+	if (!conf) {
+		return;
+	}
+
+	if (conf->mail_dir) {
+		g_free (conf->mail_dir);
+	}
+
+	#define FREE_MY_LIST(list, free_fct)				\
+		g_slist_foreach (list, (GFunc) free_fct, NULL);		\
+		g_slist_free (list);
+
+	FREE_MY_LIST (conf->imap_dirs, g_free);
+	FREE_MY_LIST (conf->pop_dirs, g_free);
+	FREE_MY_LIST (conf->maildir_dirs, g_free);
+
+	#undef FREE_MY_LIST
+
+	g_slice_free (ModestConfig, conf);
+}
+
+void
+tracker_email_watch_emails (DBConnection *db_con)
+{
+	gchar ***res, **row;
+	gint  j;
+
+	/* if initial indexing has not finished reset mtime on all email stuff so they are rechecked */
+	if (tracker_db_get_option_int (db_con->common, "InitialIndex") == 1) {
+		char *sql = g_strdup_printf ("update Services set mtime = 0 where path like '%s/.modest/%s'", g_get_home_dir (), "%");
+
+		tracker_exec_sql (db_con, sql);
+		g_free (sql);
+	}
+
+	/* check all registered mbox/paths for deletions */
+	res = tracker_db_email_get_mboxes (db_con);
+
+	for (j = 0; (row = tracker_db_get_row (res, j)); j++) {
+
+		if (row[2] && row[3]) {
+			MailStore *store = tracker_db_email_get_mbox_details (db_con, row[3]);
+
+			if (store) {
+				check_summary_file (db_con, row[2], store);
+				tracker_db_email_free_mail_store (store);
+			}
+		}
+	}
+
+	if (res) {
+		tracker_db_free_result (res);
+	}
+
+	g_slist_foreach (modest_config->imap_dirs, (GFunc) email_watch_directory, "ModestEmails");
+	g_slist_foreach (modest_config->pop_dirs, (GFunc) email_watch_directory, "ModestEmails");
+	g_slist_foreach (modest_config->maildir_dirs, (GFunc) email_watch_directory, "ModestEmails");
+}
+
+static gboolean
+modest_file_is_interesting (FileInfo *info)
+{
+	g_return_val_if_fail (info, FALSE);
+	g_return_val_if_fail (info->uri, FALSE);
+	g_return_val_if_fail (modest_config, FALSE);
+	g_return_val_if_fail (modest_config->mail_dir, FALSE);
+
+	/* maildir/pop/imap all have summary files (*.ev-summary.mmap or "summary.mmap") */
+	if ((strcmp (info->uri, "summary.mmap") == 0) || g_str_has_suffix (info->uri, "summary.mmap")) {
+		return TRUE;
+	} else {
+		return FALSE;
+	}
+
+	return FALSE;
+}
+
+
+gboolean
+tracker_email_index_file (DBConnection *db_con, FileInfo *info)
+{
+	gchar *file_name;
+
+	g_return_val_if_fail (db_con, FALSE);
+	g_return_val_if_fail (info, FALSE);
+
+	if (!modest_file_is_interesting (info))
+		return FALSE;
+
+	file_name = g_path_get_basename (info->uri);
+
+	tracker_debug ("indexing email summary %s", info->uri);
+
+	if (is_in_dir_imap (info->uri)) {
+		if (strcmp (file_name, "summary.mmap") == 0) {
+			index_mail_messages_by_summary_file (db_con, MAIL_TYPE_IMAP, info->uri,
+							     load_summary_file_meta_header_for_imap,
+							     load_mail_message_for_imap,
+							     skip_mail_message_for_imap,
+							     save_ondisk_email_message_for_imap);
+		}
+	} else
+
+	if (is_in_dir_pop (info->uri)) {
+		if (strcmp (file_name, "summary.mmap") == 0) {
+			index_mail_messages_by_summary_file (db_con, MAIL_TYPE_POP, info->uri,
+							     load_summary_file_meta_header_for_pop,
+							     load_mail_message_for_pop,
+							     skip_mail_message_for_pop,
+							     save_ondisk_email_message_for_pop);
+		}
+	} else
+
+	if (is_in_dir_maildir (info->uri)) {
+		if (strcmp (file_name, "summary.mmap") || g_str_has_suffix (info->uri, "summary.mmap")) {
+			index_mail_messages_by_summary_file (db_con, MAIL_TYPE_MAILDIR, info->uri,
+							     load_summary_file_meta_header_for_maildir,
+							     load_mail_message_for_maildir,
+							     skip_mail_message_for_maildir,
+							     save_ondisk_email_message_for_maildir);
+		}
+	}
+
+	g_free (file_name);
+
+	return TRUE;
+}
+
+const gchar *
+tracker_email_get_name (void)
+{
+	return "ModestEmails";
+}
+
+
+/********************************************************************************************
+ Private functions
+*********************************************************************************************/
+
+
+static void
+check_summary_file (DBConnection *db_con, const gchar *filename, MailStore *store)
+{
+	SummaryFile *summary = NULL;
+
+	g_return_if_fail (store);
+
+	if (open_summary_file (filename, &summary)) {
+		SummaryFileHeader *header;
+		gchar             *path;
+
+		header = NULL;
+
+		tracker_log ("Scanning summary file %s for junk", filename);
+
+		if (!load_summary_file_header (summary, &header)) {
+			free_summary_file (summary);
+			tracker_error ("ERROR: failed to open summary file %s", filename);
+			return;
+		}
+
+		if (store->type == MAIL_TYPE_IMAP) {
+			if (!load_summary_file_meta_header_for_imap (summary, header)) {
+				free_summary_file_header (header);
+				free_summary_file (summary);
+				tracker_error ("ERROR: failed to open summary header file %s", filename);
+				return;
+			}
+
+		} else if (store->type == MAIL_TYPE_POP) {
+			if (!load_summary_file_meta_header_for_pop (summary, header)) {
+				free_summary_file_header (header);
+				free_summary_file (summary);
+				tracker_error ("ERROR: failed to open summary header file %s", filename);
+				return;
+			}
+		} else if (store->type == MAIL_TYPE_MAILDIR) {
+			if (!load_summary_file_meta_header_for_pop (summary, header)) {
+				free_summary_file_header (header);
+				free_summary_file (summary);
+				tracker_error ("ERROR: failed to open summary header file %s", filename);
+				return;
+			}
+
+		} else {
+			tracker_error ("ERROR: summary file not supported");
+			free_summary_file_header (header);
+			free_summary_file (summary);
+			return;
+
+		}
+
+		path = tracker_db_email_get_mbox_path (db_con, filename);
+		tracker_db_email_set_message_counts (db_con, path, store->mail_count, header->junk_count, header->deleted_count);
+		g_free (path);
+
+		free_summary_file_header (header);
+		free_summary_file (summary);
+	}
+}
+
+
+
+
+static GSList*
+moredir (char *name, char *lastname, GSList *list) {
+	DIR *dir = opendir (name);
+	struct dirent *d;
+
+	if (dir) {
+		while ( (d = readdir(dir)) ) {
+			struct stat st;
+			if (strcmp (d->d_name, ".") != 0 && strcmp (d->d_name, "..") != 0) {
+			  char *tmp = g_build_filename (name, d->d_name, NULL);
+			  if (stat(tmp, &st) == 0 && S_ISDIR(st.st_mode))
+				list = moredir (tmp, name, list);
+			  g_free (tmp);
+
+			  if ((strcmp (d->d_name, "summary.mmap") == 0) || g_str_has_suffix (d->d_name, "summary.mmap")) {
+				tracker_log ("Adding mail_dir: %s\n", name);
+				list = g_slist_prepend (list, g_strdup (name));
+
+				/* Question from Philip Van Hoof:
+				 * I think we can return here, if a maildir's root 
+				 * has two summary files, for two subdirs, only
+				 * monitoring the root once should suffice, I think 
+				 *
+				 * Example FS structure:
+				 *
+				 * MyMailDirRoot <- Added to maildir_dirs twice (two summary files)
+				 * +- MyFolder1
+				 * |   +- cur    <- Actual settled E-mails
+				 * |   +- new    <- Recently created E-mails
+				 * |   `- tmp    <- Being created E-mails
+				*  |
+				 * +- MyFolder2  <- Added to maildir_dirs once (one summary file)
+				 * |   +- MyFolder3.ev-summary.mmap <- to monitor
+				 * |   +- MyFolder3
+				 * |   |   +- cur
+				 * |   |   +- new
+				 * |   |   `- tmp
+				 * |   |
+				 * |   +- cur
+				 * |   +- new
+				 * |   `- tmp
+				 * +- MyFolder1.ev-summary.mmap <- to monitor
+				 * `- MyFolder2.ev-summary.mmap <- to monitor
+				*/
+			  }
+			}
+		}
+		closedir(dir);
+	}
+	return list;
+}
+
+static gboolean
+load_modest_config (ModestConfig **conf)
+{
+	char		*dir_imap, *dir_pop, *dir_maildir;
+	ModestConfig	*m_conf;
+
+	if (*conf) {
+		free_modest_config (*conf);
+	}
+
+	*conf = g_slice_new0 (ModestConfig);
+	m_conf = *conf;
+
+	m_conf->mail_dir = g_build_filename (g_get_home_dir (), MODEST_MAIL_DIR_S, NULL);
+
+	dir_imap = g_build_filename (m_conf->mail_dir, "imap", NULL);
+	dir_pop = g_build_filename (m_conf->mail_dir, "pop", NULL);
+	dir_maildir = g_build_filename (g_get_home_dir (), MODEST_LOCAL_MAIL_DIR_S, NULL);
+
+	tracker_log ("Checking for Modest email accounts...");
+
+	m_conf->imap_dirs = moredir (dir_imap, m_conf->mail_dir, m_conf->imap_dirs);
+	m_conf->pop_dirs = moredir (dir_pop, m_conf->mail_dir, m_conf->pop_dirs);
+
+	/* TODO: Future support
+	 * m_conf->maildir_dirs must be updated whenever an MMC card gets inserted */
+
+	m_conf->maildir_dirs = moredir (dir_maildir, dir_maildir, m_conf->maildir_dirs);
+
+	g_free (dir_imap);
+	g_free (dir_pop);
+	g_free (dir_maildir);
+
+	return TRUE;
+}
+
+
+
+static gboolean
+is_in_dir_imap (const gchar *path)
+{
+	g_return_val_if_fail (path, FALSE);
+	return strstr (path, G_DIR_SEPARATOR_S "imap") != NULL;
+}
+
+
+static gboolean
+is_in_dir_maildir (const gchar *path)
+{
+	g_return_val_if_fail (path, FALSE);
+	return strstr (path, "ev-summary.mmap") != NULL;
+}
+
+
+static gboolean
+is_in_dir_pop (const gchar *path)
+{
+	g_return_val_if_fail (path, FALSE);
+	return strstr (path, G_DIR_SEPARATOR_S "pop" G_DIR_SEPARATOR_S) != NULL;
+}
+
+
+
+/* From RFC 2396 2.4.3, the characters that should always be encoded */
+static const char url_encoded_char[] = {
+	1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  /* 0x00 - 0x0f */
+	1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  /* 0x10 - 0x1f */
+	1, 0, 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  /*  ' ' - '/'  */
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0,  /*  '0' - '?'  */
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  /*  '@' - 'O'  */
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0,  /*  'P' - '_'  */
+	1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  /*  '`' - 'o'  */
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 1,  /*  'p' - 0x7f */
+	1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+	1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+	1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+	1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+	1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+	1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+	1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+	1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1
+};
+
+static void
+append_url_encoded (GString *str, const char *in, const char *extra_enc_chars)
+{
+	const unsigned char *s = (const unsigned char *)in;
+	while (*s) {
+		if (url_encoded_char[*s] ||
+		    (extra_enc_chars && strchr (extra_enc_chars, *s)))
+			g_string_append_printf (str, "%%%02x", (int)*s++);
+		else
+			g_string_append_c (str, *s++);
+	}
+}
+
+char *
+url_encode (const char *part, const char *escape_extra)
+{
+	GString *str;
+	char *encoded;
+	g_return_val_if_fail (part != NULL, NULL);
+	str = g_string_new (NULL);
+	append_url_encoded (str, part, escape_extra);
+	encoded = str->str;
+	g_string_free (str, FALSE);
+	return encoded;
+}
+
+char *
+file_util_safe_filename (const char *name)
+{
+#ifdef G_OS_WIN32
+	const char *unsafe_chars = "/?()'*<>:\"\\|";
+#else
+	const char *unsafe_chars = "/?()'*";
+#endif
+	if (name == NULL)
+		return NULL;
+	return url_encode(name, unsafe_chars);
+}
+
+#define DATA_CACHE_BITS (6)
+#define DATA_CACHE_MASK ((1<<DATA_CACHE_BITS)-1)
+
+static char *
+data_cache_path(const char *path, const char *key)
+{
+	char *dir, *real, *tmp;
+	guint32 hash;
+	hash = g_str_hash(key);
+	hash = (hash>>5)&DATA_CACHE_MASK;
+	dir = alloca(strlen(path) + 8);
+	sprintf(dir, "%s/%02x", path, hash);
+	tmp = file_util_safe_filename(key);
+	real = g_strdup_printf("%s/%s", dir, tmp);
+	g_free(tmp);
+	return real;
+}
+
+
+char *maildir_get_filename (const gchar *fpath, const gchar *uid)
+{
+	char *name = g_strdup (uid);
+	gint len = strlen (name);
+	gchar *cur = g_strdup_printf("%s/cur", fpath);
+	DIR *dir; struct dirent *d;
+	dir = opendir(cur);
+
+	if (dir) {
+		while ( (d = readdir(dir)) ) {
+			char *nname = g_strdup_printf ("%s/%s", cur, d->d_name);
+			char *ptr = strstr (nname, "!");
+
+			if (!ptr)
+				strstr (nname, ":");
+			if (ptr)
+				len = (ptr - nname);
+			if (!g_ascii_strncasecmp (nname, name, len)) {
+				g_free (name);
+				name = nname;
+				break;
+			}
+			g_free (nname);
+		}
+		closedir(dir);
+	}
+	g_free (cur);
+
+	return name;
+}
+
+static void
+index_mail_messages_by_summary_file (DBConnection                 *db_con,
+				     MailType                     mail_type,
+				     const gchar                  *summary_file_path,
+				     LoadSummaryFileMetaHeaderFct load_meta_header,
+				     LoadMailMessageFct           load_mail,
+				     SkipMailMessageFct           skip_mail,
+				     SaveOnDiskMailMessageFct     save_ondisk_mail)
+{
+	SummaryFile *summary = NULL;
+
+	if (!tracker->is_running)
+		return; 
+
+	if (open_summary_file (summary_file_path, &summary)) {
+		SummaryFileHeader *header;
+		gint32            mail_count, junk_count, delete_count;
+		gchar             *dir;
+
+		header = NULL;
+
+		if (!load_summary_file_header (summary, &header)) {
+			free_summary_file (summary);
+			return;
+		}
+
+		if (!(*load_meta_header) (summary, header)) {
+			free_summary_file_header (header);
+			free_summary_file (summary);
+			return;
+		}
+
+		if (mail_type != MAIL_TYPE_MAILDIR)
+			dir = g_path_get_dirname (summary->path);
+		else {
+			gchar *tdir = g_strdup (summary->path);
+			char *part = strstr (tdir, "ev-summary.mmap");
+			/**
+			 * home/user/.modest/local_folders/New folder/
+			 * home/user/.modest/local_folders/New folder/cur/
+			 * home/user/.modest/local_folders/New folder/new/
+			 * home/user/.modest/local_folders/New folder/tmp/
+			 * home/user/.modest/local_folders/New folder.ev-summary.mmap <--
+			 **/
+			if (part) {
+				part--;
+				*part = '\0';
+				dir = tdir;
+			} else {
+				dir = g_path_get_dirname (summary->path);
+				g_free (tdir);
+			}
+		}
+
+		/* check summary file is registered */
+		if (tracker_db_email_get_mbox_id (db_con, dir) == -1) {
+			char *uri_prefix = NULL;
+
+			if (mail_type == MAIL_TYPE_IMAP || mail_type == MAIL_TYPE_POP) {
+				const gchar *pos_folders = strstr (dir, G_DIR_SEPARATOR_S "folders" G_DIR_SEPARATOR_S);
+				char *piece;
+				char *tdir = g_strdup (dir);
+				char *loc = strstr (tdir, MODEST_MAIL_DIR_S);
+				char *tloc;
+
+				loc += strlen (MODEST_MAIL_DIR_S) + 1;
+				loc = strchr (loc, '/'); loc++; /* word imap|pop */
+				tloc = strchr (loc, '/'); /* word account name */
+				if (tloc)
+					loc = tloc;
+				loc++; *loc = '\0';
+
+				char *tmp = g_build_filename (tdir, "url_string", NULL);
+				FILE *f = fopen (tmp, "r");
+				if (f) {
+					char str[4000];
+					memset (str, 0, 4000);
+					fgets (str, 4000, f);
+					piece = g_strndup (str, strlen (str));
+				} else
+					piece = g_strdup ("unknown://location/");
+				g_free (tmp);
+				g_free (tdir);
+
+				if (pos_folders) {
+					size_t len_pos_folders = strlen (pos_folders);
+					if (len_pos_folders > 9) {
+						gchar *uri_dir, *clean_uri_dir;
+						pos_folders += 9;
+						uri_dir = NULL;
+						if (pos_folders)
+							uri_dir = g_strdup (pos_folders);
+						clean_uri_dir = NULL;
+						if (uri_dir) {
+							gchar *tmp_str = tracker_string_replace (uri_dir, "subfolders/", NULL);
+							clean_uri_dir = tracker_string_replace (tmp_str, "folders/", NULL);
+							g_free (tmp_str);
+							g_free (uri_dir);
+						}
+						if (clean_uri_dir) {
+							uri_prefix = g_strdup_printf ("%s/%s/", piece, clean_uri_dir);
+							g_free (clean_uri_dir);
+						} else
+							uri_prefix = g_strdup (piece);
+					} else
+						uri_prefix = g_strdup (piece);
+				} else
+					uri_prefix = g_strdup (piece);
+
+				g_free (piece);
+
+			} else if (mail_type == MAIL_TYPE_MAILDIR)
+				uri_prefix = g_strdup_printf ("maildir:/%s/", dir);
+			else 
+				uri_prefix = g_strdup ("unknown://location/");
+
+			tracker_db_email_register_mbox (db_con, MAIL_APP_MODEST, mail_type, dir, summary_file_path, uri_prefix);
+			g_free (uri_prefix);
+		}
+
+
+		MailStore *store = tracker_db_email_get_mbox_details (db_con, dir);
+
+		if (!store) {
+			tracker_error ("ERROR: could not retrieve store for file %s", dir);
+			free_summary_file (summary);
+			free_summary_file_header (header);
+
+			g_free (dir);
+			return;
+		}
+
+		tracker_debug ("Number of existing messages in %s are %d, %d junk, %d deleted and header totals are %d, %d, %d", dir,
+				store->mail_count, store->junk_count, store->delete_count, header->saved_count, header->junk_count, header->deleted_count);
+
+		tracker->mbox_count++;
+		tracker_dbus_send_index_progress_signal ("Emails", dir);
+
+		if (header->saved_count > store->mail_count) {
+			/* assume new emails received */
+
+			gint i;
+
+			/* skip already indexed emails */
+			for (i = 0; i < store->mail_count; i++) {
+				if (!(*skip_mail) (summary)) {
+					tracker_error ("ERROR: skipping email no. %d in summary file", i+1);
+					tracker_db_email_free_mail_store (store);
+					free_summary_file (summary);
+					free_summary_file_header (header);
+					tracker->mbox_processed++;
+					g_free (dir);
+					return;
+				}
+			}
+
+			mail_count = 0;
+			junk_count = 0;
+			delete_count = 0;
+
+			/* now we will read the new emails */
+			for (i = store->mail_count; i < header->saved_count; i++) {
+				MailMessage *mail_msg = NULL;
+
+				mail_count++;
+				tracker_debug ("processing email no. %d / %" G_GINT32_FORMAT, store->mail_count + 1, header->saved_count);
+
+				if (!(*load_mail) (summary, &mail_msg)) {
+					tracker_error ("ERROR: loading email no. %d in summary file", mail_count);
+					tracker_db_email_free_mail_store (store);
+					free_summary_file (summary);
+					free_summary_file_header (header);
+					tracker->mbox_processed++;
+					g_free (dir);
+					return;
+				}
+
+				
+
+				if (mail_type == MAIL_TYPE_IMAP) {
+					gchar *sum_file_dir = g_path_get_dirname (summary->path);
+					mail_msg->path = g_strdup_printf ("%s%s%s.", sum_file_dir, G_DIR_SEPARATOR_S, mail_msg->uid);
+					g_free (sum_file_dir);
+				} else if (mail_type == MAIL_TYPE_POP) {
+					gchar *sum_file_dir = g_path_get_dirname (summary->path);
+					mail_msg->path = data_cache_path (sum_file_dir, mail_msg->uid);
+					g_free (sum_file_dir);
+				} else if (mail_type == MAIL_TYPE_MAILDIR) {
+					maildir_get_filename (dir, mail_msg->uid);
+				} else
+					mail_msg->path = NULL;
+
+				mail_msg->uri = g_strconcat (store->uri_prefix, mail_msg->uid, NULL);
+
+				mail_msg->store = store;
+
+				if (!(*save_ondisk_mail) (db_con, mail_msg)) {
+					tracker_log ("WARNING: Message, or message parts, could not be found locally - if you are using IMAP make sure you have selected the \"copy folder content locally for offline operation\" option in Modest");
+					/* we do not have all infos but we still save them */
+					if (!tracker_db_email_save_email (db_con, mail_msg, MAIL_APP_MODEST)) {
+						tracker_log ("Failed to save email");
+					}
+				}
+
+				if (mail_msg->junk) {
+					junk_count++;
+				}
+
+				if (mail_msg->deleted) {
+					delete_count++;
+				}
+
+				email_free_mail_file (mail_msg->parent_mail_file);
+				email_free_mail_message (mail_msg);
+
+				if (!tracker_cache_process_events (db_con->data, TRUE)) {
+					tracker->status = STATUS_SHUTDOWN;
+					tracker->shutdown = TRUE;
+					tracker_dbus_send_index_status_change_signal ();
+					return;
+				}
+
+				if (tracker_db_regulate_transactions (db_con->data, 500)) {
+
+					if (tracker->index_count % 1000 == 0) {
+						tracker_db_end_index_transaction (db_con->data);
+						tracker_db_refresh_all (db_con->data);
+						tracker_db_start_index_transaction (db_con->data);
+					}
+					
+					tracker_dbus_send_index_progress_signal ("Emails", dir);
+								
+				}
+
+			
+			}
+
+			tracker_log ("No. of new emails indexed in summary file %s is %d, %d junk, %d deleted", dir, mail_count, junk_count, delete_count);
+
+			tracker_db_email_set_message_counts (db_con, dir, store->mail_count, store->junk_count, store->delete_count);
+
+		} else {
+			/* schedule check for junk */
+			tracker_db_email_flag_mbox_junk (db_con, dir);
+		}
+
+		tracker->mbox_processed++;
+		tracker_dbus_send_index_progress_signal ("Emails", dir);
+
+		tracker_db_email_free_mail_store (store);
+		free_summary_file (summary);
+		free_summary_file_header (header);
+
+		g_free (dir);
+	}
+}
+
+
+
+
+static gboolean
+open_summary_file (const gchar *path, SummaryFile **summary)
+{
+	gint fd;
+	FILE *f;
+
+	g_return_val_if_fail (path, FALSE);
+
+	if (!tracker_file_is_indexable (path)) {
+		return FALSE;
+	}
+
+	if (*summary) {
+		free_summary_file (*summary);
+		*summary = NULL;
+	}
+
+	fd = tracker_file_open (path, TRUE);
+
+	if (fd == -1) {
+		return FALSE;
+	}
+
+	f = fdopen (fd, "r");
+	if (!f) {
+		tracker_file_close (fd, TRUE);
+		return FALSE;
+	}
+
+	*summary = g_slice_new0 (SummaryFile);
+	(*summary)->f = f;
+	(*summary)->path = g_strdup (path);
+
+	return TRUE;
+}
+
+
+static void
+free_summary_file (SummaryFile *summary)
+{
+	if (!summary) {
+		return;
+	}
+
+	fclose (summary->f);
+
+	g_free (summary->path);
+	g_slice_free (SummaryFile, summary);
+}
+
+
+static gboolean
+load_summary_file_header (SummaryFile *summary, SummaryFileHeader **header)
+{
+	SummaryFileHeader *h;
+	FILE              *f;
+
+	g_return_val_if_fail (summary, FALSE);
+
+	if (*header) {
+		free_summary_file_header (*header);
+	}
+
+	*header = g_slice_new0 (SummaryFileHeader);
+
+	h = *header;
+
+	h->uri_prefix = NULL;
+
+	f = summary->f;
+
+
+	if (!decode_gint32 (f, &h->version)) {
+		goto error;
+	}
+
+	tracker_debug ("summary.version = %d", h->version);
+
+	if (h->version > 0xff && (h->version & 0xff) < 12) {
+		tracker_error ("ERROR: summary file header version too low");
+		goto error;
+	}
+
+	h->legacy = !(h->version < 0x100 && h->version >= 13);
+
+	if (h->legacy) {
+		tracker_debug ("WARNING: summary file is a legacy version");
+	}
+
+
+	if (!decode_gint32 (f, &h->flags) ||
+	    !decode_gint32 (f, &h->nextuid) ||
+	    !decode_time_t (f, &h->time) ||
+	    !decode_gint32 (f, &h->saved_count)) {
+		goto error;
+	}
+
+	tracker_debug ("summary.flags = %d", h->flags);
+	tracker_debug ("summary.nextuid = %d", h->nextuid);
+	tracker_debug ("summary.time = %d", h->time);
+	tracker_debug ("summary.count = %" G_GINT32_FORMAT, h->saved_count);
+
+	if (!h->legacy) {
+		if (!decode_gint32 (f, &h->unread_count) ||
+		    !decode_gint32 (f, &h->deleted_count) ||
+		    !decode_gint32 (f, &h->junk_count)) {
+			goto error;
+		}
+	}
+
+	tracker_debug ("summary.Unread = %d", h->unread_count);
+	tracker_debug ("summary.deleted = %d", h->deleted_count);
+	tracker_debug ("summary.junk = %d", h->junk_count);
+
+	return TRUE;
+
+ error:
+	free_summary_file_header (*header);
+	*header = NULL;
+
+	return FALSE;
+}
+
+
+static void
+free_summary_file_header (SummaryFileHeader *header)
+{
+	if (!header) {
+		return;
+	}
+
+	if (header->uri_prefix) {
+		g_free (header->uri_prefix);
+	}
+
+	g_slice_free (SummaryFileHeader, header);
+}
+
+
+static gboolean
+load_summary_file_meta_header_maildir (SummaryFile *summary, SummaryFileHeader *header)
+{
+	FILE    *f;
+
+	g_return_val_if_fail (summary, FALSE);
+	g_return_val_if_fail (header, FALSE);
+
+	f = summary->f;
+
+	/* check for legacy version */
+	if (header->version != 0x30c) {
+		gint32 version;
+
+		if (!decode_gint32 (f, &version)) {
+			return FALSE;
+		}
+
+		if (version < 0) {
+			tracker_error ("ERROR: summary file version too low");
+			return FALSE;
+		}
+
+		/* Right now we only support summary versions 1 through 3 */
+		if (version > 3) {
+			tracker_error ("ERROR: reported summary version (%" G_GINT32_FORMAT ") is too new", version);
+			return FALSE;
+		}
+
+		if (version == 2) {
+			if (!skip_gint32_decoding (f)) {
+				return FALSE;
+			}
+		}
+
+	} 
+
+	return TRUE;
+}
+
+
+static gboolean
+load_summary_file_meta_header_pop (SummaryFile *summary, SummaryFileHeader *header)
+{
+	FILE    *f;
+
+	g_return_val_if_fail (summary, FALSE);
+	g_return_val_if_fail (header, FALSE);
+
+	f = summary->f;
+
+	return TRUE;
+}
+
+static gboolean
+load_summary_file_meta_header_for_imap (SummaryFile *summary, SummaryFileHeader *header)
+{
+	FILE    *f;
+	guint32 dummy0;
+
+	g_return_val_if_fail (summary, FALSE);
+	g_return_val_if_fail (header, FALSE);
+
+	f = summary->f;
+
+	/* check for legacy version */
+	if (header->version != 0x30c) {
+		gint32 version, dummy1;
+
+		if (!decode_gint32 (f, &version)) {
+			return FALSE;
+		}
+
+		if (version < 0) {
+			tracker_error ("ERROR: summary file version too low");
+			return FALSE;
+		}
+
+		/* Right now we only support summary versions 1 through 3 */
+		if (version > 3) {
+			tracker_error ("ERROR: reported summary version (%" G_GINT32_FORMAT ") is too new", version);
+			return FALSE;
+		}
+
+		if (version == 2) {
+			if (!skip_gint32_decoding (f)) {
+				return FALSE;
+			}
+		}
+
+		/* validity */
+		if (!decode_gint32 (f, &dummy1)) {
+			return FALSE;
+		}
+	} else {
+		/* validity */
+		if (!decode_guint32 (f, &dummy0)) {
+			return FALSE;
+		}
+	}
+
+	return TRUE;
+}
+
+
+static gboolean
+load_summary_file_meta_header_for_pop (SummaryFile *summary, SummaryFileHeader *header)
+{
+	return load_summary_file_meta_header_pop (summary, header);
+}
+
+static gboolean
+load_summary_file_meta_header_for_maildir (SummaryFile *summary, SummaryFileHeader *header)
+{
+	return load_summary_file_meta_header_maildir (summary, header);
+}
+
+
+static gboolean
+load_mail_message_for_imap (SummaryFile *summary, MailMessage **mail_msg)
+{
+	return do_load_mail_message_for_imap (summary, mail_msg, TRUE);
+}
+
+static gboolean
+load_mail_message_for_maildir (SummaryFile *summary, MailMessage **mail_msg)
+{
+	return do_load_mail_message_for_maildir (summary, mail_msg, FALSE);
+}
+
+static gboolean
+load_mail_message_for_pop (SummaryFile *summary, MailMessage **mail_msg)
+{
+	return do_load_mail_message_for_pop (summary, mail_msg, FALSE);
+}
+
+
+static gboolean
+do_load_mail_message_for_imap (SummaryFile *summary, MailMessage **mail_msg, gboolean do_skipping_of_content_info)
+{
+	guint32 server_flags;
+
+	g_return_val_if_fail (summary, FALSE);
+
+	if (*mail_msg) {
+		email_free_mail_message (*mail_msg);
+	}
+
+	*mail_msg = email_allocate_mail_message ();
+
+	if (!load_mail_message (summary, *mail_msg)) {
+		goto error;
+	}
+
+	if (!decode_guint32 (summary->f, &server_flags)) {
+		goto error;
+	}
+
+	if (do_skipping_of_content_info) {
+		if (!skip_loading_content_info (summary)) {
+			goto error;
+		}
+	}
+
+	return TRUE;
+
+ error:
+	email_free_mail_message (*mail_msg);
+	*mail_msg = NULL;
+	return FALSE;
+}
+
+
+
+static gboolean
+do_load_mail_message_generic (SummaryFile *summary, MailMessage **mail_msg, gboolean do_skipping_of_content_info)
+{
+	g_return_val_if_fail (summary, FALSE);
+
+	if (*mail_msg) {
+		email_free_mail_message (*mail_msg);
+	}
+
+	*mail_msg = email_allocate_mail_message ();
+
+	if (!load_mail_message (summary, *mail_msg)) {
+		goto error;
+	}
+
+	if (do_skipping_of_content_info) {
+		if (!skip_loading_content_info (summary)) {
+			goto error;
+		}
+	}
+
+	return TRUE;
+
+ error:
+	email_free_mail_message (*mail_msg);
+	*mail_msg = NULL;
+	return FALSE;
+}
+
+
+
+static gboolean
+do_load_mail_message_for_pop (SummaryFile *summary, MailMessage **mail_msg, gboolean do_skipping_of_content_info)
+{
+
+	return do_load_mail_message_generic (summary, mail_msg, do_skipping_of_content_info);
+}
+
+
+
+static gboolean
+do_load_mail_message_for_maildir (SummaryFile *summary, MailMessage **mail_msg, gboolean do_skipping_of_content_info)
+{
+	return do_load_mail_message_generic (summary, mail_msg, do_skipping_of_content_info);
+}
+
+static gboolean
+load_mail_message (SummaryFile *summary, MailMessage *mail_msg)
+{
+	FILE    *f;
+	guint32	flags, size, count;
+	time_t  date_sent, date_received;
+	gchar   *uid, *to, *cc, *mlist;
+
+	g_return_val_if_fail (summary, FALSE);
+	g_return_val_if_fail (mail_msg, FALSE);
+
+	f = summary->f;
+
+	if (!decode_string (f, &uid) ||
+	    !decode_guint32 (f, &size) ||  /* Size and flags are reversed in tny */
+	    !decode_guint32 (f, &flags) ||  /* Size and flags are reversed in tny */
+	    !decode_time_t (f, &date_sent) ||
+	    !decode_time_t (f, &date_received) ||
+	    !decode_string (f, &mail_msg->subject) ||
+	    !decode_string (f, &mail_msg->from) ||
+	    !decode_string (f, &to) ||
+	    !decode_string (f, &cc) ||
+	    !decode_string (f, &mlist)) /* mlist will be an empty string in tny */
+	{
+
+		return FALSE;
+	}
+
+	g_free (mlist);
+
+
+	/* This is pointless, it's not always an int as a string*/
+	mail_msg->id = strtoul (uid, NULL, 10);
+
+	/* Only this really makes sense */
+	mail_msg->uid = uid; /* g_free (uid); */
+
+	if ((flags & MODEST_MESSAGE_DELETED) == MODEST_MESSAGE_DELETED) {
+		mail_msg->deleted = TRUE;
+	}
+
+	if ((flags & MODEST_MESSAGE_EXPUNGED) == MODEST_MESSAGE_EXPUNGED) {
+		mail_msg->deleted = TRUE;
+	}
+
+	mail_msg->junk = FALSE;
+
+	mail_msg->date = (long) date_received;
+
+	mail_msg->to = add_persons_from_internet_address_list_string_parsing (NULL, to);
+	mail_msg->cc = add_persons_from_internet_address_list_string_parsing (NULL, cc);
+
+	g_free (to);
+	g_free (cc);
+
+	skip_gint32_decoding (f);	/* mi->message_id.id.part.hi */
+	skip_gint32_decoding (f);	/* mi->message_id.id.part.lo */
+
+	/* references */
+	if (decode_guint32 (f, &count) && count <= 500) {
+		guint32 i;
+		for (i = 0; i < count; i++) {
+			skip_gint32_decoding (f);	/* mi->references->references[i].id.part.hi */
+			skip_gint32_decoding (f);	/* mi->references->references[i].id.part.lo */
+		}
+	} else {
+		return FALSE;
+	}
+
+	/* user flags */
+	if (decode_guint32 (f, &count) && count <= 500) {
+		guint32 i;
+		for (i = 0; i < count; i++) {
+			skip_string_decoding (f);	/* a flag */
+		}
+	} else {
+		return FALSE;
+	}
+
+	/* user tags */
+	if (decode_guint32 (f, &count) && count <= 500) {
+		guint32 i;
+		for (i = 0; i < count; i++) {
+			skip_string_decoding (f);	/* tag name */
+			skip_string_decoding (f);	/* tag value */
+		}
+	} else {
+		return FALSE;
+	}
+
+	return TRUE;
+}
+
+
+static gboolean
+skip_mail_message_for_imap (SummaryFile *summary)
+{
+	return do_skip_mail_message_for_imap (summary, TRUE);
+}
+
+
+static gboolean
+skip_mail_message_for_pop (SummaryFile *summary)
+{
+	return do_skip_mail_message_for_pop (summary, FALSE);
+}
+
+static gboolean
+skip_mail_message_for_maildir (SummaryFile *summary)
+{
+	return do_skip_mail_message_for_maildir (summary, FALSE);
+}
+
+
+static gboolean
+do_skip_mail_message_for_imap (SummaryFile *summary, gboolean do_skipping_of_content_info)
+{
+	g_return_val_if_fail (summary, FALSE);
+
+	if (!skip_mail_message (summary)) {
+		return FALSE;
+	}
+
+	if (!skip_guint32_decoding (summary->f)) {
+		return FALSE;
+	}
+
+	if (do_skipping_of_content_info) {
+		if (!skip_loading_content_info (summary)) {
+			return FALSE;
+		}
+	}
+
+	return TRUE;
+}
+
+
+
+static gboolean
+do_skip_mail_message_for_pop (SummaryFile *summary, gboolean do_skipping_of_content_info)
+{
+	g_return_val_if_fail (summary, FALSE);
+
+	if (!skip_mail_message (summary)) {
+		return FALSE;
+	}
+
+	if (do_skipping_of_content_info) {
+		if (!skip_loading_content_info (summary)) {
+			return FALSE;
+		}
+	}
+
+	return TRUE;
+}
+
+
+
+static gboolean
+do_skip_mail_message_for_maildir (SummaryFile *summary, gboolean do_skipping_of_content_info)
+{
+	g_return_val_if_fail (summary, FALSE);
+
+	if (!skip_mail_message (summary)) {
+		return FALSE;
+	}
+
+	if (do_skipping_of_content_info) {
+		if (!skip_loading_content_info (summary)) {
+			return FALSE;
+		}
+	}
+
+	return TRUE;
+}
+
+
+
+
+static gboolean
+skip_mail_message (SummaryFile *summary)
+{
+	FILE    *f;
+	guint32 count;
+	time_t  tt;
+	guint   n;
+
+	g_return_val_if_fail (summary, FALSE);
+
+	f = summary->f;
+
+	if (!skip_string_decoding (f))
+		return FALSE;
+
+	if (!decode_guint32 (f, &n))
+		return FALSE;
+
+	if (!decode_guint32 (f, &n))
+		return FALSE;
+
+	if (!decode_time_t (f, &tt))
+		return FALSE;
+
+	if (!decode_time_t (f, &tt))
+		return FALSE;
+
+	if (!skip_string_decoding (f))
+		return FALSE;
+
+	if (!skip_string_decoding (f))
+		return FALSE;
+
+	if (!skip_string_decoding (f))
+		return FALSE;
+
+	if (!skip_string_decoding (f))
+		return FALSE;
+
+	if (!skip_string_decoding (f))
+		return FALSE;
+
+
+	skip_gint32_decoding (f);	/* mi->message_id.id.part.hi */
+	skip_gint32_decoding (f);	/* mi->message_id.id.part.lo */
+
+	/* references , always 0 items in tny */
+	if (decode_guint32 (f, &count) && count <= 500) {
+		guint32 i;
+		for (i = 0; i < count; i++) {
+			skip_gint32_decoding (f);	/* mi->references->references[i].id.part.hi */
+			skip_gint32_decoding (f);	/* mi->references->references[i].id.part.lo */
+		}
+	} else {
+		return FALSE;
+	}
+
+	/* user flags , always 0 items in tny */
+	if (decode_guint32 (f, &count) && count <= 500) {
+		guint32 i;
+		for (i = 0; i < count; i++) {
+			skip_string_decoding (f);	/* a flag */
+		}
+	} else {
+		return FALSE;
+	}
+
+	/* user tags , always 0 items in tny */
+	if (decode_guint32 (f, &count) && count <= 500) {
+		guint32 i;
+		for (i = 0; i < count; i++) {
+			skip_string_decoding (f);	/* tag name */
+			skip_string_decoding (f);	/* tag value */
+		}
+	} else {
+		return FALSE;
+	}
+
+	return TRUE;
+}
+
+
+static inline gboolean
+skip_over_mail (FILE *f)
+{
+	return (skip_string_decoding (f) &&  /* uid */
+		skip_guint32_decoding (f) && /* size switched with flags in tny */
+		skip_guint32_decoding (f) && /* flags switched with size in tny */
+		skip_time_t_decoding (f) &&  /* date_sent */
+		skip_time_t_decoding (f) &&  /* date_received */
+		skip_string_decoding (f) &&  /* subject */
+		skip_string_decoding (f) &&  /* from */
+		skip_string_decoding (f) &&  /* to */
+		skip_string_decoding (f) &&  /* cc */
+		skip_string_decoding (f));   /* mlist? */
+}
+
+
+static gboolean
+skip_loading_content_info (SummaryFile *summary)
+{
+	guint32 count, i;
+
+	g_return_val_if_fail (summary, FALSE);
+
+	if (!do_skip_loading_content_info (summary)) {
+		return FALSE;
+	}
+
+	if (!decode_guint32 (summary->f, &count)) {
+		return FALSE;
+	}
+
+	if (count > 500) {
+		return FALSE;
+	}
+
+	for (i = 0; i < count; i++) {
+		if (!skip_loading_content_info (summary)) {
+			return FALSE;
+		}
+	}
+
+	return TRUE;
+}
+
+
+static gboolean
+do_skip_loading_content_info (SummaryFile *summary)
+{
+	FILE    *f;
+	guint32	count;
+	guint32 doit = 0;
+
+	g_return_val_if_fail (summary, FALSE);
+
+	f = summary->f;
+
+	if (!decode_guint32 (f, &doit))
+		return FALSE;
+
+	if (!doit)
+		return TRUE;
+
+	skip_token_decoding (f);	/* type */
+	skip_token_decoding (f);	/* subtype */
+
+	if (decode_guint32 (f, &count) && count <= 500) {
+		guint32 i;
+		for (i = 0; i < count; i++) {
+			skip_token_decoding (f);	/* name */
+			skip_token_decoding (f);	/* value */
+		}
+	} else {
+		return FALSE;
+	}
+
+	if (!skip_token_decoding (f) ||		/* id */
+	    !skip_token_decoding (f) ||		/* description */
+	    !skip_token_decoding (f) ||		/* encoding */
+	    !decode_guint32 (f, &count)) {	/* size */
+		return FALSE;
+	}
+
+	return TRUE;
+}
+
+
+static gboolean
+save_ondisk_email_message_for_imap (DBConnection *db_con, MailMessage *mail_msg)
+{
+	return do_save_ondisk_email_message_generic (db_con, mail_msg);
+}
+
+
+static gboolean
+save_ondisk_email_message_for_pop (DBConnection *db_con, MailMessage *mail_msg)
+{
+	return do_save_ondisk_email_message_generic (db_con, mail_msg);
+}
+
+static gboolean
+save_ondisk_email_message_for_maildir (DBConnection *db_con, MailMessage *mail_msg)
+{
+	return do_save_ondisk_email_message_generic (db_con, mail_msg);
+}
+
+static gboolean
+do_save_ondisk_email_message_generic (DBConnection *db_con, MailMessage *mail_msg)
+{
+	g_return_val_if_fail (db_con, FALSE);
+	g_return_val_if_fail (mail_msg, FALSE);
+
+	tracker_log ("Trying to index mail \"%s\"", mail_msg->uri);
+
+	if (!do_save_ondisk_email_message (db_con, mail_msg)) {
+		tracker_log ("Indexing mail without body nor attachment parsing \"%s\"", mail_msg->uri);
+		tracker_db_email_save_email (db_con, mail_msg, MAIL_APP_MODEST);
+	} else {
+		tracker_log ("Simple index of mail \"%s\" finished", mail_msg->uri);
+	}
+
+
+	return TRUE;
+
+}
+
+static void
+find_attachment (GMimeObject *obj, gpointer data) 
+{
+	/* For now we don't want to do anything with attachments on the device */
+	return;
+}
+
+static gboolean
+do_save_ondisk_email_message (DBConnection *db_con, MailMessage *mail_msg)
+{
+	g_return_val_if_fail (db_con, FALSE);
+	g_return_val_if_fail (mail_msg, FALSE);
+
+	if (mail_msg->path && g_file_test (mail_msg->path, G_FILE_TEST_EXISTS) && tracker_file_is_indexable (mail_msg->path)) {
+		/* we have downloaded the mail message on disk so we can fully index it. */
+		MailMessage *mail_msg_on_disk = NULL;
+
+		/* The last argument is a function pointer for implementing 
+		 * fetching the attachments and indexing them */
+
+		mail_msg_on_disk = email_parse_mail_message_by_path (MAIL_APP_MODEST,
+				mail_msg->path, NULL, NULL, find_attachment);
+
+		if (mail_msg_on_disk && mail_msg_on_disk->parent_mail_file) {
+
+			mail_msg_on_disk->parent_mail_file->next_email_offset = 0;
+			mail_msg_on_disk->uri = g_strdup (mail_msg->uri);
+			mail_msg_on_disk->store = mail_msg->store;
+
+			tracker_db_email_save_email (db_con, mail_msg_on_disk, MAIL_APP_MODEST);
+
+			email_free_mail_file (mail_msg_on_disk->parent_mail_file);
+			email_free_mail_message (mail_msg_on_disk);
+
+			return TRUE;
+		}
+	}
+
+	return FALSE;
+}
+
+
+static GSList *
+add_persons_from_internet_address_list_string_parsing (GSList *list, const gchar *s)
+{
+	InternetAddressList *addrs_list, *tmp;
+
+	g_return_val_if_fail (s, NULL);
+
+	addrs_list = internet_address_parse_string (s);
+
+	for (tmp = addrs_list; tmp; tmp = tmp->next) {
+		MailPerson *mp;
+
+		mp = email_allocate_mail_person ();
+
+		mp->addr = g_strdup (tmp->address->value.addr);
+		if(tmp->address->name)
+                	mp->name = g_strdup (tmp->address->name);
+		else
+			mp->name = g_strdup (tmp->address->value.addr);
+
+		list = g_slist_prepend (list, mp);
+	}
+
+	internet_address_list_destroy (addrs_list);
+
+	return list;
+}
+
+
+
+/***
+  Functions to decode summary (or ev-summary) files.
+***/
+
+
+static inline gboolean
+decode_string (FILE *in, gchar **str)
+{
+	guint32 len;
+	register gchar *ret;
+
+	if (!decode_guint32 (in, &len)) {
+		*str = NULL;
+		return FALSE;
+	}
+
+	/* I think I need to remove this for tinymail vs. evolution,
+	 * because Tinymail's format cares about a last \0 character */
+
+	/* len--; */
+
+	if (len > 65536) {
+		*str = NULL;
+		return FALSE;
+	}
+
+	ret = g_malloc (len+1);
+	if (len > 0 && fread (ret, len, 1, in) != 1) {
+		g_free (ret);
+		*str = NULL;
+		return FALSE;
+	}
+
+	ret[len] = 0;
+	*str = ret;
+	return TRUE;
+}
+
+
+static inline gboolean
+decode_gint32 (FILE *f, gint32 *dest)
+{
+	guint32 save;
+
+	if (!f) return FALSE;
+
+	if (fread (&save, sizeof (save), 1, f) == 1) {
+		*dest = g_ntohl (save);
+		return TRUE;
+	} else {
+		return FALSE;
+	}
+}
+
+/* This is completely different in Tinymail (we just reuse the impl for signed) */
+static inline gboolean
+decode_guint32 (FILE *f, guint32 *n)
+{
+	return decode_gint32 (f, (gint32*)n);
+}
+
+/* These are all aliases for signed ints in tinymail's format */
+
+#define CFU_DECODE_T(type)				\
+static inline gboolean					\
+decode_##type (FILE *in, type *dest)			\
+{							\
+	return decode_gint32 (in, (gint32*) dest);	\
+}
+
+CFU_DECODE_T(time_t)
+CFU_DECODE_T(off_t)
+CFU_DECODE_T(size_t)
+
+static inline gboolean
+skip_gint32_decoding (FILE *f)
+{
+	return fseek (f, 4, SEEK_CUR) > 0;
+}
+
+
+/* Same, we just reuse the impl. for signed numbers */
+static inline gboolean
+skip_guint32_decoding (FILE *f)
+{
+	return skip_gint32_decoding (f);
+}
+
+/* Same, we just reuse the impl. for signed numbers */
+static inline gboolean
+skip_time_t_decoding (FILE *f)
+{
+	return skip_gint32_decoding (f);
+}
+
+/* Same, we just reuse the impl. for signed numbers */
+static inline gboolean
+skip_off_t_decoding (FILE *f)
+{
+	return skip_gint32_decoding (f);
+}
+
+
+static inline gboolean
+skip_string_decoding (FILE *f)
+{
+	guint32 len;
+
+	if (!decode_guint32 (f, &len)) {
+		return FALSE;
+	}
+
+	/* Same as decode_string, Tinymail cares about the last \0 character
+	 * whereas this character is not present in Evolution's format */
+
+	if (fseek (f, len /*- 1*/, SEEK_CUR) != 0) {
+		tracker_error ("ERROR: seek failed for string with length %d with error code %d", len - 1, errno);
+		return FALSE;
+	}
+
+	return TRUE;
+}
+
+
+static inline gboolean
+skip_token_decoding (FILE *f)
+{
+	guint32 len;
+
+	if (!decode_guint32 (f, &len)) {
+		return FALSE;
+	}
+
+	if (len < 32) {
+		return TRUE;
+	}
+
+	len -= 32;
+	return fseek (f, len, SEEK_CUR) == 0;
+}
Index: src/trackerd/tracker-email-kmail.c
===================================================================
--- src/trackerd/tracker-email-kmail.c	(revision 1250)
+++ src/trackerd/tracker-email-kmail.c	(working copy)
@@ -721,7 +721,7 @@
         tracker_log ("Looking for email file \"%s\"", info->uri);
 
         if (!tracker_db_email_is_saved_email_file (db_con, info->uri)) {
-                MailMessage *mail_msg = email_parse_mail_message_by_path (MAIL_APP_KMAIL, info->uri, NULL, NULL);
+                MailMessage *mail_msg = email_parse_mail_message_by_path (MAIL_APP_KMAIL, info->uri, NULL, NULL, NULL);
 
                 if (!mail_msg) {
                         tracker_log ("WARNING: email %s not found", info->uri);
@@ -736,7 +736,7 @@
                 mail_msg->uri = g_strdup (mail_msg->path);
                 mail_msg->store = store;
                 mail_msg->mtime = tracker_get_file_mtime (mail_msg->path);
-                tracker_db_email_save_email (db_con, mail_msg);
+                tracker_db_email_save_email (db_con, mail_msg, MAIL_APP_KMAIL);
 
                 email_free_mail_file (mail_msg->parent_mail_file);
                 email_free_mail_message (mail_msg);
Index: src/trackerd/tracker-email-modest.h
===================================================================
--- src/trackerd/tracker-email-modest.h	(revision 0)
+++ src/trackerd/tracker-email-modest.h	(revision 0)
@@ -0,0 +1 @@
+
Index: src/trackerd/Makefile.am
===================================================================
--- src/trackerd/Makefile.am	(revision 1250)
+++ src/trackerd/Makefile.am	(working copy)
@@ -122,8 +122,13 @@
 mail_modules_LTLIBRARIES = \
 	libemail-evolution.la \
 	libemail-thunderbird.la \
-	libemail-kmail.la
+	libemail-kmail.la \
+	libemail-modest.la
 
+libemail_modest_la_SOURCES = tracker-email-modest.c
+libemail_modest_la_LDFLAGS = $(module_flags)
+libemail_modest_la_LIBADD = $(GLIB2_LIBS)
+
 libemail_evolution_la_SOURCES = tracker-email-evolution.c
 libemail_evolution_la_LDFLAGS = $(module_flags)
 libemail_evolution_la_LIBADD = $(GLIB2_LIBS)
Index: src/libtracker-common/tracker-configuration.c
===================================================================
--- src/libtracker-common/tracker-configuration.c	(revision 1250)
+++ src/libtracker-common/tracker-configuration.c	(working copy)
@@ -140,6 +140,8 @@
 				"[Emails]\n",
 				"# Index email messages from Evolution\n",
 				"IndexEvolutionEmails = true\n",
+				"# Index email messages from Modest\n",
+				"IndexModestEmails = false\n",
 				"# Index email messages from Thunderbird\n",
 				"IndexThunderbirdEmails = true\n\n",
 				"[Performance]\n",
Index: src/tracker-search-tool/tracker-search-tool-callbacks.c
===================================================================
--- src/tracker-search-tool/tracker-search-tool-callbacks.c	(revision 1250)
+++ src/tracker-search-tool/tracker-search-tool-callbacks.c	(working copy)
@@ -603,6 +603,8 @@
 		if (gsearch->type == SERVICE_EMAILS) {
 			if (strstr (mime, "Evolution")) {
 				exec = g_strdup_printf ("evolution \"%s\"", uri);
+			} else if (strstr (mime, "Modest")) {
+				exec = g_strdup_printf ("modest-open \"%s\"", uri);
 			} else if (strstr (mime, "KMail")) {
 				exec = g_strdup_printf ("kmail --view \"%s\"", uri);
 			} else if (strstr (mime, "Thunderbird")) {
Index: src/tracker-preferences/tracker-preferences.glade
===================================================================
--- src/tracker-preferences/tracker-preferences.glade	(revision 1250)
+++ src/tracker-preferences/tracker-preferences.glade	(working copy)
@@ -878,6 +878,19 @@
                       </packing>
                     </child>
                     <child>
+                      <widget class="GtkCheckButton" id="chkEnableModestIndexing">
+                        <property name="visible">True</property>
+                        <property name="label" translatable="yes">Enable _Modest email indexing</property>
+                        <property name="use_underline">True</property>
+                        <property name="response_id">0</property>
+                        <property name="active">True</property>
+                        <property name="draw_indicator">True</property>
+                      </widget>
+                      <packing>
+                        <property name="expand">False</property>
+                      </packing>
+                    </child>
+                    <child>
                       <widget class="GtkCheckButton" id="chkEnableThunderbirdIndexing">
                         <property name="visible">True</property>
                         <property name="sensitive">False</property>
Index: src/tracker-preferences/tracker-preferences.c
===================================================================
--- src/tracker-preferences/tracker-preferences.c	(revision 1250)
+++ src/tracker-preferences/tracker-preferences.c	(working copy)
@@ -468,6 +468,13 @@
 	gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (widget), value);
 
 	widget = glade_xml_get_widget (priv->gxml,
+				       "chkEnableModestIndexing");
+	value = tracker_configuration_get_boolean ("/Emails/IndexModestEmails",
+						   NULL);
+	gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (widget), value);
+
+
+	widget = glade_xml_get_widget (priv->gxml,
 				       "chkEnableThunderbirdIndexing");
 	value = tracker_configuration_get_boolean ("/Emails/IndexThunderbirdEmails",
 						   NULL);
@@ -750,6 +757,16 @@
 		tracker_configuration_set_boolean ("/Emails/IndexEvolutionEmails", bvalue);
 	}
 
+
+	widget = glade_xml_get_widget (priv->gxml, "chkEnableModestIndexing");
+	bvalue = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (widget));
+	bvalue_old = tracker_configuration_get_boolean ("/Emails/IndexModestEmails",
+							NULL);
+	if (bvalue != bvalue_old) {
+		set_bool_option (priv, "EnableModest", bvalue);
+		tracker_configuration_set_boolean ("/Emails/IndexModestEmails", bvalue);
+	}
+
 	widget = glade_xml_get_widget (priv->gxml, "chkEnableThunderbirdIndexing");
 	bvalue = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (widget));
 	bvalue_old = tracker_configuration_get_boolean ("/Emails/IndexThunderbirdEmails",
Index: docs/tracker.cfg.5
===================================================================
--- docs/tracker.cfg.5	(revision 1250)
+++ docs/tracker.cfg.5	(working copy)
@@ -163,6 +163,9 @@
 IndexEvolutionEmails=BOOLEAN
 Enable or disable indexing for Evolution emails.
 .TP
+IndexModestEmails=BOOLEAN
+Enable or disable indexing for Modest emails.
+.TP
 IndexThunderbirdEmails=BOOLEAN
 Enable or disable indexing for Thunderbird emails.
 
Index: data/services/default.service
===================================================================
--- data/services/default.service	(revision 1250)
+++ data/services/default.service	(working copy)
@@ -170,6 +170,18 @@
 TileMetadata=Email:Sender;Email:Subject;Email:Date;Email:SentTo;Email:CC;Email:Attachments
 ContentMetadata=Email:Body
 
+[ModestEmails]
+DisplayName=Modest Emails
+Description=Modest based emails
+Parent=Emails
+ViewerExec=modest-open "%1"
+KeyMetadata1=Email:Subject
+KeyMetadata2=Email:Sender
+KeyMetadata3=Email:Date
+TabularMetadata=Email:Sender;Email:Subject;Email:Date;
+TileMetadata=Email:Sender;Email:Subject;Email:Date;Email:SentTo;Email:CC;Email:Attachments
+ContentMetadata=Email:Body
+
 [ThunderbirdEmails]
 DisplayName=Thunderbird Emails
 Description=Thunderbird based emails
@@ -206,6 +218,12 @@
 Parent=EmailAttachments
 Icon=stock_attach
 
+[ModestAttachments]
+DisplayName=Modest Email Attachments
+Description=All files that are attached to an Modest Email
+Parent=EmailAttachments
+Icon=stock_attach
+
 [KMailAttachments]
 DisplayName=KMail Email Attachments
 Description=All files that are attached to an KMail Email


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]