[evolution/gnome-3-0] Bug 655263 - mail lost in MailDir migration
- From: Chenthill Palanisamy <pchen src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [evolution/gnome-3-0] Bug 655263 - mail lost in MailDir migration
- Date: Wed, 27 Jul 2011 09:39:03 +0000 (UTC)
commit b8a3a342a0a9f2421e38b4d17ae52257c7b0f702
Author: Chenthill Palanisamy <pchenthill novell com>
Date: Wed Jul 27 15:02:20 2011 +0530
Bug 655263 - mail lost in MailDir migration
mail/e-mail-migrate.c | 75 ++++++++++++++++++---
mail/em-utils.c | 138 ++++++++++++++++++++++++++++++++++++++++
mail/em-utils.h | 8 ++
mail/importers/mail-importer.c | 135 +--------------------------------------
mail/importers/mail-importer.h | 7 --
5 files changed, 212 insertions(+), 151 deletions(-)
---
diff --git a/mail/e-mail-migrate.c b/mail/e-mail-migrate.c
index 9d1452b..d101906 100644
--- a/mail/e-mail-migrate.c
+++ b/mail/e-mail-migrate.c
@@ -797,10 +797,16 @@ sanitize_maildir_folder_name (gchar *folder_name)
}
static void
-copy_folder (CamelStore *mbox_store, CamelStore *maildir_store, const gchar *mbox_fname, const gchar *maildir_fname)
+copy_folder (EShellBackend *shell_backend, CamelStore *mbox_store, CamelStore *maildir_store, const gchar *mbox_fname, const gchar *maildir_fname)
{
CamelFolder *fromfolder, *tofolder;
- GPtrArray *uids;
+ EMailSession *mail_session;
+ GPtrArray *uids, *single_uid;
+ GError *error = NULL;
+ gboolean use_fallback = FALSE;
+ guint i;
+
+ mail_session = e_mail_backend_get_session (E_MAIL_BACKEND (shell_backend));
fromfolder = camel_store_get_folder_sync (
mbox_store, mbox_fname, 0, NULL, NULL);
@@ -820,18 +826,63 @@ copy_folder (CamelStore *mbox_store, CamelStore *maildir_store, const gchar *mbo
}
uids = camel_folder_get_uids (fromfolder);
- camel_folder_transfer_messages_to_sync (
- fromfolder, uids, tofolder,
- FALSE, NULL,
- NULL, NULL);
+ single_uid = g_ptr_array_new ();
+
+ /* import mails one by one to detect summary-mismatch errors */
+ for (i = 0; i < uids->len; i++) {
+ gpointer uid = g_ptr_array_index (uids, i);
+
+ g_ptr_array_add (single_uid, uid);
+ camel_folder_transfer_messages_to_sync (
+ fromfolder, single_uid, tofolder,
+ FALSE, NULL,
+ NULL, &error);
+ g_ptr_array_remove_index (single_uid, 0);
+ if (error) {
+ g_warning ("Error migrating folder %s: %s \n", mbox_fname, error->message);
+
+ g_clear_error (&error);
+ /* delete the maildir folder */
+ camel_store_delete_folder_sync (maildir_store, maildir_fname, NULL, NULL);
+ if (error)
+ g_warning ("Error deleting maildir folder %s: %s \n", maildir_fname, error->message);
+
+ use_fallback = TRUE;
+ break;
+ }
+ }
camel_folder_free_uids (fromfolder, uids);
+ g_ptr_array_free (single_uid, TRUE);
+
+ /* fallback, import the mbox file directly. All the flags will be lost in this method */
+ if (use_fallback) {
+ const gchar *to_uri;
+ CamelService *mbox_service;
+ gchar *mbox_file_name;
+
+ g_message ("Using the fallback method to migrate \n");
+ to_uri = camel_folder_get_uri (tofolder);
+
+ /* build the filename ourselves as there is no way i see to get the filename from the store */
+ mbox_service = (CamelService *) mbox_store;
+ mbox_file_name = g_build_filename (mbox_service->url->path, mbox_fname, NULL);
+
+ g_clear_error (&error);
+ em_utils_import_mbox (mail_session, to_uri, mbox_file_name, NULL, &error);
+
+ g_free (mbox_file_name);
+ }
+
+ if (error)
+ g_warning ("Error migrating folder %s: %s \n", mbox_fname, error->message);
g_object_unref (fromfolder);
g_object_unref (tofolder);
+ g_clear_error (&error);
}
static void
-copy_folders (CamelStore *mbox_store, CamelStore *maildir_store, CamelFolderInfo *fi, EMMigrateSession *session)
+copy_folders (EShellBackend *shell_backend, CamelStore *mbox_store, CamelStore *maildir_store, CamelFolderInfo *fi, EMMigrateSession *session)
{
if (fi) {
if (!g_str_has_prefix (fi->full_name, ".#evolution")) {
@@ -839,19 +890,20 @@ copy_folders (CamelStore *mbox_store, CamelStore *maildir_store, CamelFolderInfo
/* sanitize folder names and copy folders */
maildir_folder_name = sanitize_maildir_folder_name (fi->full_name);
- copy_folder (mbox_store, maildir_store, fi->full_name, maildir_folder_name);
+ copy_folder (shell_backend, mbox_store, maildir_store, fi->full_name, maildir_folder_name);
g_free (maildir_folder_name);
}
if (fi->child)
- copy_folders (mbox_store, maildir_store, fi->child, session);
+ copy_folders (shell_backend, mbox_store, maildir_store, fi->child, session);
- copy_folders (mbox_store, maildir_store, fi->next, session);
+ copy_folders (shell_backend, mbox_store, maildir_store, fi->next, session);
}
}
struct MigrateStore {
EMMigrateSession *session;
+ EShellBackend *shell_backend;
CamelStore *mbox_store;
CamelStore *maildir_store;
gboolean complete;
@@ -872,7 +924,7 @@ migrate_stores (struct MigrateStore *ms)
NULL, NULL);
/* FIXME progres dialog */
- copy_folders (mbox_store, maildir_store, mbox_fi, ms->session);
+ copy_folders (ms->shell_backend, mbox_store, maildir_store, mbox_fi, ms->session);
ms->complete = TRUE;
return;
@@ -920,6 +972,7 @@ migrate_mbox_to_maildir (EShellBackend *shell_backend, EMMigrateSession *session
ms.mbox_store = mbox_store;
ms.maildir_store = maildir_store;
ms.session = session;
+ ms.shell_backend = shell_backend;
ms.complete = FALSE;
g_thread_create ((GThreadFunc) migrate_stores, &ms, TRUE, NULL);
diff --git a/mail/em-utils.c b/mail/em-utils.c
index 15008ab..1cbb2ff 100644
--- a/mail/em-utils.c
+++ b/mail/em-utils.c
@@ -2446,3 +2446,141 @@ em_utils_is_local_delivery_mbox_file (const gchar *uri)
return FALSE;
}
+
+static struct {
+ gchar tag;
+ guint32 mozflag;
+ guint32 flag;
+} status_flags[] = {
+ { 'F', MSG_FLAG_MARKED, CAMEL_MESSAGE_FLAGGED },
+ { 'A', MSG_FLAG_REPLIED, CAMEL_MESSAGE_ANSWERED },
+ { 'D', MSG_FLAG_EXPUNGED, CAMEL_MESSAGE_DELETED },
+ { 'R', MSG_FLAG_READ, CAMEL_MESSAGE_SEEN },
+};
+
+static guint32
+decode_status (const gchar *status)
+{
+ const gchar *p;
+ guint32 flags = 0;
+ gint i;
+
+ p = status;
+ while ((*p++)) {
+ for (i = 0; i < G_N_ELEMENTS (status_flags); i++)
+ if (status_flags[i].tag == *p)
+ flags |= status_flags[i].flag;
+ }
+
+ return flags;
+}
+
+static guint32
+decode_mozilla_status (const gchar *tmp)
+{
+ unsigned long status = strtoul (tmp, NULL, 16);
+ guint32 flags = 0;
+ gint i;
+
+ for (i = 0; i < G_N_ELEMENTS (status_flags); i++)
+ if (status_flags[i].mozflag & status)
+ flags |= status_flags[i].flag;
+ return flags;
+}
+
+void
+em_utils_import_mbox (EMailSession *mail_session, const gchar *folder_uri, const gchar *mbox_path, GCancellable *cancellable, GError **error)
+{
+ CamelFolder *folder;
+ CamelMimeParser *mp = NULL;
+ struct stat st;
+ gint fd;
+ CamelMessageInfo *info;
+
+ if (g_stat (mbox_path, &st) == -1) {
+ g_warning("cannot find source file to import '%s': %s", mbox_path, g_strerror(errno));
+ return;
+ }
+
+ if (folder_uri == NULL || folder_uri[0] == 0)
+ folder = e_mail_local_get_folder (E_MAIL_LOCAL_FOLDER_INBOX);
+ else
+ folder = e_mail_session_uri_to_folder_sync (
+ mail_session, folder_uri, CAMEL_STORE_FOLDER_CREATE,
+ cancellable, error);
+
+ if (folder == NULL)
+ return;
+
+ if (S_ISREG (st.st_mode)) {
+ fd = g_open (mbox_path, O_RDONLY|O_BINARY, 0);
+ if (fd == -1) {
+ g_warning("cannot find source file to import '%s': %s", mbox_path, g_strerror(errno));
+ goto fail1;
+ }
+
+ mp = camel_mime_parser_new ();
+ camel_mime_parser_scan_from (mp, TRUE);
+ if (camel_mime_parser_init_with_fd (mp, fd) == -1) {
+ /* will never happen - 0 is unconditionally returned */
+ goto fail2;
+ }
+
+ camel_operation_push_message (
+ cancellable, _("Importing '%s'"),
+ camel_folder_get_full_name (folder));
+ camel_folder_freeze (folder);
+ while (camel_mime_parser_step (mp, NULL, NULL) == CAMEL_MIME_PARSER_STATE_FROM) {
+ CamelMimeMessage *msg;
+ const gchar *tmp;
+ gint pc = 0;
+ guint32 flags = 0;
+
+ if (st.st_size > 0)
+ pc = (gint)(100.0 * ((double)camel_mime_parser_tell (mp) / (double)st.st_size));
+ camel_operation_progress (cancellable, pc);
+
+ msg = camel_mime_message_new ();
+ if (!camel_mime_part_construct_from_parser_sync (
+ (CamelMimePart *)msg, mp, NULL, NULL)) {
+ /* set exception? */
+ g_object_unref (msg);
+ break;
+ }
+
+ info = camel_message_info_new (NULL);
+
+ tmp = camel_medium_get_header((CamelMedium *)msg, "X-Mozilla-Status");
+ if (tmp)
+ flags |= decode_mozilla_status (tmp);
+ tmp = camel_medium_get_header((CamelMedium *)msg, "Status");
+ if (tmp)
+ flags |= decode_status (tmp);
+ tmp = camel_medium_get_header((CamelMedium *)msg, "X-Status");
+ if (tmp)
+ flags |= decode_status (tmp);
+
+ camel_message_info_set_flags (info, flags, ~0);
+ camel_folder_append_message_sync (
+ folder, msg, info, NULL,
+ cancellable, error);
+ camel_message_info_free (info);
+ g_object_unref (msg);
+
+ if (error && *error != NULL)
+ break;
+
+ camel_mime_parser_step (mp, NULL, NULL);
+ }
+ /* FIXME Not passing a GCancellable or GError here. */
+ camel_folder_synchronize_sync (folder, FALSE, NULL, NULL);
+ camel_folder_thaw (folder);
+ camel_operation_pop_message (cancellable);
+ fail2:
+ g_object_unref (mp);
+ }
+fail1:
+ /* FIXME Not passing a GCancellable or GError here. */
+ camel_folder_synchronize_sync (folder, FALSE, NULL, NULL);
+ g_object_unref (folder);
+}
diff --git a/mail/em-utils.h b/mail/em-utils.h
index 73916b1..1892c4c 100644
--- a/mail/em-utils.h
+++ b/mail/em-utils.h
@@ -35,6 +35,13 @@ G_BEGIN_DECLS
struct _EMFormat;
+/* Defines copied from nsMsgMessageFlags.h in Mozilla source. */
+/* Evolution only cares about these headers I think */
+#define MSG_FLAG_READ 0x0001
+#define MSG_FLAG_REPLIED 0x0002
+#define MSG_FLAG_MARKED 0x0004
+#define MSG_FLAG_EXPUNGED 0x0008
+
gboolean em_utils_ask_open_many (GtkWindow *parent, gint how_many);
gboolean em_utils_prompt_user (GtkWindow *parent, const gchar *promptkey, const gchar *tag, ...);
@@ -101,6 +108,7 @@ void emu_remove_from_mail_cache_1 (const gchar *address);
void emu_free_mail_cache (void);
void emu_restore_folder_tree_state (EMFolderTree *folder_tree);
+void em_utils_import_mbox (EMailSession *mail_session, const gchar *folder_uri, const gchar *mbox_path, GCancellable *cancellable, GError **error);
gboolean em_utils_is_local_delivery_mbox_file (const gchar *uri);
diff --git a/mail/importers/mail-importer.c b/mail/importers/mail-importer.c
index f6cbbbb..a47fa30 100644
--- a/mail/importers/mail-importer.c
+++ b/mail/importers/mail-importer.c
@@ -40,6 +40,7 @@
#include "e-util/e-util-private.h"
#include "shell/e-shell-backend.h"
+#include "em-utils.h"
#include "mail-mt.h"
#include "mail-tools.h"
#include "e-mail-local.h"
@@ -65,144 +66,12 @@ import_mbox_desc (struct _import_mbox_msg *m)
return g_strdup (_("Importing mailbox"));
}
-static struct {
- gchar tag;
- guint32 mozflag;
- guint32 flag;
-} status_flags[] = {
- { 'F', MSG_FLAG_MARKED, CAMEL_MESSAGE_FLAGGED },
- { 'A', MSG_FLAG_REPLIED, CAMEL_MESSAGE_ANSWERED },
- { 'D', MSG_FLAG_EXPUNGED, CAMEL_MESSAGE_DELETED },
- { 'R', MSG_FLAG_READ, CAMEL_MESSAGE_SEEN },
-};
-
-static guint32
-decode_status (const gchar *status)
-{
- const gchar *p;
- guint32 flags = 0;
- gint i;
-
- p = status;
- while ((*p++)) {
- for (i = 0; i < G_N_ELEMENTS (status_flags); i++)
- if (status_flags[i].tag == *p)
- flags |= status_flags[i].flag;
- }
-
- return flags;
-}
-
-static guint32
-decode_mozilla_status (const gchar *tmp)
-{
- unsigned long status = strtoul (tmp, NULL, 16);
- guint32 flags = 0;
- gint i;
-
- for (i = 0; i < G_N_ELEMENTS (status_flags); i++)
- if (status_flags[i].mozflag & status)
- flags |= status_flags[i].flag;
- return flags;
-}
-
static void
import_mbox_exec (struct _import_mbox_msg *m,
GCancellable *cancellable,
GError **error)
{
- CamelFolder *folder;
- CamelMimeParser *mp = NULL;
- struct stat st;
- gint fd;
- CamelMessageInfo *info;
-
- if (g_stat (m->path, &st) == -1) {
- g_warning("cannot find source file to import '%s': %s", m->path, g_strerror(errno));
- return;
- }
-
- if (m->uri == NULL || m->uri[0] == 0)
- folder = e_mail_local_get_folder (E_MAIL_LOCAL_FOLDER_INBOX);
- else
- folder = e_mail_session_uri_to_folder_sync (
- m->session, m->uri, CAMEL_STORE_FOLDER_CREATE,
- cancellable, error);
-
- if (folder == NULL)
- return;
-
- if (S_ISREG (st.st_mode)) {
- fd = g_open (m->path, O_RDONLY|O_BINARY, 0);
- if (fd == -1) {
- g_warning("cannot find source file to import '%s': %s", m->path, g_strerror(errno));
- goto fail1;
- }
-
- mp = camel_mime_parser_new ();
- camel_mime_parser_scan_from (mp, TRUE);
- if (camel_mime_parser_init_with_fd (mp, fd) == -1) {
- /* will never happen - 0 is unconditionally returned */
- goto fail2;
- }
-
- camel_operation_push_message (
- cancellable, _("Importing '%s'"),
- camel_folder_get_full_name (folder));
- camel_folder_freeze (folder);
- while (camel_mime_parser_step (mp, NULL, NULL) == CAMEL_MIME_PARSER_STATE_FROM) {
- CamelMimeMessage *msg;
- const gchar *tmp;
- gint pc = 0;
- guint32 flags = 0;
-
- if (st.st_size > 0)
- pc = (gint)(100.0 * ((double)camel_mime_parser_tell (mp) / (double)st.st_size));
- camel_operation_progress (cancellable, pc);
-
- msg = camel_mime_message_new ();
- if (!camel_mime_part_construct_from_parser_sync (
- (CamelMimePart *)msg, mp, NULL, NULL)) {
- /* set exception? */
- g_object_unref (msg);
- break;
- }
-
- info = camel_message_info_new (NULL);
-
- tmp = camel_medium_get_header((CamelMedium *)msg, "X-Mozilla-Status");
- if (tmp)
- flags |= decode_mozilla_status (tmp);
- tmp = camel_medium_get_header((CamelMedium *)msg, "Status");
- if (tmp)
- flags |= decode_status (tmp);
- tmp = camel_medium_get_header((CamelMedium *)msg, "X-Status");
- if (tmp)
- flags |= decode_status (tmp);
-
- camel_message_info_set_flags (info, flags, ~0);
- camel_folder_append_message_sync (
- folder, msg, info, NULL,
- cancellable, error);
- camel_message_info_free (info);
- g_object_unref (msg);
-
- if (error && *error != NULL)
- break;
-
- camel_mime_parser_step (mp, NULL, NULL);
- }
- /* FIXME Not passing a GCancellable or GError here. */
- camel_folder_synchronize_sync (folder, FALSE, NULL, NULL);
- camel_folder_thaw (folder);
- camel_operation_pop_message (cancellable);
- fail2:
- g_object_unref (mp);
- }
-fail1:
- /* FIXME Not passing a GCancellable or GError here. */
- camel_folder_synchronize_sync (folder, FALSE, NULL, NULL);
- g_object_unref (folder);
+ em_utils_import_mbox (m->session, m->uri, m->path, cancellable, error);
}
static void
diff --git a/mail/importers/mail-importer.h b/mail/importers/mail-importer.h
index 93d1897..e22131b 100644
--- a/mail/importers/mail-importer.h
+++ b/mail/importers/mail-importer.h
@@ -40,13 +40,6 @@ void mbox_importer_set_preview_funcs (MboxImporterCreatePreviewFunc create_func,
EImportImporter *elm_importer_peek (void);
EImportImporter *pine_importer_peek (void);
-/* Defines copied from nsMsgMessageFlags.h in Mozilla source. */
-/* Evolution only cares about these headers I think */
-#define MSG_FLAG_READ 0x0001
-#define MSG_FLAG_REPLIED 0x0002
-#define MSG_FLAG_MARKED 0x0004
-#define MSG_FLAG_EXPUNGED 0x0008
-
gint mail_importer_import_mbox (EMailSession *session,
const gchar *path,
const gchar *folderuri,
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]