aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--mail/e-mail-migrate.c325
-rw-r--r--shell/Makefile.am3
-rw-r--r--shell/e-convert-local-mail.c315
-rw-r--r--shell/main.c15
4 files changed, 332 insertions, 326 deletions
diff --git a/mail/e-mail-migrate.c b/mail/e-mail-migrate.c
index e2968c1d9f..c642df91db 100644
--- a/mail/e-mail-migrate.c
+++ b/mail/e-mail-migrate.c
@@ -65,50 +65,6 @@
/* 1.4 upgrade functions */
-#define EM_TYPE_MIGRATE_SESSION \
- (em_migrate_session_get_type ())
-
-typedef struct _EMMigrateSession {
- CamelSession parent_object;
-
- CamelStore *store; /* new folder tree store */
- gchar *srcdir; /* old folder tree path */
-} EMMigrateSession;
-
-typedef struct _EMMigrateSessionClass {
- CamelSessionClass parent_class;
-
-} EMMigrateSessionClass;
-
-GType em_migrate_session_get_type (void);
-
-G_DEFINE_TYPE (EMMigrateSession, em_migrate_session, CAMEL_TYPE_SESSION)
-
-static void
-em_migrate_session_class_init (EMMigrateSessionClass *class)
-{
-}
-
-static void
-em_migrate_session_init (EMMigrateSession *session)
-{
-}
-
-static EMMigrateSession *
-em_migrate_session_new (const gchar *user_data_dir)
-{
- const gchar *user_cache_dir;
-
- /* FIXME Really need to kill this function and
- * get the cache dir from EShellBackend. */
- user_cache_dir = mail_session_get_cache_dir ();
-
- return g_object_new (
- EM_TYPE_MIGRATE_SESSION,
- "user-data-dir", user_data_dir,
- "user-cache-dir", user_cache_dir, NULL);
-}
-
static GtkProgressBar *progress;
static void
@@ -275,284 +231,6 @@ emm_setup_initial (const gchar *data_dir)
return TRUE;
}
-static gboolean
-mbox_to_maildir_migration_needed (EShellBackend *shell_backend)
-{
- gchar *local_store;
- gchar *local_outbox;
- const gchar *data_dir;
- gboolean migration_needed = FALSE;
-
- data_dir = e_shell_backend_get_data_dir (shell_backend);
-
- local_store = g_build_filename (data_dir, "local", NULL);
- local_outbox = g_build_filename (local_store, ".Outbox", NULL);
-
- /* If this is a fresh install (no local store exists yet)
- * then obviously there's nothing to migrate to Maildir. */
- if (!g_file_test (local_store, G_FILE_TEST_IS_DIR))
- migration_needed = FALSE;
-
- /* Look for a Maildir Outbox folder. */
- else if (!g_file_test (local_outbox, G_FILE_TEST_IS_DIR))
- migration_needed = TRUE;
-
- g_free (local_store);
- g_free (local_outbox);
-
- return migration_needed;
-}
-
-/* Folder names with '.' are converted to '_' */
-static gchar *
-sanitize_maildir_folder_name (gchar *folder_name)
-{
- gchar *maildir_folder_name;
-
- maildir_folder_name = g_strdup (folder_name);
- g_strdelimit (maildir_folder_name, ".", '_');
-
- return maildir_folder_name;
-}
-
-static void
-copy_folder (CamelStore *mbox_store,
- CamelStore *maildir_store,
- const gchar *mbox_fname,
- const gchar *maildir_fname)
-{
- CamelFolder *fromfolder, *tofolder;
- GPtrArray *uids;
-
- fromfolder = camel_store_get_folder_sync (
- mbox_store, mbox_fname, 0, NULL, NULL);
- if (fromfolder == NULL) {
- g_warning ("Cannot find mbox folder %s \n", mbox_fname);
- return;
- }
-
- tofolder = camel_store_get_folder_sync (
- maildir_store, maildir_fname,
- CAMEL_STORE_FOLDER_CREATE,
- NULL, NULL);
- if (tofolder == NULL) {
- g_warning ("Cannot create maildir folder %s \n", maildir_fname);
- g_object_unref (fromfolder);
- return;
- }
-
- uids = camel_folder_get_uids (fromfolder);
- camel_folder_transfer_messages_to_sync (
- fromfolder, uids, tofolder,
- FALSE, NULL,
- NULL, NULL);
- camel_folder_free_uids (fromfolder, uids);
-
- g_object_unref (fromfolder);
- g_object_unref (tofolder);
-}
-
-static void
-copy_folders (CamelStore *mbox_store,
- CamelStore *maildir_store,
- CamelFolderInfo *fi,
- EMMigrateSession *session)
-{
- if (fi) {
- if (!g_str_has_prefix (fi->full_name, ".#evolution")) {
- gchar *maildir_folder_name;
-
- /* 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);
- g_free (maildir_folder_name);
- }
-
- if (fi->child)
- copy_folders (mbox_store, maildir_store, fi->child, session);
-
- copy_folders (mbox_store, maildir_store, fi->next, session);
- }
-}
-
-struct MigrateStore {
- EMMigrateSession *session;
- CamelStore *mbox_store;
- CamelStore *maildir_store;
- gboolean complete;
-};
-
-static void
-migrate_stores (struct MigrateStore *ms)
-{
- CamelFolderInfo *mbox_fi;
- CamelStore *mbox_store = ms->mbox_store;
- CamelStore *maildir_store = ms->maildir_store;
-
- mbox_fi = camel_store_get_folder_info_sync (
- mbox_store, NULL,
- CAMEL_STORE_FOLDER_INFO_RECURSIVE |
- CAMEL_STORE_FOLDER_INFO_FAST |
- CAMEL_STORE_FOLDER_INFO_SUBSCRIBED,
- NULL, NULL);
-
- /* FIXME progres dialog */
- copy_folders (mbox_store, maildir_store, mbox_fi, ms->session);
- ms->complete = TRUE;
-
- return;
-}
-
-static gboolean
-migrate_mbox_to_maildir (EShellBackend *shell_backend,
- EMMigrateSession *session)
-{
- EShell *shell;
- ESource *source;
- ESourceRegistry *registry;
- ESourceExtension *extension;
- const gchar *extension_name;
- CamelService *mbox_service;
- CamelService *maildir_service;
- CamelStore *mbox_store;
- CamelStore *maildir_store;
- CamelSettings *settings;
- const gchar *data_dir;
- const gchar *uid;
- gchar *path;
- struct MigrateStore ms;
- GError *error = NULL;
-
- data_dir = e_shell_backend_get_data_dir (shell_backend);
- shell = e_shell_backend_get_shell (shell_backend);
- registry = e_shell_get_registry (shell);
-
- source = e_source_new (NULL, NULL, NULL);
- e_source_set_display_name (source, "local_mbox");
-
- uid = e_source_get_uid (source);
-
- extension_name = E_SOURCE_EXTENSION_MAIL_ACCOUNT;
- extension = e_source_get_extension (source, extension_name);
-
- e_source_backend_set_backend_name (
- E_SOURCE_BACKEND (extension), "mbox");
-
- extension_name = e_source_camel_get_extension_name ("mbox");
- extension = e_source_get_extension (source, extension_name);
- settings = e_source_camel_get_settings (E_SOURCE_CAMEL (extension));
-
- path = g_build_filename (data_dir, "local_mbox", NULL);
- g_object_set (settings, "path", path, NULL);
- g_free (path);
-
- e_source_registry_commit_source_sync (
- registry, source, NULL, &error);
-
- if (error == NULL)
- mbox_service = camel_session_add_service (
- CAMEL_SESSION (session), uid, "mbox",
- CAMEL_PROVIDER_STORE, &error);
-
- if (error == NULL)
- maildir_service = camel_session_add_service (
- CAMEL_SESSION (session), "local", "maildir",
- CAMEL_PROVIDER_STORE, &error);
-
- if (error != NULL) {
- g_warning ("%s: %s", G_STRFUNC, error->message);
- g_object_unref (source);
- g_error_free (error);
- return FALSE;
- }
-
- camel_service_set_settings (mbox_service, settings);
-
- g_object_unref (source);
-
- settings = camel_service_get_settings (maildir_service);
- path = g_build_filename (data_dir, "local", NULL);
- g_object_set (settings, "path", path, NULL);
- g_mkdir (path, 0700);
- g_free (path);
-
- mbox_store = CAMEL_STORE (mbox_service);
- maildir_store = CAMEL_STORE (maildir_service);
-
- ms.mbox_store = mbox_store;
- ms.maildir_store = maildir_store;
- ms.session = session;
- ms.complete = FALSE;
-
- g_thread_create ((GThreadFunc) migrate_stores, &ms, TRUE, NULL);
- while (!ms.complete)
- g_main_context_iteration (NULL, TRUE);
-
- return TRUE;
-}
-
-static void
-rename_mbox_dir (EShellBackend *shell_backend)
-{
- gchar *local_mbox_path, *new_mbox_path;
- const gchar *data_dir;
-
- data_dir = e_shell_backend_get_data_dir (shell_backend);
- local_mbox_path = g_build_filename (data_dir, "local", NULL);
- new_mbox_path = g_build_filename (data_dir, "local_mbox", NULL);
-
- if (!g_file_test (local_mbox_path, G_FILE_TEST_EXISTS))
- goto exit;
-
- if (g_file_test (new_mbox_path, G_FILE_TEST_EXISTS))
- goto exit;
-
- g_rename (local_mbox_path, new_mbox_path);
-
-exit:
- g_free (local_mbox_path);
- g_free (new_mbox_path);
-}
-
-static gboolean
-migrate_local_store (EShellBackend *shell_backend)
-{
- EMMigrateSession *session;
- const gchar *data_dir;
- gchar *local_store;
- gint response;
-
- if (!mbox_to_maildir_migration_needed (shell_backend))
- return TRUE;
-
- response = e_alert_run_dialog_for_args (
- e_shell_get_active_window (NULL),
- "mail:ask-migrate-store", NULL);
-
- if (response == GTK_RESPONSE_CANCEL)
- exit (EXIT_SUCCESS);
-
- rename_mbox_dir (shell_backend);
- data_dir = e_shell_backend_get_data_dir (shell_backend);
- local_store = g_build_filename (data_dir, "local", NULL);
-
- if (!g_file_test (local_store, G_FILE_TEST_EXISTS))
- g_mkdir_with_parents (local_store, 0700);
-
- session = em_migrate_session_new (data_dir);
- camel_session_set_online (CAMEL_SESSION (session), FALSE);
-
- migrate_mbox_to_maildir (shell_backend, session);
-
- g_object_unref (session);
-
- g_free (local_store);
-
- return TRUE;
-}
-
static void
em_rename_view_in_folder (gpointer data,
gpointer user_data)
@@ -660,9 +338,6 @@ e_mail_migrate (EShellBackend *shell_backend,
if (major == 0)
return emm_setup_initial (data_dir);
- if (!migrate_local_store (shell_backend))
- return FALSE;
-
if (major <= 2 || (major == 3 && minor < 4))
em_rename_folder_views (shell_backend);
diff --git a/shell/Makefile.am b/shell/Makefile.am
index b460d08d43..a01dc7771c 100644
--- a/shell/Makefile.am
+++ b/shell/Makefile.am
@@ -143,7 +143,8 @@ evolution_CPPFLAGS = \
$(CLUTTER_CFLAGS)
evolution_SOURCES = \
- main.c
+ main.c \
+ e-convert-local-mail.c
evolution_LDADD = \
libeshell.la \
diff --git a/shell/e-convert-local-mail.c b/shell/e-convert-local-mail.c
new file mode 100644
index 0000000000..c36a036749
--- /dev/null
+++ b/shell/e-convert-local-mail.c
@@ -0,0 +1,315 @@
+/*
+ * e-convert-local-mail.c
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
+ *
+ * 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 the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ */
+
+#include <config.h>
+
+#include <glib/gstdio.h>
+#include <camel/camel.h>
+
+#include <shell/e-shell.h>
+#include <libevolution-utils/e-alert-dialog.h>
+
+/* Forward Declarations */
+void e_convert_local_mail (EShell *shell);
+
+static gboolean
+mail_to_maildir_migration_needed (const gchar *mail_data_dir)
+{
+ gchar *local_store;
+ gchar *local_outbox;
+ gboolean migration_needed = FALSE;
+
+ local_store = g_build_filename (mail_data_dir, "local", NULL);
+ local_outbox = g_build_filename (local_store, ".Outbox", NULL);
+
+ /* If this is a fresh install (no local store exists yet)
+ * then obviously there's nothing to migrate to Maildir. */
+ if (!g_file_test (local_store, G_FILE_TEST_IS_DIR))
+ migration_needed = FALSE;
+
+ /* Look for a Maildir Outbox folder. */
+ else if (!g_file_test (local_outbox, G_FILE_TEST_IS_DIR))
+ migration_needed = TRUE;
+
+ g_free (local_store);
+ g_free (local_outbox);
+
+ return migration_needed;
+}
+
+/* Folder names with '.' are converted to '_' */
+static gchar *
+sanitize_maildir_folder_name (gchar *folder_name)
+{
+ gchar *maildir_folder_name;
+
+ maildir_folder_name = g_strdup (folder_name);
+ g_strdelimit (maildir_folder_name, ".", '_');
+
+ return maildir_folder_name;
+}
+
+static void
+copy_folder (CamelStore *mail_store,
+ CamelStore *maildir_store,
+ const gchar *mail_fname,
+ const gchar *maildir_fname)
+{
+ CamelFolder *fromfolder, *tofolder;
+ GPtrArray *uids;
+
+ fromfolder = camel_store_get_folder_sync (
+ mail_store, mail_fname, 0, NULL, NULL);
+ if (fromfolder == NULL) {
+ g_warning ("Cannot find mail folder %s \n", mail_fname);
+ return;
+ }
+
+ tofolder = camel_store_get_folder_sync (
+ maildir_store, maildir_fname,
+ CAMEL_STORE_FOLDER_CREATE, NULL, NULL);
+ if (tofolder == NULL) {
+ g_warning ("Cannot create maildir folder %s \n", maildir_fname);
+ g_object_unref (fromfolder);
+ return;
+ }
+
+ uids = camel_folder_get_uids (fromfolder);
+ camel_folder_transfer_messages_to_sync (
+ fromfolder, uids, tofolder, FALSE, NULL, NULL, NULL);
+ camel_folder_free_uids (fromfolder, uids);
+
+ g_object_unref (fromfolder);
+ g_object_unref (tofolder);
+}
+
+static void
+copy_folders (CamelStore *mail_store,
+ CamelStore *maildir_store,
+ CamelFolderInfo *fi,
+ CamelSession *session)
+{
+ if (fi) {
+ if (!g_str_has_prefix (fi->full_name, ".#evolution")) {
+ gchar *maildir_folder_name;
+
+ /* sanitize folder names and copy folders */
+ maildir_folder_name = sanitize_maildir_folder_name (fi->full_name);
+ copy_folder (
+ mail_store, maildir_store,
+ fi->full_name, maildir_folder_name);
+ g_free (maildir_folder_name);
+ }
+
+ if (fi->child)
+ copy_folders (mail_store, maildir_store, fi->child, session);
+
+ copy_folders (mail_store, maildir_store, fi->next, session);
+ }
+}
+
+struct MigrateStore {
+ CamelSession *session;
+ CamelStore *mail_store;
+ CamelStore *maildir_store;
+ gboolean complete;
+};
+
+static void
+migrate_stores (struct MigrateStore *ms)
+{
+ CamelFolderInfo *mail_fi;
+ CamelStore *mail_store = ms->mail_store;
+ CamelStore *maildir_store = ms->maildir_store;
+
+ mail_fi = camel_store_get_folder_info_sync (
+ mail_store, NULL,
+ CAMEL_STORE_FOLDER_INFO_RECURSIVE |
+ CAMEL_STORE_FOLDER_INFO_FAST |
+ CAMEL_STORE_FOLDER_INFO_SUBSCRIBED,
+ NULL, NULL);
+
+ /* FIXME progres dialog */
+ copy_folders (mail_store, maildir_store, mail_fi, ms->session);
+ ms->complete = TRUE;
+}
+
+static void
+rename_mail_dir (ESource *mbox_source,
+ const gchar *mail_data_dir)
+{
+ gchar *old_mail_dir;
+ gchar *new_mail_dir;
+ gboolean need_rename;
+ const gchar *mbox_uid;
+
+ mbox_uid = e_source_get_uid (mbox_source);
+
+ old_mail_dir = g_build_filename (mail_data_dir, "local", NULL);
+ new_mail_dir = g_build_filename (mail_data_dir, mbox_uid, NULL);
+
+ /* Rename if old directory exists and new directory does not. */
+ need_rename =
+ g_file_test (old_mail_dir, G_FILE_TEST_EXISTS) &&
+ !g_file_test (new_mail_dir, G_FILE_TEST_EXISTS);
+
+ if (need_rename)
+ g_rename (old_mail_dir, new_mail_dir);
+
+ g_free (old_mail_dir);
+ g_free (new_mail_dir);
+}
+
+static gboolean
+migrate_mail_to_maildir (EShell *shell,
+ CamelSession *session,
+ ESource *mbox_source)
+{
+ ESourceRegistry *registry;
+ ESourceExtension *extension;
+ const gchar *extension_name;
+ CamelService *mail_service;
+ CamelService *maildir_service;
+ CamelStore *mail_store;
+ CamelStore *maildir_store;
+ CamelSettings *settings;
+ const gchar *data_dir;
+ const gchar *mbox_uid;
+ gchar *path;
+ struct MigrateStore ms;
+ GError *error = NULL;
+
+ registry = e_shell_get_registry (shell);
+
+ data_dir = camel_session_get_user_data_dir (session);
+
+ mbox_uid = e_source_get_uid (mbox_source);
+ e_source_set_display_name (mbox_source, "local_mbox");
+
+ extension_name = E_SOURCE_EXTENSION_MAIL_ACCOUNT;
+ extension = e_source_get_extension (mbox_source, extension_name);
+
+ e_source_backend_set_backend_name (
+ E_SOURCE_BACKEND (extension), "mbox");
+
+ extension_name = e_source_camel_get_extension_name ("mbox");
+ extension = e_source_get_extension (mbox_source, extension_name);
+ settings = e_source_camel_get_settings (E_SOURCE_CAMEL (extension));
+
+ path = g_build_filename (data_dir, mbox_uid, NULL);
+ g_object_set (settings, "path", path, NULL);
+ g_free (path);
+
+ e_source_registry_commit_source_sync (
+ registry, mbox_source, NULL, &error);
+
+ if (error == NULL)
+ mail_service = camel_session_add_service (
+ session, mbox_uid, "mbox",
+ CAMEL_PROVIDER_STORE, &error);
+
+ if (error == NULL)
+ maildir_service = camel_session_add_service (
+ session, "local", "maildir",
+ CAMEL_PROVIDER_STORE, &error);
+
+ if (error != NULL) {
+ g_warning ("%s: %s", G_STRFUNC, error->message);
+ g_error_free (error);
+ return FALSE;
+ }
+
+ camel_service_set_settings (mail_service, settings);
+
+ settings = camel_service_get_settings (maildir_service);
+ path = g_build_filename (data_dir, "local", NULL);
+ g_object_set (settings, "path", path, NULL);
+ g_mkdir (path, 0700);
+ g_free (path);
+
+ mail_store = CAMEL_STORE (mail_service);
+ maildir_store = CAMEL_STORE (maildir_service);
+
+ ms.mail_store = mail_store;
+ ms.maildir_store = maildir_store;
+ ms.session = session;
+ ms.complete = FALSE;
+
+ g_thread_create ((GThreadFunc) migrate_stores, &ms, TRUE, NULL);
+ while (!ms.complete)
+ g_main_context_iteration (NULL, TRUE);
+
+ return TRUE;
+}
+
+void
+e_convert_local_mail (EShell *shell)
+{
+ CamelSession *session;
+ ESource *mbox_source;
+ const gchar *user_data_dir;
+ const gchar *user_cache_dir;
+ gchar *mail_data_dir;
+ gchar *mail_cache_dir;
+ gchar *local_store;
+ gint response;
+
+ user_data_dir = e_get_user_data_dir ();
+ user_cache_dir = e_get_user_cache_dir ();
+
+ mail_data_dir = g_build_filename (user_data_dir, "mail", NULL);
+ mail_cache_dir = g_build_filename (user_cache_dir, "mail", NULL);
+
+ if (!mail_to_maildir_migration_needed (mail_data_dir))
+ goto exit;
+
+ response = e_alert_run_dialog_for_args (
+ e_shell_get_active_window (NULL),
+ "mail:ask-migrate-store", NULL);
+
+ if (response == GTK_RESPONSE_CANCEL)
+ exit (EXIT_SUCCESS);
+
+ mbox_source = e_source_new (NULL, NULL, NULL);
+
+ rename_mail_dir (mbox_source, mail_data_dir);
+
+ local_store = g_build_filename (mail_data_dir, "local", NULL);
+
+ if (!g_file_test (local_store, G_FILE_TEST_EXISTS))
+ g_mkdir_with_parents (local_store, 0700);
+
+ g_free (local_store);
+
+ session = g_object_new (
+ CAMEL_TYPE_SESSION,
+ "online", FALSE,
+ "user-data-dir", mail_data_dir,
+ "user-cache-dir", mail_cache_dir,
+ NULL);
+
+ migrate_mail_to_maildir (shell, session, mbox_source);
+
+ g_object_unref (session);
+
+ g_object_unref (mbox_source);
+
+exit:
+ g_free (mail_data_dir);
+ g_free (mail_cache_dir);
+}
diff --git a/shell/main.c b/shell/main.c
index d6de1499e4..a19614d76c 100644
--- a/shell/main.c
+++ b/shell/main.c
@@ -114,6 +114,9 @@ static gchar *geometry = NULL;
static gchar *requested_view = NULL;
static gchar **remaining_args;
+/* Forward declarations */
+void e_convert_local_mail (EShell *shell);
+
static void
categories_icon_theme_hack (void)
{
@@ -644,6 +647,18 @@ main (gint argc,
goto exit;
}
+ /* This routine converts the local mail store from mbox format to
+ * Maildir format as needed. The reason the code is here and not
+ * in the mail module is because we inform the user at startup of
+ * the impending mail conversion by displaying a popup dialog and
+ * waiting for confirmation before proceeding.
+ *
+ * This has to be done before we load modules because some of the
+ * EShellBackends immediately add GMainContext sources that would
+ * otherwise get dispatched during gtk_dialog_run(), and we don't
+ * want them dispatched until after the conversion is complete. */
+ e_convert_local_mail (shell);
+
e_shell_load_modules (shell);
if (!disable_eplugin) {