diff options
author | Not Zed <NotZed@Ximian.com> | 2004-02-13 18:14:30 +0800 |
---|---|---|
committer | Michael Zucci <zucchi@src.gnome.org> | 2004-02-13 18:14:30 +0800 |
commit | 39f16a70161b982003faca8b1fea7845a4a4e5fc (patch) | |
tree | f757ae0e6cc6957336c07f49781b8bfc50b6f8bc /mail | |
parent | 1f4808666f7070789ada617b9fbb652d4e9512a0 (diff) | |
download | gsoc2013-evolution-39f16a70161b982003faca8b1fea7845a4a4e5fc.tar.gz gsoc2013-evolution-39f16a70161b982003faca8b1fea7845a4a4e5fc.tar.zst gsoc2013-evolution-39f16a70161b982003faca8b1fea7845a4a4e5fc.zip |
use mail-importer to import the mail tree, fix the account stuff to talk
2004-02-13 Not Zed <NotZed@Ximian.com>
* importers/netscape-importer.c: use mail-importer to import the
mail tree, fix the account stuff to talk directly to mail config.
Added cancel button. etc. This is completely untested apart from
compiling with no warnings.
* importers/mail-importer.c (import_mbox_import): dont re-use the
exception for syncing.
* importers/evolution-outlook-importer.c: major reworking. Some
platform fixes, runs in another thread, simpler/cleaner main loop.
This is completely untested apart from compiling with no warnings.
* importers/evolution-mbox-importer.c (support_format_fn): we dont
want to check the From_ line case insensitive!
(create_control_fn): implement this weird api.
2004-02-12 Not Zed <NotZed@Ximian.com>
* importers/elm-importer.c: rewrote all importing stuff.
* importers/mail-importer.c (mail_importer_import_folders_sync):
split out into a recursive function & entry. Now handles mozilla
format stuff with a flag.
(import_mbox_import): made the cameloperation properly
save/restore multiple registrations.
svn path=/trunk/; revision=24732
Diffstat (limited to 'mail')
-rw-r--r-- | mail/ChangeLog | 28 | ||||
-rw-r--r-- | mail/importers/elm-importer.c | 488 | ||||
-rw-r--r-- | mail/importers/evolution-mbox-importer.c | 350 | ||||
-rw-r--r-- | mail/importers/evolution-outlook-importer.c | 474 | ||||
-rw-r--r-- | mail/importers/mail-importer.c | 87 | ||||
-rw-r--r-- | mail/importers/mail-importer.h | 5 | ||||
-rw-r--r-- | mail/importers/netscape-importer.c | 712 | ||||
-rw-r--r-- | mail/importers/pine-importer.c | 18 |
8 files changed, 988 insertions, 1174 deletions
diff --git a/mail/ChangeLog b/mail/ChangeLog index 08b1efbce4..d22638b3e9 100644 --- a/mail/ChangeLog +++ b/mail/ChangeLog @@ -1,3 +1,31 @@ +2004-02-13 Not Zed <NotZed@Ximian.com> + + * importers/netscape-importer.c: use mail-importer to import the + mail tree, fix the account stuff to talk directly to mail config. + Added cancel button. etc. This is completely untested apart from + compiling with no warnings. + + * importers/mail-importer.c (import_mbox_import): dont re-use the + exception for syncing. + + * importers/evolution-outlook-importer.c: major reworking. Some + platform fixes, runs in another thread, simpler/cleaner main loop. + This is completely untested apart from compiling with no warnings. + + * importers/evolution-mbox-importer.c (support_format_fn): we dont + want to check the From_ line case insensitive! + (create_control_fn): implement this weird api. + +2004-02-12 Not Zed <NotZed@Ximian.com> + + * importers/elm-importer.c: rewrote all importing stuff. + + * importers/mail-importer.c (mail_importer_import_folders_sync): + split out into a recursive function & entry. Now handles mozilla + format stuff with a flag. + (import_mbox_import): made the cameloperation properly + save/restore multiple registrations. + 2004-02-12 Radek Doulik <rodo@ximian.com> * em-junk-filter.c (pipe_to_sa_with_error): use diff --git a/mail/importers/elm-importer.c b/mail/importers/elm-importer.c index 63f282fd48..2793f58f50 100644 --- a/mail/importers/elm-importer.c +++ b/mail/importers/elm-importer.c @@ -1,8 +1,8 @@ /* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ /* elm-importer.c * - * Authors: - * Iain Holmes <iain@ximian.com> + * Authors: Iain Holmes <iain@ximian.com> + * Michael Zucchi <notzed@ximian.com> * * Copyright 2001 Ximian, Inc. (www.ximian.com) * @@ -38,15 +38,10 @@ #include <gconf/gconf.h> #include <gconf/gconf-client.h> +#include <camel/camel-operation.h> + #include <bonobo/bonobo-object.h> #include <bonobo/bonobo-control.h> -#include <bonobo/bonobo-context.h> -#include <bonobo/bonobo-generic-factory.h> -#include <bonobo/bonobo-main.h> -#include <bonobo/bonobo-exception.h> -#include <bonobo/bonobo-moniker-util.h> - -#include <bonobo-activation/bonobo-activation.h> #include <importer/evolution-intelligent-importer.h> #include <importer/evolution-importer-client.h> @@ -54,6 +49,8 @@ #include "mail-importer.h" +#include "mail/mail-mt.h" + #define KEY "elm-mail-imported" /*#define SUPER_IMPORTER_DEBUG*/ @@ -66,33 +63,23 @@ typedef struct { EvolutionIntelligentImporter *ii; - GList *dir_list; + GHashTable *prefs; - int progress_count; - int more; - EvolutionImporterResult result; + GMutex *status_lock; + char *status_what; + int status_pc; + int status_timeout_id; + CamelOperation *cancel; /* cancel/status port */ - GNOME_Evolution_Importer importer; - EvolutionImporterListener *listener; - GtkWidget *mail; gboolean do_mail; + gboolean done_mail; GtkWidget *dialog; GtkWidget *label; GtkWidget *progressbar; } ElmImporter; -typedef struct { - char *parent; - char *foldername; - char *path; -} ElmFolder; - -static GHashTable *elm_prefs = NULL; - -static void import_next (ElmImporter *importer); - static GtkWidget * create_importer_gui (ElmImporter *importer) { @@ -103,7 +90,6 @@ create_importer_gui (ElmImporter *importer) importer->label = gtk_label_new (_("Please wait")); importer->progressbar = gtk_progress_bar_new (); - gtk_progress_set_activity_mode (GTK_PROGRESS (importer->progressbar), TRUE); gtk_box_pack_start (GTK_BOX (GNOME_DIALOG (dialog)->vbox), importer->label, FALSE, FALSE, 0); gtk_box_pack_start (GTK_BOX (GNOME_DIALOG (dialog)->vbox), importer->progressbar, FALSE, FALSE, 0); @@ -116,7 +102,7 @@ elm_store_settings (ElmImporter *importer) GConfClient *gconf; gconf = gconf_client_get_default (); - gconf_client_set_bool (gconf, "/apps/evolution/importer/elm/mail", importer->do_mail, NULL); + gconf_client_set_bool (gconf, "/apps/evolution/importer/elm/mail", importer->done_mail, NULL); g_object_unref(gconf); } @@ -125,110 +111,27 @@ elm_restore_settings (ElmImporter *importer) { GConfClient *gconf = gconf_client_get_default (); - importer->do_mail = gconf_client_get_bool (gconf, "/apps/evolution/importer/elm/mail", NULL); -} - -static void -importer_cb (EvolutionImporterListener *listener, - EvolutionImporterResult result, - gboolean more_items, - void *data) -{ - ElmImporter *importer = (ElmImporter *) data; - - importer->result = result; - importer->more = more_items; -} - -static gboolean -elm_import_file (ElmImporter *importer, - const char *path, - const char *folderpath) -{ - CORBA_boolean result; - CORBA_Environment ev; - CORBA_Object objref; - char *str, *uri; - struct stat st; - - str = g_strdup_printf (_("Importing %s as %s"), path, folderpath); - gtk_label_set_text (GTK_LABEL (importer->label), str); - g_free (str); - while (g_main_context_iteration(NULL, FALSE)) - ; - - uri = mail_importer_make_local_folder(folderpath); - if (!uri) - return FALSE; - - /* if its a dir, we just create it, but dont add anything */ - if (lstat(path, &st) == 0 && S_ISDIR(st.st_mode)) { - g_free(uri); - /* this is ok, we return false to say we haven't launched an async task */ - return FALSE; - } - - CORBA_exception_init(&ev); -#warning "loadFile needs a destination path" - - result = GNOME_Evolution_Importer_loadFile (importer->importer, path, &ev); - g_free(uri); - if (ev._major != CORBA_NO_EXCEPTION || result == FALSE) { - g_warning ("Exception here: %s", CORBA_exception_id (&ev)); - CORBA_exception_free (&ev); - return FALSE; - } - - /* process all items in a direct loop */ - importer->listener = evolution_importer_listener_new (importer_cb, importer); - objref = bonobo_object_corba_objref (BONOBO_OBJECT (importer->listener)); - do { - importer->progress_count++; - if ((importer->progress_count & 0xf) == 0) - gtk_progress_bar_pulse(GTK_PROGRESS_BAR(importer->progressbar)); - - importer->result = -1; - GNOME_Evolution_Importer_processItem (importer->importer, objref, &ev); - if (ev._major != CORBA_NO_EXCEPTION) { - g_warning ("Exception: %s", CORBA_exception_id (&ev)); - break; - } - - while (importer->result == -1 || g_main_context_pending(NULL)) - g_main_context_iteration(NULL, TRUE); - } while (importer->more); - - bonobo_object_unref((BonoboObject *)importer->listener); - - CORBA_exception_free (&ev); - - return FALSE; + importer->done_mail = gconf_client_get_bool (gconf, "/apps/evolution/importer/elm/mail", NULL); + g_object_unref(gconf); } static void -parse_elm_rc (const char *elmrc) +parse_elm_rc(ElmImporter *importer, const char *elmrc) { - static gboolean parsed = FALSE; char line[4096]; FILE *handle; - gboolean exists; - if (parsed == TRUE) + if (importer->prefs) return; - elm_prefs = g_hash_table_new (g_str_hash, g_str_equal); + importer->prefs = g_hash_table_new(g_str_hash, g_str_equal); - exists = g_file_exists (elmrc); - if (exists == FALSE) { - parsed = TRUE; + if (!g_file_exists(elmrc)) return; - } handle = fopen (elmrc, "r"); - if (handle == NULL) { - parsed = TRUE; + if (handle == NULL) return; - } while (fgets (line, 4096, handle) != NULL) { char *linestart, *end; @@ -264,183 +167,181 @@ parse_elm_rc (const char *elmrc) *end = 0; value = g_strdup (linestart); - g_hash_table_insert (elm_prefs, key, value); + g_hash_table_insert (importer->prefs, key, value); } - parsed = TRUE; fclose (handle); } static char * -elm_get_rc_value (const char *value) +elm_get_rc_value(ElmImporter *importer, const char *value) { - if (elm_prefs == NULL) - return NULL; - - return g_hash_table_lookup (elm_prefs, value); + return g_hash_table_lookup(importer->prefs, value); } static gboolean -elm_can_import (EvolutionIntelligentImporter *ii, - void *closure) +elm_can_import(EvolutionIntelligentImporter *ii, void *closure) { ElmImporter *importer = closure; - char *elmdir, *maildir, *aliasfile; - char *elmrc; - gboolean exists, mailexists, aliasexists; - gboolean mail; + const char *maildir; + char *elmdir, *elmrc; + gboolean mailexists, exists; +#if 0 + char *aliasfile; + gboolean aliasexists; +#endif struct stat st; - GConfClient *gconf = gconf_client_get_default(); - mail = gconf_client_get_bool(gconf, "/apps/evolution/importer/elm/mail-imported", NULL); - if (mail) - return FALSE; - - importer->do_mail = !mail; - gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (importer->mail), - importer->do_mail); + elm_restore_settings(importer); + + importer->do_mail = !importer->done_mail; + gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (importer->mail), importer->do_mail); - elmdir = gnome_util_prepend_user_home (".elm"); + elmdir = g_build_filename(g_get_home_dir(), ".elm", NULL); exists = lstat(elmdir, &st) == 0 && S_ISDIR(st.st_mode); - g_free (elmdir); - if (exists == FALSE) + if (!exists) return FALSE; - elmrc = gnome_util_prepend_user_home (".elm/elmrc"); - parse_elm_rc (elmrc); + elmrc = g_build_filename(g_get_home_dir(), ".elm/elmrc", NULL); + parse_elm_rc (importer, elmrc); + g_free(elmrc); - maildir = elm_get_rc_value ("maildir"); - if (maildir == NULL) { - maildir = g_strdup ("Mail"); - } else { - maildir = g_strdup (maildir); - } + maildir = elm_get_rc_value(importer, "maildir"); + if (maildir == NULL) + maildir = "Mail"; - if (!g_path_is_absolute (maildir)) { - elmdir = gnome_util_prepend_user_home (maildir); - } else { + if (!g_path_is_absolute (maildir)) + elmdir = g_build_filename(g_get_home_dir(), maildir, NULL); + else elmdir = g_strdup (maildir); - } - - g_free (maildir); mailexists = lstat(elmdir, &st) == 0 && S_ISDIR(st.st_mode); g_free (elmdir); +#if 0 aliasfile = gnome_util_prepend_user_home (".elm/aliases"); aliasexists = lstat(aliasfile, &st) == 0 && S_ISREG(st.st_mode); g_free (aliasfile); exists = (aliasexists || mailexists); +#endif - return exists; + return mailexists; } -static void -import_next (ElmImporter *importer) +/* Almost all that follows is a direct copy of pine-importer.c with + * search and replace run on it */ +struct _elm_import_msg { + struct _mail_msg msg; + + ElmImporter *importer; +}; + +static char * +elm_import_describe (struct _mail_msg *mm, int complete) { - ElmFolder *data; + return g_strdup (_("Importing Elm data")); +} -trynext: - if (importer->dir_list) { - char *folder; - GList *l; - int ok; +static MailImporterSpecial elm_special_folders[] = { + { "received", "Inbox" }, + { 0 }, +}; - l = importer->dir_list; - data = l->data; +static void +elm_import_import(struct _mail_msg *mm) +{ + struct _elm_import_msg *m = (struct _elm_import_msg *) mm; - folder = g_concat_dir_and_file (data->parent, data->foldername); + if (m->importer->do_mail) { + const char *maildir; + char *elmdir; - importer->dir_list = l->next; - g_list_free_1(l); + maildir = elm_get_rc_value(m->importer, "maildir"); + if (maildir == NULL) + maildir = "Mail"; - ok = elm_import_file (importer, data->path, folder); - g_free (folder); - g_free (data->parent); - g_free (data->path); - g_free (data->foldername); - g_free (data); - /* its ugly, but so is everything else in this file */ - if (!ok) - goto trynext; - } else { - bonobo_object_unref((BonoboObject *)importer->ii); + if (!g_path_is_absolute(maildir)) + elmdir = g_build_filename(g_get_home_dir(), maildir, NULL); + else + elmdir = g_strdup(maildir); + + mail_importer_import_folders_sync(elmdir, elm_special_folders, 0, m->importer->cancel); } } static void -scan_dir (ElmImporter *importer, - const char *orig_parent, - const char *dirname) +elm_import_imported(struct _mail_msg *mm) { - DIR *maildir; - struct stat buf; - struct dirent *current; - char *str; - - maildir = opendir (dirname); - if (maildir == NULL) { - g_warning ("Could not open %s\nopendir returned: %s", - dirname, g_strerror (errno)); - return; - } +} + +static void +elm_import_free(struct _mail_msg *mm) +{ + /*struct _elm_import_msg *m = (struct _elm_import_msg *)mm;*/ +} + +static struct _mail_msg_op elm_import_op = { + elm_import_describe, + elm_import_import, + elm_import_imported, + elm_import_free, +}; + +static int +mail_importer_elm_import(ElmImporter *importer) +{ + struct _elm_import_msg *m; + int id; + + m = mail_msg_new(&elm_import_op, NULL, sizeof (*m)); + m->importer = importer; + + id = m->msg.seq; - str = g_strdup_printf (_("Scanning %s"), dirname); - gtk_label_set_text (GTK_LABEL (importer->label), str); - g_free (str); + e_thread_put(mail_thread_queued, (EMsg *) m); - while (gtk_events_pending ()) { - gtk_main_iteration (); - } + return id; +} - current = readdir (maildir); - while (current) { - ElmFolder *pf; - char *fullname; - - /* Ignore . and .. */ - if (current->d_name[0] == '.') { - if (current->d_name[1] == '\0' || - (current->d_name[1] == '.' && current->d_name[2] == '\0')) { - current = readdir (maildir); - continue; - } - } - - fullname = g_concat_dir_and_file (dirname, current->d_name); - if (stat (fullname, &buf) == -1) { - g_warning ("Could not stat %s\nstat returned: %s", - fullname, g_strerror (errno)); - current = readdir (maildir); - g_free (fullname); - continue; - } - - if (S_ISREG (buf.st_mode)) { - pf = g_new (ElmFolder, 1); - pf->path = g_strdup (fullname); - pf->parent = g_strdup (orig_parent); - pf->foldername = g_strdup (current->d_name); - importer->dir_list = g_list_append (importer->dir_list, pf); - } else if (S_ISDIR (buf.st_mode)) { - char *subdir; - - pf = g_new (ElmFolder, 1); - pf->path = NULL; - pf->parent = g_strdup (orig_parent); - pf->foldername = g_strdup (current->d_name); - importer->dir_list = g_list_append (importer->dir_list, pf); - - subdir = g_concat_dir_and_file (orig_parent, current->d_name); - scan_dir (importer, subdir, fullname); - g_free (subdir); - } - - g_free (fullname); - current = readdir (maildir); - } +static void +elm_status(CamelOperation *op, const char *what, int pc, void *data) +{ + ElmImporter *importer = data; + + if (pc == CAMEL_OPERATION_START) + pc = 0; + else if (pc == CAMEL_OPERATION_END) + pc = 100; + + g_mutex_lock(importer->status_lock); + g_free(importer->status_what); + importer->status_what = g_strdup(what); + importer->status_pc = pc; + g_mutex_unlock(importer->status_lock); +} + +static gboolean +elm_status_timeout(void *data) +{ + ElmImporter *importer = data; + int pc; + char *what; + + if (!importer->status_what) + return TRUE; + + g_mutex_lock(importer->status_lock); + what = importer->status_what; + importer->status_what = NULL; + pc = importer->status_pc; + g_mutex_unlock(importer->status_lock); + + gtk_progress_bar_set_fraction((GtkProgressBar *)importer->progressbar, (gfloat)(pc/100.0)); + gtk_progress_bar_set_text((GtkProgressBar *)importer->progressbar, what); + + return TRUE; } static void @@ -448,60 +349,53 @@ elm_create_structure (EvolutionIntelligentImporter *ii, void *closure) { ElmImporter *importer = closure; - char *maildir; - /* Reference our object so when the shell release_unrefs us - we will still exist and not go byebye */ - bonobo_object_ref (BONOBO_OBJECT (ii)); + if (importer->do_mail) { + importer->dialog = create_importer_gui(importer); + gtk_widget_show_all(importer->dialog); + importer->status_timeout_id = g_timeout_add(100, elm_status_timeout, importer); + importer->cancel = camel_operation_new(elm_status, importer); - elm_store_settings (importer); - - if (importer->do_mail == TRUE) { - char *elmdir; - GConfClient *gconf = gconf_client_get_default(); + mail_msg_wait(mail_importer_elm_import(importer)); - importer->dialog = create_importer_gui (importer); - gtk_widget_show_all (importer->dialog); - while (gtk_events_pending ()) { - gtk_main_iteration (); - } + camel_operation_unref(importer->cancel); + g_source_remove(importer->status_timeout_id); + importer->status_timeout_id = 0; - gconf_client_set_bool(gconf, "/apps/evolution/importer/elm/mail-imported", TRUE, NULL); - - maildir = elm_get_rc_value ("maildir"); - if (maildir == NULL) { - maildir = g_strdup ("Mail"); - } else { - maildir = g_strdup (maildir); - } - - if (!g_path_is_absolute (maildir)) { - elmdir = gnome_util_prepend_user_home (maildir); - } else { - elmdir = g_strdup (maildir); - } - - g_free (maildir); - - scan_dir (importer, "/", elmdir); - g_free (elmdir); - - /* Import them */ - import_next (importer); + importer->done_mail = TRUE; } + elm_store_settings (importer); + bonobo_object_unref (BONOBO_OBJECT (ii)); } static void +free_pref(void *key, void *value, void *data) +{ + g_free(key); + g_free(value); +} + +static void elm_destroy_cb (ElmImporter *importer, GtkObject *object) { - elm_store_settings (importer); + elm_store_settings(importer); + + if (importer->status_timeout_id) + g_source_remove(importer->status_timeout_id); + g_free(importer->status_what); + g_mutex_free(importer->status_lock); if (importer->dialog) gtk_widget_destroy(importer->dialog); - bonobo_object_release_unref (importer->importer, NULL); + if (importer->prefs) { + g_hash_table_foreach(importer->prefs, free_pref, NULL); + g_hash_table_destroy(importer->prefs); + } + + g_free(importer); } /* Fun initialisation stuff */ @@ -539,26 +433,12 @@ elm_intelligent_importer_new(void) EvolutionIntelligentImporter *importer; BonoboControl *control; ElmImporter *elm; - CORBA_Environment ev; char *message = N_("Evolution has found Elm mail files\n" "Would you like to import them into Evolution?"); elm = g_new0 (ElmImporter, 1); - - CORBA_exception_init (&ev); - + elm->status_lock = g_mutex_new(); elm_restore_settings (elm); - - elm->importer = bonobo_activation_activate_from_id (MBOX_IMPORTER_IID, 0, NULL, &ev); - if (ev._major != CORBA_NO_EXCEPTION) { - g_free (elm); - g_warning ("Could not start MBox importer\n%s", - CORBA_exception_id (&ev)); - CORBA_exception_free (&ev); - return NULL; - } - CORBA_exception_free (&ev); - importer = evolution_intelligent_importer_new (elm_can_import, elm_create_structure, _("Elm"), @@ -566,8 +446,8 @@ elm_intelligent_importer_new(void) g_object_weak_ref(G_OBJECT (importer), (GWeakNotify)elm_destroy_cb, elm); elm->ii = importer; - control = create_checkboxes_control (elm); - bonobo_object_add_interface (BONOBO_OBJECT (importer), - BONOBO_OBJECT (control)); - return BONOBO_OBJECT (importer); + control = create_checkboxes_control(elm); + bonobo_object_add_interface(BONOBO_OBJECT(importer), BONOBO_OBJECT(control)); + + return BONOBO_OBJECT(importer); } diff --git a/mail/importers/evolution-mbox-importer.c b/mail/importers/evolution-mbox-importer.c index a7691b38f0..7e830a207a 100644 --- a/mail/importers/evolution-mbox-importer.c +++ b/mail/importers/evolution-mbox-importer.c @@ -2,8 +2,10 @@ /* evolution-mbox-importer.c * * Authors: Iain Holmes <iain@ximian.com> + * Michael Zucchi <notzed@ximian.com> * - * Copyright (C) 2001 Ximian, Inc. + * Copyright (C) 2001 Ximian, Inc. + * Copyright (C) 2004 Novell, Inc. * * This program is free software; you can redistribute it and/or * modify it under the terms of version 2 of the GNU General Public @@ -24,25 +26,31 @@ #include <config.h> #endif +#include <sys/types.h> +#include <sys/stat.h> +#include <fcntl.h> +#include <unistd.h> + #include <stdio.h> #include <ctype.h> #include <string.h> -#include <bonobo/bonobo-object.h> -#include <bonobo/bonobo-generic-factory.h> +#include <gtk/gtkhbox.h> +#include <gtk/gtklabel.h> +#include <gtk/gtkmessagedialog.h> +#include <gtk/gtkprogressbar.h> + +#include <bonobo/bonobo-control.h> #include <camel/camel-exception.h> -#include <camel/camel-mime-message.h> -#include <camel/camel-mime-parser.h> -#include <camel/camel-mime-part.h> #include <importer/evolution-importer.h> #include <importer/GNOME_Evolution_Importer.h> -#include "mail/mail-tools.h" -#include "mail/mail-component.h" +#include "mail/em-folder-selection-button.h" -#include "e-util/e-path.h" +#include "mail/mail-component.h" +#include "mail/mail-mt.h" #include "mail-importer.h" @@ -56,252 +64,188 @@ #endif typedef struct { - MailImporter importer; /* Parent */ + EvolutionImporter *ii; - char *filename; - int num; + GMutex *status_lock; + char *status_what; + int status_pc; + int status_timeout_id; + CamelOperation *cancel; /* cancel/status port */ - CamelMimeParser *mp; - gboolean is_folder; -} MboxImporter; + GtkWidget *selector; + GtkWidget *label; + GtkWidget *progressbar; + GtkWidget *dialog; -/* EvolutionImporter methods */ + char *uri; +} MboxImporter; -static CamelMessageInfo * -get_info_from_mozilla (const char *mozilla_status, - gboolean *deleted) +static void +process_item_fn(EvolutionImporter *eimporter, CORBA_Object listener, void *data, CORBA_Environment *ev) { - unsigned int status; - CamelMessageInfo *info; - - *deleted = FALSE; - - status = strtoul (mozilla_status, NULL, 16); - if (status == 0) { - return camel_message_info_new (); - } - - if (status & MSG_FLAG_EXPUNGED) { - *deleted = TRUE; - - return NULL; - } - - info = camel_message_info_new (); - - if (status & MSG_FLAG_READ) - info->flags |= CAMEL_MESSAGE_SEEN; - - if (status & MSG_FLAG_MARKED) - info->flags |= CAMEL_MESSAGE_FLAGGED; - - if (status & MSG_FLAG_REPLIED) - info->flags |= CAMEL_MESSAGE_ANSWERED; - - return info; + /*MboxImporter *importer = data;*/ + GNOME_Evolution_ImporterListener_ImporterResult result; + + /* This is essentially a NOOP, it merely returns ok/fail and is only called once */ + +#if 0 + if (camel_exception_is_set(importer->ex)) + result = GNOME_Evolution_ImporterListener_BAD_FILE; + else +#endif + result = GNOME_Evolution_ImporterListener_OK; + + GNOME_Evolution_ImporterListener_notifyResult(listener, result, FALSE, ev); } static void -process_item_fn (EvolutionImporter *eimporter, - CORBA_Object listener, - void *closure, - CORBA_Environment *ev) +folder_selected(EMFolderSelectionButton *button, MboxImporter *importer) { - MboxImporter *mbi = (MboxImporter *) closure; - MailImporter *importer = (MailImporter *) mbi; - gboolean done = FALSE; - CamelException *ex; - const char *mozilla_status; - - if (importer->folder == NULL) { - GNOME_Evolution_ImporterListener_notifyResult (listener, - GNOME_Evolution_ImporterListener_BAD_FILE, - FALSE, ev); - } + g_free(importer->uri); + importer->uri = g_strdup(em_folder_selection_button_get_selection(button)); +} - if (mbi->is_folder == TRUE) { - GNOME_Evolution_ImporterListener_notifyResult (listener, - GNOME_Evolution_ImporterListener_OK, - FALSE, ev); - return; - } - - ex = camel_exception_new (); - if (camel_mime_parser_step (mbi->mp, 0, 0) == CAMEL_MIME_PARSER_STATE_FROM) { - /* Import the next message */ - CamelMimeMessage *msg; - CamelMessageInfo *info; - gboolean deleted; - - IN; - msg = camel_mime_message_new (); - if (camel_mime_part_construct_from_parser (CAMEL_MIME_PART (msg), mbi->mp) == -1) { - g_warning ("Failed message %d", mbi->num); - camel_object_unref (CAMEL_OBJECT (msg)); - done = TRUE; - } else { - mozilla_status = camel_medium_get_header (CAMEL_MEDIUM (msg), "X-Mozilla-Status"); - if (mozilla_status != NULL) { - info = get_info_from_mozilla (mozilla_status, &deleted); - } else { - deleted = FALSE; - info = camel_message_info_new (); - } - - if (deleted == FALSE) { - /* write the mesg */ - camel_folder_append_message (importer->folder, msg, info, NULL, ex); - } - - if (info) - camel_message_info_free (info); - - camel_object_unref (msg); - if (camel_exception_is_set (ex)) { - g_warning ("Failed message %d", mbi->num); - done = TRUE; - } - } - OUT; - } else { - IN; - /* all messages have now been imported */ - camel_folder_sync (importer->folder, FALSE, ex); - camel_folder_thaw (importer->folder); - importer->frozen = FALSE; - done = TRUE; - OUT; - } - - if (!done) - camel_mime_parser_step (mbi->mp, 0, 0); +static void +create_control_fn(EvolutionImporter *importer, Bonobo_Control *control, void *data) +{ + GtkWidget *hbox, *w; - camel_exception_free (ex); + hbox = gtk_hbox_new(FALSE, FALSE); + + w = gtk_label_new(_("Destination folder:")); + gtk_box_pack_start((GtkBox *)hbox, w, FALSE, TRUE, 6); + + w = em_folder_selection_button_new(_("Select folder"), _("Select folder to import into")); + /* set selection to Inbox? */ + g_signal_connect(w, "selected", G_CALLBACK(folder_selected), data); + gtk_box_pack_start((GtkBox *)hbox, w, FALSE, TRUE, 6); + + gtk_widget_show_all(hbox); - GNOME_Evolution_ImporterListener_notifyResult (listener, - GNOME_Evolution_ImporterListener_OK, - !done, ev); - return; + /* Another weird-arsed shell api */ + *control = BONOBO_OBJREF(bonobo_control_new(hbox)); } static gboolean -support_format_fn (EvolutionImporter *importer, - const char *filename, - void *closure) +support_format_fn(EvolutionImporter *importer, const char *filename, void *closure) { char signature[6]; gboolean ret = FALSE; int fd, n; - fd = open (filename, O_RDONLY); - if (fd == -1) - return FALSE; - - n = read (fd, signature, 5); - if (n > 0) { - signature[n] = '\0'; - if (!g_strncasecmp (signature, "From ", 5)) - ret = TRUE; + fd = open(filename, O_RDONLY); + if (fd != -1) { + n = read(fd, signature, 5); + ret = n == 5 && memcmp(signature, "From ", 5) == 0; + close(fd); } - close (fd); - return ret; } static void -importer_destroy_cb (void *data, GObject *object) +importer_destroy_cb(void *data, GObject *object) { - MboxImporter *mbi = data; - MailImporter *importer = data; + MboxImporter *importer = data; - if (importer->folder) { - if (importer->frozen) { - camel_folder_sync (importer->folder, FALSE, NULL); - camel_folder_thaw (importer->folder); - } + if (importer->status_timeout_id) + g_source_remove(importer->status_timeout_id); + g_free(importer->status_what); + g_mutex_free(importer->status_lock); - camel_object_unref (importer->folder); - } + if (importer->dialog) + gtk_widget_destroy(importer->dialog); - g_free (mbi->filename); - if (mbi->mp) - camel_object_unref (mbi->mp); + g_free(importer); +} - g_free (mbi); +static void +mbox_status(CamelOperation *op, const char *what, int pc, void *data) +{ + MboxImporter *importer = data; + + if (pc == CAMEL_OPERATION_START) + pc = 0; + else if (pc == CAMEL_OPERATION_END) + pc = 100; + + g_mutex_lock(importer->status_lock); + g_free(importer->status_what); + importer->status_what = g_strdup(what); + importer->status_pc = pc; + g_mutex_unlock(importer->status_lock); } static gboolean -load_file_fn (EvolutionImporter *eimporter, - const char *filename, - void *closure) +mbox_status_timeout(void *data) { - MboxImporter *mbi; - MailImporter *importer; - struct stat buf; - int fd; - char *uri; + MboxImporter *importer = data; + int pc; + char *what; - mbi = (MboxImporter *) closure; - importer = (MailImporter *) mbi; + if (!importer->status_what) + return TRUE; - mbi->filename = g_strdup (filename); + g_mutex_lock(importer->status_lock); + what = importer->status_what; + importer->status_what = NULL; + pc = importer->status_pc; + g_mutex_unlock(importer->status_lock); - fd = open (filename, O_RDONLY); - if (fd == -1) { - g_warning ("Cannot open file"); - return FALSE; - } + gtk_progress_bar_set_fraction((GtkProgressBar *)importer->progressbar, (gfloat)(pc/100.0)); + gtk_progress_bar_set_text((GtkProgressBar *)importer->progressbar, what); + + return TRUE; +} - fstat (fd, &buf); - if (S_ISREG (buf.st_mode)) { - mbi->mp = camel_mime_parser_new (); - camel_mime_parser_scan_from (mbi->mp, TRUE); - if (camel_mime_parser_init_with_fd (mbi->mp, fd) == -1) { - g_warning ("Unable to process spool folder"); - goto fail; - } - mbi->is_folder = FALSE; - } else { - mbi->is_folder = TRUE; - } +static void +mbox_importer_response(GtkWidget *w, guint button, void *data) +{ + MboxImporter *importer = data; - importer->mstream = NULL; -#warning "No destination uri" - uri = NULL; - if (uri == NULL || *uri == '\0') - importer->folder = mail_component_get_folder(NULL, MAIL_COMPONENT_FOLDER_INBOX); - else - importer->folder = mail_tool_uri_to_folder(uri, 0, NULL); + if (button == GTK_RESPONSE_CANCEL + && importer->cancel) + camel_operation_cancel(importer->cancel); +} - if (importer->folder == NULL) { - g_warning ("Bad folder\n"); - goto fail; - } +static gboolean +load_file_fn(EvolutionImporter *eimporter, const char *filename, void *data) +{ + MboxImporter *importer = data; - if (importer->folder != NULL) { - camel_folder_freeze (importer->folder); - importer->frozen = TRUE; - } + importer->dialog = gtk_message_dialog_new(NULL, 0/*GTK_DIALOG_NO_SEPARATOR*/, + GTK_MESSAGE_INFO, GTK_BUTTONS_CANCEL, + _("Importing `%s'"), filename); + gtk_window_set_title (GTK_WINDOW (importer->dialog), _("Importing...")); - return TRUE; + importer->label = gtk_label_new (_("Please wait")); + importer->progressbar = gtk_progress_bar_new (); + gtk_box_pack_start (GTK_BOX (GTK_DIALOG (importer->dialog)->vbox), importer->label, FALSE, FALSE, 0); + gtk_box_pack_start (GTK_BOX (GTK_DIALOG (importer->dialog)->vbox), importer->progressbar, FALSE, FALSE, 0); + g_signal_connect(importer->dialog, "response", G_CALLBACK(mbox_importer_response), importer); + gtk_widget_show_all(importer->dialog); - fail: - camel_object_unref (mbi->mp); - mbi->mp = NULL; + importer->status_timeout_id = g_timeout_add(100, mbox_status_timeout, importer); + importer->cancel = camel_operation_new(mbox_status, importer); - return FALSE; + mail_msg_wait(mail_importer_import_mbox(filename, importer->uri, importer->cancel)); + + camel_operation_unref(importer->cancel); + g_source_remove(importer->status_timeout_id); + importer->status_timeout_id = 0; + + return TRUE; } BonoboObject * mbox_importer_new(void) { - EvolutionImporter *importer; MboxImporter *mbox; mbox = g_new0 (MboxImporter, 1); - importer = evolution_importer_new(NULL, support_format_fn, load_file_fn, process_item_fn, NULL, mbox); - g_object_weak_ref(G_OBJECT(importer), importer_destroy_cb, mbox); + mbox->status_lock = g_mutex_new(); + mbox->ii = evolution_importer_new(create_control_fn, support_format_fn, load_file_fn, process_item_fn, NULL, mbox); + g_object_weak_ref(G_OBJECT(mbox->ii), importer_destroy_cb, mbox); - return BONOBO_OBJECT (importer); + return BONOBO_OBJECT (mbox->ii); } diff --git a/mail/importers/evolution-outlook-importer.c b/mail/importers/evolution-outlook-importer.c index 8233c82ca5..3a8b334ba8 100644 --- a/mail/importers/evolution-outlook-importer.c +++ b/mail/importers/evolution-outlook-importer.c @@ -20,46 +20,68 @@ * Boston, MA 02111-1307, USA. */ - #ifdef HAVE_CONFIG_H #include <config.h> #endif -#include <bonobo/bonobo-object.h> -#include <bonobo/bonobo-generic-factory.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <fcntl.h> +#include <unistd.h> +#include <errno.h> #include <stdio.h> +#include <ctype.h> +#include <string.h> + +#include <gtk/gtkhbox.h> +#include <gtk/gtklabel.h> +#include <gtk/gtkmessagedialog.h> +#include <gtk/gtkprogressbar.h> + +#include <bonobo/bonobo-control.h> + +#include <camel/camel-exception.h> +#include <camel/camel-folder.h> +#include <camel/camel-stream-mem.h> +#include <camel/camel-store.h> #include <importer/evolution-importer.h> #include <importer/GNOME_Evolution_Importer.h> -#include <camel/camel-exception.h> +#include "mail/em-folder-selection-button.h" -#include "e-util/e-memory.h" -#include "mail/mail-tools.h" #include "mail/mail-component.h" +#include "mail/mail-mt.h" +#include "mail/mail-tools.h" #include "mail-importer.h" -extern char *evolution_dir; +static int mail_importer_import_outlook(const char *path, const char *folderuri, CamelOperation *cancel); + typedef struct { - MailImporter importer; + EvolutionImporter *ii; - char *filename; - gboolean oe4; /* Is file OE4 or not? */ - FILE *handle; - long pos; - off_t size; + GMutex *status_lock; + char *status_what; + int status_pc; + int status_timeout_id; + CamelOperation *cancel; /* cancel/status port */ + + GtkWidget *selector; + GtkWidget *label; + GtkWidget *progressbar; + GtkWidget *dialog; - gboolean busy; + char *uri; } OutlookImporter; struct oe_msg_segmentheader { - int self; - int increase; - int include; - int next; - int usenet; + gint32 self; + gint32 increase; + gint32 include; + gint32 next; + gint32 usenet; }; typedef struct oe_msg_segmentheader oe_msg_segmentheader; @@ -73,104 +95,19 @@ typedef struct oe_msg_segmentheader oe_msg_segmentheader; Copyright (C) 2001 Ximian, Inc. */ static void -process_item_fn (EvolutionImporter *eimporter, - CORBA_Object listener, - void *closure, - CORBA_Environment *ev) +process_item_fn(EvolutionImporter *eimporter, CORBA_Object listener, void *data, CORBA_Environment *ev) { - OutlookImporter *oli = (OutlookImporter *) closure; - MailImporter *importer = (MailImporter *) oli; - oe_msg_segmentheader *header; - gboolean more = TRUE; - char *cb, *sfull, *s; - long end_pos = 0; - int i; - - if (oli->busy == TRUE) { - GNOME_Evolution_ImporterListener_notifyResult (listener, - GNOME_Evolution_ImporterListener_BUSY, - more, ev); - return; - } - - oli->busy = TRUE; - header = g_new (oe_msg_segmentheader, 1); - fread (header, 16, 1, oli->handle); - - /* Write a From line */ - mail_importer_add_line (importer, - "From evolution-outlook-importer", FALSE); - end_pos = oli->pos + header->include; - if (end_pos >= oli->size) { - end_pos = oli->size; - more = FALSE; - } - - oli->pos += 4; - - cb = g_new (char, 4); - sfull = g_new (char, 65536); - s = sfull; - - while (oli->pos < end_pos) { - fread (cb, 1, 4, oli->handle); - for (i = 0; i < 4; i++, oli->pos++) { - if (*(cb + i ) != 0x0d) { - *s++ = *(cb + i); - - if (*(cb + i) == 0x0a) { - *s = '\0'; - mail_importer_add_line (importer, - sfull, FALSE); - s = sfull; - } - } - } - } - - if (s != sfull) { - *s = '\0'; - mail_importer_add_line (importer, sfull, FALSE); - s = sfull; - } - - mail_importer_add_line (importer, "\n", TRUE); - - oli->pos = end_pos; - fseek (oli->handle, oli->pos, SEEK_SET); - - g_free (header); - g_free (sfull); - g_free (cb); - - GNOME_Evolution_ImporterListener_notifyResult (listener, - GNOME_Evolution_ImporterListener_OK, - more, ev); - if (more == FALSE) { - CamelException *ex; - - ex = camel_exception_new (); - camel_folder_thaw (importer->folder); - camel_folder_sync (importer->folder, FALSE, ex); - camel_exception_free (ex); - fclose (oli->handle); - oli->handle = NULL; - } - - oli->busy = FALSE; - return; } /* EvolutionImporterFactory methods */ static gboolean -support_format_fn (EvolutionImporter *importer, - const char *filename, - void *closure) +support_format_fn(EvolutionImporter *importer, const char *filename, void *data) { FILE *handle; - int signature[4]; + guint32 signature[4]; + int ok; /* Outlook Express sniffer. Taken from liboe 0.92 (STABLE) @@ -181,96 +118,118 @@ support_format_fn (EvolutionImporter *importer, return FALSE; /* Can't open file: Can't support it :) */ /* SIGNATURE */ - fread (&signature, 16, 1, handle); - if ((signature[0]!=0xFE12ADCF) || /* OE 5 & OE 5 BETA SIGNATURE */ - (signature[1]!=0x6F74FDC5) || - (signature[2]!=0x11D1E366) || - (signature[3]!=0xC0004E9A)) { - if ((signature[0]==0x36464D4A) && - (signature[1]==0x00010003)) /* OE4 SIGNATURE */ { - fclose (handle); - return TRUE; /* OE 4 */ - } - fclose (handle); - return FALSE; /* Not Outlook 4 or 5 */ - } + fread (&signature, 16, 1, handle); + /* This needs testing */ +#if G_BYTE_ORDER == G_BIG_ENDIAN + signature[0] = GUINT32_TO_BE(signature[0]); + signature[1] = GUINT32_TO_BE(signature[1]); + signature[2] = GUINT32_TO_BE(signature[2]); + signature[3] = GUINT32_TO_BE(signature[3]); +#endif + ok = ((signature[0]!=0xFE12ADCF /* OE 5 & OE 5 BETA SIGNATURE */ + || signature[1]!=0x6F74FDC5 + || signature[2]!=0x11D1E366 + || signature[3]!=0xC0004E9A) + && (signature[0]==0x36464D4A /* OE4 SIGNATURE */ + && signature[1]==0x00010003)); fclose (handle); - return FALSE; /* Can't handle OE 5 yet */ + return ok; /* Can't handle OE 5 yet */ } +/* Note the similarity of most of this code to evolution-mbox-importer. + Yes it should be subclassed, or something ... */ static void -importer_destroy_cb (void *data, GObject *object) +importer_destroy_cb(void *data, GObject *object) { - OutlookImporter *oli = data; - MailImporter *importer = data; + OutlookImporter *importer = data; - if (importer->folder) - camel_object_unref (importer->folder); + if (importer->status_timeout_id) + g_source_remove(importer->status_timeout_id); + g_free(importer->status_what); + g_mutex_free(importer->status_lock); - g_free (oli->filename); - if (oli->handle) - fclose (oli->handle); + if (importer->dialog) + gtk_widget_destroy(importer->dialog); - g_free (oli); + g_free(importer); +} + +static void +outlook_status(CamelOperation *op, const char *what, int pc, void *data) +{ + OutlookImporter *importer = data; + + if (pc == CAMEL_OPERATION_START) + pc = 0; + else if (pc == CAMEL_OPERATION_END) + pc = 100; + + g_mutex_lock(importer->status_lock); + g_free(importer->status_what); + importer->status_what = g_strdup(what); + importer->status_pc = pc; + g_mutex_unlock(importer->status_lock); } static gboolean -load_file_fn (EvolutionImporter *eimporter, - const char *filename, - void *closure) +outlook_status_timeout(void *data) { - OutlookImporter *oli; - MailImporter *importer; - struct stat buf; - long pos = 0x54; - char *uri; + OutlookImporter *importer = data; + int pc; + char *what; - oli = (OutlookImporter *) closure; - importer = (MailImporter *) oli; + if (!importer->status_what) + return TRUE; - oli->filename = g_strdup (filename); - /* Will return TRUE if oe4 format */ - oli->oe4 = support_format_fn (NULL, filename, NULL); - if (oli->oe4 == FALSE) { - g_warning ("Not OE4 format"); - return FALSE; - } + g_mutex_lock(importer->status_lock); + what = importer->status_what; + importer->status_what = NULL; + pc = importer->status_pc; + g_mutex_unlock(importer->status_lock); - oli->handle = fopen (filename, "rb"); - if (oli->handle == NULL) { - g_warning ("Cannot open the file"); - return FALSE; - } - - /* Get size of file */ - if (stat (filename, &buf) == -1) { - g_warning ("Cannot stat file"); - return FALSE; - } + gtk_progress_bar_set_fraction((GtkProgressBar *)importer->progressbar, (gfloat)(pc/100.0)); + gtk_progress_bar_set_text((GtkProgressBar *)importer->progressbar, what); - oli->size = buf.st_size; + return TRUE; +} - /* Set the fposition to the begining */ - fseek (oli->handle, pos, SEEK_SET); - oli->pos = pos; +static void +outlook_importer_response(GtkWidget *w, guint button, void *data) +{ + OutlookImporter *importer = data; - importer->mstream = NULL; + if (button == GTK_RESPONSE_CANCEL + && importer->cancel) + camel_operation_cancel(importer->cancel); +} -#warning "no uri for load file fn" - uri = NULL; - if (uri == NULL || *uri == 0) - importer->folder = mail_component_get_folder(NULL, MAIL_COMPONENT_FOLDER_INBOX); - else - importer->folder = mail_tool_uri_to_folder (uri, 0, NULL); +static gboolean +load_file_fn(EvolutionImporter *eimporter, const char *filename, void *data) +{ + OutlookImporter *importer = data; - if (importer->folder == NULL){ - g_warning ("Bad folder"); - return FALSE; - } + importer->dialog = gtk_message_dialog_new(NULL, 0/*GTK_DIALOG_NO_SEPARATOR*/, + GTK_MESSAGE_INFO, GTK_BUTTONS_CANCEL, + _("Importing `%s'"), filename); + gtk_window_set_title (GTK_WINDOW (importer->dialog), _("Importing...")); + + importer->label = gtk_label_new (_("Please wait")); + importer->progressbar = gtk_progress_bar_new (); + gtk_box_pack_start (GTK_BOX (GTK_DIALOG (importer->dialog)->vbox), importer->label, FALSE, FALSE, 0); + gtk_box_pack_start (GTK_BOX (GTK_DIALOG (importer->dialog)->vbox), importer->progressbar, FALSE, FALSE, 0); + g_signal_connect(importer->dialog, "response", G_CALLBACK(outlook_importer_response), importer); + gtk_widget_show_all(importer->dialog); + + importer->status_timeout_id = g_timeout_add(100, outlook_status_timeout, importer); + importer->cancel = camel_operation_new(outlook_status, importer); + + mail_msg_wait(mail_importer_import_outlook(filename, importer->uri, importer->cancel)); + + camel_operation_unref(importer->cancel); + g_source_remove(importer->status_timeout_id); + importer->status_timeout_id = 0; - camel_folder_freeze (importer->folder); - oli->busy = FALSE; return TRUE; } @@ -287,3 +246,166 @@ outlook_importer_new(void) return BONOBO_OBJECT (importer); } + +struct _import_outlook_msg { + struct _mail_msg msg; + + char *path; + char *uri; + CamelOperation *cancel; +}; + +static char * +import_outlook_describe(struct _mail_msg *mm, int complete) +{ + return g_strdup (_("Importing mailbox")); +} + +static void +import_outlook_import(struct _mail_msg *mm) +{ + struct _import_outlook_msg *m = (struct _import_outlook_msg *) mm; + struct stat st; + CamelFolder *folder; + + if (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 = mail_component_get_folder(NULL, MAIL_COMPONENT_FOLDER_INBOX); + else + folder = mail_tool_uri_to_folder(m->uri, CAMEL_STORE_FOLDER_CREATE, &mm->ex); + + if (folder == NULL) + return; + + if (S_ISREG(st.st_mode)) { + CamelOperation *oldcancel = NULL; + CamelMessageInfo *info; + GByteArray *buffer; + int fd; + off_t pos; + + fd = open(m->path, O_RDONLY); + if (fd == -1) { + g_warning("cannot find source file to import '%s': %s", m->path, g_strerror(errno)); + goto fail; + } + + if (lseek(fd, 0x54, SEEK_SET) == -1) + goto fail; + + if (m->cancel) + oldcancel = camel_operation_register(m->cancel); + + camel_folder_freeze(folder); + + buffer = g_byte_array_new(); + pos = 0x54; + do { + oe_msg_segmentheader header; + int pc; + size_t len; + CamelStream *mem; + CamelMimeMessage *msg; + + if (st.st_size > 0) + pc = (int)(100.0 * ((double)pos / (double)st.st_size)); + camel_operation_progress(NULL, pc); + + if (read(fd, &header, sizeof(header)) != sizeof(header)) + goto fail2; + + pos += sizeof(header); + +#if G_BYTE_ORDER == G_BIG_ENDIAN + header.include = GUINT32_TO_BE(header.include); +#endif + /* the -4 is some magical value */ + len = header.include - sizeof(header) - 4; + /* sanity check */ + if (len > (pos + st.st_size)) + goto fail2; + g_byte_array_set_size(buffer, len); + if (read(fd, buffer->data, len) != len) + goto fail2; + + pos += len; + + mem = camel_stream_mem_new(); + camel_stream_mem_set_byte_array((CamelStreamMem *)mem, buffer); + + msg = camel_mime_message_new(); + if (camel_data_wrapper_construct_from_stream((CamelDataWrapper *)msg, mem) == -1) { + camel_object_unref(msg); + camel_object_unref(mem); + goto fail2; + } + + info = camel_message_info_new(); + /* any headers to read? */ + + camel_folder_append_message(folder, msg, info, NULL, &mm->ex); + + camel_message_info_free(info); + camel_object_unref(msg); + camel_object_unref(mem); + } while (!camel_exception_is_set(&mm->ex) && pos < st.st_size); + + camel_folder_sync(folder, FALSE, NULL); + camel_folder_thaw(folder); + camel_operation_end(NULL); + fail2: + /* TODO: these api's are a bit weird, registering the old is the same as deregistering */ + if (m->cancel) + camel_operation_register(oldcancel); + g_byte_array_free(buffer, TRUE); + } +fail: + camel_object_unref(folder); +} + +static void +import_outlook_done(struct _mail_msg *mm) +{ +} + +static void +import_outlook_free (struct _mail_msg *mm) +{ + struct _import_outlook_msg *m = (struct _import_outlook_msg *)mm; + + if (m->cancel) + camel_operation_unref(m->cancel); + g_free(m->uri); + g_free(m->path); +} + +static struct _mail_msg_op import_outlook_op = { + import_outlook_describe, + import_outlook_import, + import_outlook_done, + import_outlook_free, +}; + +static int +mail_importer_import_outlook(const char *path, const char *folderuri, CamelOperation *cancel) +{ + struct _import_outlook_msg *m; + int id; + + m = mail_msg_new(&import_outlook_op, NULL, sizeof (*m)); + m->path = g_strdup(path); + m->uri = g_strdup(folderuri); + if (cancel) { + m->cancel = cancel; + camel_operation_ref(cancel); + } + + id = m->msg.seq; + e_thread_put(mail_thread_queued, (EMsg *)m); + + return id; +} diff --git a/mail/importers/mail-importer.c b/mail/importers/mail-importer.c index 0cfeb3b56a..ea28ff3a7b 100644 --- a/mail/importers/mail-importer.c +++ b/mail/importers/mail-importer.c @@ -200,6 +200,8 @@ import_mbox_import(struct _mail_msg *mm) return; if (S_ISREG(st.st_mode)) { + CamelOperation *oldcancel = NULL; + fd = open(m->path, O_RDONLY); if (fd == -1) { g_warning("cannot find source file to import '%s': %s", m->path, g_strerror(errno)); @@ -213,7 +215,7 @@ import_mbox_import(struct _mail_msg *mm) } if (m->cancel) - camel_operation_register(m->cancel); + oldcancel = camel_operation_register(m->cancel); camel_operation_start(NULL, _("Importing `%s'"), folder->full_name); camel_folder_freeze(folder); @@ -254,16 +256,17 @@ import_mbox_import(struct _mail_msg *mm) camel_mime_parser_step(mp, 0, 0); } - camel_folder_sync(folder, FALSE, &mm->ex); + camel_folder_sync(folder, FALSE, NULL); camel_folder_thaw(folder); camel_operation_end(NULL); + /* TODO: these api's are a bit weird, registering the old is the same as deregistering */ if (m->cancel) - camel_operation_unregister(m->cancel); + camel_operation_register(oldcancel); fail2: camel_object_unref(mp); } fail1: - camel_folder_sync(folder, FALSE, &mm->ex); + camel_folder_sync(folder, FALSE, NULL); camel_object_unref(folder); } @@ -328,11 +331,15 @@ mail_importer_import_mbox_sync(const char *path, const char *folderuri, CamelOpe mail_msg_free(&m->msg); } -/* This should probably take a list of all folders, otherwise we need to duplicate it for netscape folders */ +struct _import_folders_data { + MailImporterSpecial *special_folders; + CamelOperation *cancel; -/* pass folderparent = NULL first time */ -void -mail_importer_import_folders_sync(const char *filepath, const char *folderparent, MailImporterSpecial special_folders[], CamelOperation *cancel) + int elmfmt:1; +}; + +static void +import_folders_rec(struct _import_folders_data *m, const char *filepath, const char *folderparent) { DIR *dir; struct dirent *d; @@ -347,13 +354,15 @@ mail_importer_import_folders_sync(const char *filepath, const char *folderparent camel_operation_start(NULL, _("Scanning %s"), filepath); while ( (d=readdir(dir)) ) { - if (strcmp(d->d_name, ".") == 0 - || strcmp(d->d_name, "..") == 0) + if (d->d_name[0] == '.') continue; filefull = g_build_filename(filepath, d->d_name, NULL); + + /* skip non files and directories, and skip directories in mozilla mode */ if (stat(filefull, &st) == -1 - || !(S_ISREG(st.st_mode) || S_ISDIR(st.st_mode))) { + || !(S_ISREG(st.st_mode) + || (m->elmfmt && S_ISDIR(st.st_mode)))) { g_free(filefull); continue; } @@ -362,9 +371,9 @@ mail_importer_import_folders_sync(const char *filepath, const char *folderparent if (folderparent == NULL) { int i; - for (i=0;special_folders[i].orig;i++) - if (strcmp(special_folders[i].orig, folder) == 0) { - folder = special_folders[i].new; + for (i=0;m->special_folders[i].orig;i++) + if (strcmp(m->special_folders[i].orig, folder) == 0) { + folder = m->special_folders[i].new; break; } /* FIXME: need a better way to get default store location */ @@ -374,12 +383,24 @@ mail_importer_import_folders_sync(const char *filepath, const char *folderparent } printf("importing to uri %s\n", uri); - mail_importer_import_mbox_sync(filefull, uri, cancel); + mail_importer_import_mbox_sync(filefull, uri, m->cancel); g_free(uri); + /* This little gem re-uses the stat buffer and filefull to automagically scan mozilla-format folders */ + if (!m->elmfmt) { + char *tmp = g_strdup_printf("%s.sbd", filefull); + + g_free(filefull); + filefull = tmp; + if (stat(filefull, &st) == -1) { + g_free(filefull); + continue; + } + } + if (S_ISDIR(st.st_mode)) { foldersub = folderparent?g_strdup_printf("%s/%s", folderparent, folder):g_strdup(folder); - mail_importer_import_folders_sync(filefull, foldersub, special_folders, cancel); + import_folders_rec(m, filefull, foldersub); g_free(foldersub); } @@ -388,3 +409,37 @@ mail_importer_import_folders_sync(const char *filepath, const char *folderparent camel_operation_end(NULL); } + +/** + * mail_importer_import_folders_sync: + * @filepath: + * @: + * @flags: + * @cancel: + * + * import from a base path @filepath into the root local folder tree, + * scanning all sub-folders. + * + * if @flags is MAIL_IMPORTER_MOZFMT, then subfolders are assumed to + * be in mozilla/evolutoin 1.5 format, appending '.sbd' to the + * directory name. Otherwise they are in elm/mutt/pine format, using + * standard unix directories. + **/ +void +mail_importer_import_folders_sync(const char *filepath, MailImporterSpecial special_folders[], int flags, CamelOperation *cancel) +{ + struct _import_folders_data m; + CamelOperation *oldcancel = NULL; + + m.special_folders = special_folders; + m.elmfmt = (flags & MAIL_IMPORTER_MOZFMT) == 0; + m.cancel = cancel; + + if (cancel) + oldcancel = camel_operation_register(cancel); + + import_folders_rec(&m, filepath, NULL); + + if (cancel) + camel_operation_register(oldcancel); +} diff --git a/mail/importers/mail-importer.h b/mail/importers/mail-importer.h index dfc7fcde93..42e68f4ad4 100644 --- a/mail/importers/mail-importer.h +++ b/mail/importers/mail-importer.h @@ -82,7 +82,10 @@ struct _MailImporterSpecial { }; typedef struct _MailImporterSpecial MailImporterSpecial; +/* mozilla format subdirs */ +#define MAIL_IMPORTER_MOZFMT (1<<0) + /* api in flux */ -void mail_importer_import_folders_sync(const char *filepath, const char *folderparent, MailImporterSpecial special_folders[], struct _CamelOperation *cancel); +void mail_importer_import_folders_sync(const char *filepath, MailImporterSpecial special_folders[], int flags, struct _CamelOperation *cancel); #endif diff --git a/mail/importers/netscape-importer.c b/mail/importers/netscape-importer.c index 4ce1570b8c..1e60e7f3c5 100644 --- a/mail/importers/netscape-importer.c +++ b/mail/importers/netscape-importer.c @@ -41,15 +41,9 @@ #include <gconf/gconf.h> #include <gconf/gconf-client.h> -#include <bonobo/bonobo-main.h> -#include <bonobo/bonobo-object.h> -#include <bonobo/bonobo-generic-factory.h> -#include <bonobo/bonobo-control.h> -#include <bonobo/bonobo-context.h> -#include <bonobo/bonobo-exception.h> -#include <bonobo/bonobo-moniker-util.h> +#include <camel/camel-operation.h> -#include <bonobo-activation/bonobo-activation.h> +#include <bonobo/bonobo-control.h> #include <importer/evolution-intelligent-importer.h> #include <importer/GNOME_Evolution_Importer.h> @@ -62,8 +56,16 @@ #include <filter/filter-folder.h> #include <filter/filter-int.h> +#include "e-util/e-account-list.h" + +#include "mail/mail-mt.h" +#include "mail/mail-config.h" +#include "mail/em-utils.h" +#include "mail/mail-component.h" + #include "mail-importer.h" +/* FIXME: dont make this stuff global */ static char *nsmail_dir = NULL; static GHashTable *user_prefs = NULL; @@ -85,28 +87,23 @@ static char *filter_name = N_("Priority Filter \"%s\""); typedef struct { EvolutionIntelligentImporter *ii; - GList *dir_list; - - int progress_count; - int more; - EvolutionImporterResult result; - - GNOME_Evolution_Importer importer; - EvolutionImporterListener *listener; + GMutex *status_lock; + char *status_what; + int status_pc; + int status_timeout_id; + CamelOperation *cancel; /* cancel/status port */ - /* Checkboxes */ GtkWidget *mail; - gboolean do_mail; -/* - GtkWidget *addrs; - gboolean do_addrs; -*/ GtkWidget *filters; - gboolean do_filters; GtkWidget *settings; - gboolean do_settings; - /*Bonobo_ConfigDatabase db;*/ + gboolean do_mail; + gboolean done_mail; + + gboolean do_filters; + gboolean done_filters; + gboolean do_settings; + gboolean done_settings; /* GUI */ GtkWidget *dialog; @@ -191,8 +188,7 @@ typedef struct { /* Prototypes ------------------------------------------------------------- */ static void netscape_filter_cleanup (NsFilter *nsf); -static char *fix_netscape_folder_names (const char *original_name); -static void import_next (NsImporter *importer); +static const char *fix_netscape_folder_names (const char *original_name); /* Email filter stuff ----------------------------------------------------- */ @@ -368,7 +364,6 @@ netscape_filter_parse_conditions (NsFilter *nsf, FILE *f, char *condition) nsf->conditions = g_list_append (nsf->conditions, cond); } } - static NsFilter * netscape_filter_read_next (FILE *mailrule_handle) @@ -516,7 +511,6 @@ netscape_filter_read_next (FILE *mailrule_handle) return NULL; } - static void netscape_filter_cleanup (NsFilter *nsf) { @@ -538,7 +532,6 @@ netscape_filter_cleanup (NsFilter *nsf) g_free (nsf); } - static gboolean netscape_filter_set_opt_for_cond (NsFilterCondition *cond, FilterOption* op) { @@ -568,7 +561,6 @@ netscape_filter_set_opt_for_cond (NsFilterCondition *cond, FilterOption* op) return TRUE; } - /* Translates a string of the form folder1.sbd/folder2.sbd/.../folderN.sbd/folder @@ -582,7 +574,7 @@ netscape_filter_strip_sbd (char *ns_folder) char *folder_copy; char s[MAXLEN]; char *ptr, *ptr2; - char *fixed_folder; + const char *fixed_folder; folder_copy = g_strdup (ns_folder); ptr = folder_copy; @@ -601,7 +593,6 @@ netscape_filter_strip_sbd (char *ns_folder) fixed_folder = fix_netscape_folder_names (ptr); strcat (s, fixed_folder); g_free (folder_copy); - g_free (fixed_folder); d(g_warning ("Stripped '%s' to '%s'", ns_folder, s)); @@ -613,31 +604,38 @@ static char * netscape_filter_map_folder_to_uri (char *folder) { char *folder_copy; - char s[MAXLEN]; char *ptr, *ptr2; - + GString *s; + folder_copy = g_strdup (folder); ptr = folder_copy; - g_snprintf (s, MAXLEN, "file://%s/evolution/local/", g_get_home_dir ()); + /* FIXME: this should use account-relative uri's */ + + s = g_string_new("mbox:"); + g_string_append(s, g_get_home_dir()); + g_string_append(s, "/mail/local#"); while (ptr) { if ( (ptr2 = strchr (ptr, '/')) == NULL) break; *ptr2 = '\0'; - strcat (s, ptr); - strcat (s, "/subfolders/"); + g_string_append(s, ptr); + g_string_append_c(s, '/'); ptr = ptr2 + 1; } - strcat (s, ptr); + g_string_append(s, ptr); g_free (folder_copy); d(g_warning ("Mapped '%s' to '%s'", folder, s)); - return g_strdup (s); + ptr = s->str; + g_string_free(s, FALSE); + + return ptr; } @@ -1181,8 +1179,7 @@ netscape_import_filters (NsImporter *importer) } fc = filter_context_new (); - user = g_concat_dir_and_file (g_get_home_dir (), - "evolution/filters.xml"); + user = g_build_filename(g_get_home_dir (), "evolution/filters.xml"); system = EVOLUTION_PRIVDATADIR "/filtertypes.xml"; if (rule_context_load ((RuleContext *)fc, system, user) < 0) { @@ -1212,12 +1209,8 @@ netscape_import_filters (NsImporter *importer) } - - - /* Email folder & accounts stuff ----------------------------------------------- */ - static GtkWidget * create_importer_gui (NsImporter *importer) { @@ -1242,9 +1235,9 @@ netscape_store_settings (NsImporter *importer) { GConfClient *gconf = gconf_client_get_default(); - gconf_client_set_bool(gconf, "/apps/evolution/importer/netscape/mail", importer->do_mail, NULL); - gconf_client_set_bool(gconf, "/apps/evolution/importer/netscape/settings", importer->do_settings, NULL); - gconf_client_set_bool(gconf, "/apps/evolution/importer/netscape/filters", importer->do_filters, NULL); + gconf_client_set_bool(gconf, "/apps/evolution/importer/netscape/mail", importer->done_mail, NULL); + gconf_client_set_bool(gconf, "/apps/evolution/importer/netscape/settings", importer->done_settings, NULL); + gconf_client_set_bool(gconf, "/apps/evolution/importer/netscape/filters", importer->done_filters, NULL); } static void @@ -1252,9 +1245,9 @@ netscape_restore_settings (NsImporter *importer) { GConfClient *gconf = gconf_client_get_default(); - importer->do_mail = gconf_client_get_bool(gconf, "/apps/evolution/importer/netscape/mail", NULL); - importer->do_settings = gconf_client_get_bool(gconf, "/apps/evolution/importer/netscape/settings", NULL); - importer->do_filters = gconf_client_get_bool(gconf, "/apps/evolution/importer/netscape/filters", NULL); + importer->done_mail = gconf_client_get_bool(gconf, "/apps/evolution/importer/netscape/mail", NULL); + importer->done_settings = gconf_client_get_bool(gconf, "/apps/evolution/importer/netscape/settings", NULL); + importer->done_filters = gconf_client_get_bool(gconf, "/apps/evolution/importer/netscape/filters", NULL); } static const char * @@ -1431,16 +1424,14 @@ get_user_fullname (void) uname = getenv ("USER"); pwd = getpwnam (uname); - if (strcmp (pwd->pw_gecos, "") == 0) { + if (strcmp (pwd->pw_gecos, "") == 0) return g_strdup (uname); - } special = strchr (pwd->pw_gecos, ','); - if (special == NULL) { + if (special == NULL) gecos = g_strdup (pwd->pw_gecos); - } else { + else gecos = g_strndup (pwd->pw_gecos, special - pwd->pw_gecos); - } special = strchr (gecos, '&'); if (special == NULL) { @@ -1461,18 +1452,14 @@ get_user_fullname (void) } } -#if 0 +/* Needs to run in gui thread */ static void netscape_import_accounts (NsImporter *importer) { char *username; const char *nstr; const char *imap; - GNOME_Evolution_MailConfig_Account account; - GNOME_Evolution_MailConfig_Service source, transport; - GNOME_Evolution_MailConfig_Identity id; - CORBA_Object objref; - CORBA_Environment ev; + EAccount *account; if (user_prefs == NULL) { netscape_init_prefs (); @@ -1480,97 +1467,74 @@ netscape_import_accounts (NsImporter *importer) return; } - CORBA_exception_init (&ev); - objref = bonobo_activation_activate_from_id (MAIL_CONFIG_IID, 0, NULL, &ev); - if (ev._major != CORBA_NO_EXCEPTION) { - g_warning ("Error starting mail config"); - CORBA_exception_free (&ev); - return; - } - - if (objref == CORBA_OBJECT_NIL) { - g_warning ("Error activating mail config"); - return; - } - /* Create identify structure */ nstr = netscape_get_string ("mail.identity.username"); - if (nstr != NULL) { + if (nstr != NULL) username = g_strdup (nstr); - } else { + else username = get_user_fullname (); - } - id.name = CORBA_string_dup (username); - nstr = netscape_get_string ("mail.identity.useremail"); - id.address = CORBA_string_dup (nstr ? nstr : ""); - nstr = netscape_get_string ("mail.identity.organization"); - id.organization = CORBA_string_dup (nstr ? nstr : ""); + account = e_account_new(); + + account->id->name = g_strdup(username); + account->id->address = g_strdup(netscape_get_string("mail.identity.useremail")); + account->id->organization = g_strdup(netscape_get_string("mail.identity.organization")); + nstr = netscape_get_string ("mail.signature_file"); - /* FIXME rodo id.signature = CORBA_string_dup (nstr ? nstr : ""); - id.html_signature = CORBA_string_dup (""); - id.has_html_signature = FALSE; */ + if (nstr != NULL) { + MailConfigSignature *sig; + char *cmd; + + sig = mail_config_signature_new(FALSE, NULL); + mail_config_signature_add(sig); + account->id->def_signature = sig->id; + account->id->auto_signature = FALSE; + /* HACK: yeah this is a hack, who cares? */ + cmd = g_strdup_printf("cp \'%s\' \'%s\'", nstr, sig->filename); + system(cmd); + g_free(cmd); + } /* Create transport */ nstr = netscape_get_string ("network.hosts.smtp_server"); if (nstr != NULL) { - char *url; const char *nstr2; nstr2 = netscape_get_string ("mail.smtp_name"); - if (nstr2) { - url = g_strconcat ("smtp://", nstr2, "@", nstr, NULL); - } else { - url = g_strconcat ("smtp://", nstr, NULL); - } - transport.url = CORBA_string_dup (url); - transport.keep_on_server = FALSE; - transport.auto_check = FALSE; - transport.auto_check_time = 10; - transport.save_passwd = FALSE; - transport.enabled = TRUE; - g_free (url); + if (nstr2) + account->transport->url = g_strconcat ("smtp://", nstr2, "@", nstr, NULL); + else + account->transport->url = g_strconcat ("smtp://", nstr, NULL); } else { - transport.url = CORBA_string_dup (""); - transport.keep_on_server = FALSE; - transport.auto_check = FALSE; - transport.auto_check_time = 0; - transport.save_passwd = FALSE; - transport.enabled = FALSE; + account->transport->url = g_strdup(""); } - /* Create account */ - account.name = CORBA_string_dup (username); - account.id = id; - account.transport = transport; + account->transport->keep_on_server = FALSE; + account->transport->auto_check = FALSE; + account->transport->auto_check_time = 10; + account->transport->save_passwd = FALSE; - account.drafts_folder_uri = CORBA_string_dup (""); - account.sent_folder_uri = CORBA_string_dup (""); + /*transport.enabled = FALSE;*/ + + /* Create account */ + account->drafts_folder_uri = em_uri_from_camel(mail_component_get_folder_uri(NULL, MAIL_COMPONENT_FOLDER_DRAFTS)); + account->sent_folder_uri = em_uri_from_camel(mail_component_get_folder_uri(NULL, MAIL_COMPONENT_FOLDER_SENT)); /* Create POP3 source */ nstr = netscape_get_string ("network.hosts.pop_server"); if (nstr != NULL && *nstr != 0) { - char *url; - gboolean bool; const char *nstr2; nstr2 = netscape_get_string ("mail.pop_name"); - if (nstr2) { - url = g_strconcat ("pop://", nstr2, "@", nstr, NULL); - } else { - url = g_strconcat ("pop://", nstr, NULL); - } - source.url = CORBA_string_dup (url); - bool = netscape_get_boolean ("mail.leave_on_server"); - g_warning ("mail.leave_on_server: %s", bool ? "true" : "false"); - source.keep_on_server = netscape_get_boolean ("mail.leave_on_server"); - source.auto_check = TRUE; - source.auto_check_time = 10; - bool = netscape_get_boolean ("mail.remember_password"); - g_warning ("mail.remember_password: %s", bool ? "true" : "false"); - source.save_passwd = netscape_get_boolean ("mail.remember_password"); - source.enabled = TRUE; - g_free (url); + if (nstr2) + account->source->url = g_strconcat ("pop://", nstr2, "@", nstr, NULL); + else + account->source->url = g_strconcat ("pop://", nstr, NULL); + account->source->keep_on_server = netscape_get_boolean ("mail.leave_on_server"); + account->source->auto_check = TRUE; + account->source->auto_check_time = 10; + account->source->save_passwd = netscape_get_boolean ("mail.remember_password"); + account->enabled = TRUE; } else { /* Are there IMAP accounts? */ imap = netscape_get_string ("network.hosts.imap_servers"); @@ -1578,11 +1542,14 @@ netscape_import_accounts (NsImporter *importer) char **servers; int i; - servers = g_strsplit (imap, ",", 1024); + servers = g_strsplit (imap, ",", 0); for (i = 0; servers[i] != NULL; i++) { - GNOME_Evolution_MailConfig_Service imapsource; char *serverstr, *name, *url; const char *username; + EAccount *imap; + + imap = e_account_new(); + e_account_import(imap, account); /* Create a server for each of these */ serverstr = g_strdup_printf ("mail.imap.server.%s.", servers[i]); @@ -1591,73 +1558,48 @@ netscape_import_accounts (NsImporter *importer) g_free (name); if (username) - url = g_strconcat ("imap://", username, - "@", servers[i], NULL); + imap->source->url = g_strconcat ("imap://", username, "@", servers[i], NULL); else - url = g_strconcat ("imap://", servers[i], NULL); + imap->source->url = g_strconcat ("imap://", servers[i], NULL); - imapsource.url = CORBA_string_dup (url); - - imapsource.keep_on_server = netscape_get_boolean ("mail.leave_on_server"); + imap->source->keep_on_server = netscape_get_boolean ("mail.leave_on_server"); name = g_strconcat (serverstr, "check_new_mail", NULL); - imapsource.auto_check = netscape_get_boolean (name); + imap->source->auto_check = netscape_get_boolean (name); g_free (name); name = g_strconcat (serverstr, "check_time", NULL); - imapsource.auto_check_time = netscape_get_integer (name); + imap->source->auto_check_time = netscape_get_integer (name); g_free (name); name = g_strconcat (serverstr, "remember_password", NULL); - imapsource.save_passwd = netscape_get_boolean (name); + imap->source->save_passwd = netscape_get_boolean (name); g_free (name); - imapsource.enabled = TRUE; - account.source = imapsource; + imap->enabled = TRUE; - GNOME_Evolution_MailConfig_addAccount (objref, &account, &ev); - if (ev._major != CORBA_NO_EXCEPTION) { - g_warning ("Error setting account: %s", CORBA_exception_id (&ev)); - CORBA_exception_free (&ev); - return; - } - + mail_config_add_account(imap); g_free (url); g_free (serverstr); } - CORBA_exception_free (&ev); + g_object_unref(account); g_strfreev (servers); return; } else { - char *url, *path; - /* Using Movemail */ - path = getenv ("MAIL"); - url = g_strconcat ("mbox://", path, NULL); - source.url = CORBA_string_dup (url); - g_free (url); - - source.keep_on_server = netscape_get_boolean ("mail.leave_on_server"); - source.auto_check = TRUE; - source.auto_check_time = 10; - source.save_passwd = netscape_get_boolean ("mail.remember_password"); - source.enabled = FALSE; + account->source->url = g_strconcat ("mbox://", getenv("MAIL"), NULL); + account->source->keep_on_server = netscape_get_boolean ("mail.leave_on_server"); + account->source->auto_check = TRUE; + account->source->auto_check_time = 10; + account->source->save_passwd = netscape_get_boolean ("mail.remember_password"); + account->enabled = TRUE; } } - account.source = source; - GNOME_Evolution_MailConfig_addAccount (objref, &account, &ev); - if (ev._major != CORBA_NO_EXCEPTION) { - g_warning ("Error setting account: %s", CORBA_exception_id (&ev)); - CORBA_exception_free (&ev); - return; - } - - g_free (username); - CORBA_exception_free (&ev); + mail_config_add_account(account); + g_free(username); } -#endif static gboolean is_dir_empty (const char *path) @@ -1700,326 +1642,177 @@ is_dir_empty (const char *path) } static gboolean -netscape_can_import (EvolutionIntelligentImporter *ii, - void *closure) +netscape_can_import(EvolutionIntelligentImporter *ii, void *data) { - if (user_prefs == NULL) { + int can; + NsImporter *importer = data; + + if (user_prefs == NULL) netscape_init_prefs (); - } - if (user_prefs == NULL) { - d(g_warning ("No netscape dir")); - return FALSE; - } + can = user_prefs + && (nsmail_dir = g_hash_table_lookup (user_prefs, "mail.directory")) != NULL + && !is_dir_empty(nsmail_dir); - nsmail_dir = g_hash_table_lookup (user_prefs, "mail.directory"); - if (nsmail_dir == NULL) { - return FALSE; - } else { - return !is_dir_empty (nsmail_dir); - } -} + importer->do_mail = can && !importer->done_mail; + importer->do_settings = can && !importer->done_settings; + importer->do_filters = importer->do_mail && !importer->done_filters; -static void -importer_cb (EvolutionImporterListener *listener, - EvolutionImporterResult result, - gboolean more_items, - void *data) -{ - NsImporter *importer = (NsImporter *) data; + gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON (importer->mail), importer->do_mail); + gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON (importer->settings), importer->do_settings); + gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON (importer->mail), importer->do_filters); - importer->result = result; - importer->more = more_items; + return can; } -static gboolean -netscape_import_file (NsImporter *importer, - const char *path, - const char *folderpath) -{ - CORBA_boolean result; - CORBA_Environment ev; - CORBA_Object objref; - char *str, *uri; +struct _netscape_import_msg { + struct _mail_msg msg; - /* Do import of mail folder */ - d(g_warning ("Importing %s as %s", path, folderpath)); + NsImporter *importer; +}; - CORBA_exception_init (&ev); - - str = g_strdup_printf (_("Importing %s as %s"), path, folderpath); - gtk_label_set_text (GTK_LABEL (importer->label), str); - g_free (str); - while (g_main_context_iteration(NULL, FALSE)) - ; - - uri = mail_importer_make_local_folder(folderpath); - if (!uri) - return FALSE; +static char * +netscape_import_describe (struct _mail_msg *mm, int complete) +{ + return g_strdup (_("Importing Netscape data")); +} -#warning "load file dest path" - result = GNOME_Evolution_Importer_loadFile (importer->importer, path, &ev); - g_free(uri); - if (ev._major != CORBA_NO_EXCEPTION || result == FALSE) { - g_warning ("Exception here: %s", CORBA_exception_id (&ev)); - CORBA_exception_free (&ev); - return FALSE; - } +/* Translations ? */ +static MailImporterSpecial netscape_special_folders[] = { + { "Trash", "Netscape-Trash" }, + { "Calendar", "Netscape-Calendar" }, + { "Contacts", "Netscape-Contacts" }, + { "Tasks", "Netscape-Tasks" }, + { "Unsent Messages", "Outbox" }, + { 0 }, +}; - /* process all items in a direct loop */ - importer->listener = evolution_importer_listener_new (importer_cb, importer); - objref = bonobo_object_corba_objref (BONOBO_OBJECT (importer->listener)); - do { - importer->progress_count++; - if ((importer->progress_count & 0xf) == 0) - gtk_progress_bar_pulse(GTK_PROGRESS_BAR(importer->progressbar)); - - importer->result = -1; - GNOME_Evolution_Importer_processItem (importer->importer, objref, &ev); - if (ev._major != CORBA_NO_EXCEPTION) { - g_warning ("Exception: %s", CORBA_exception_id (&ev)); - break; - } +static const char *fix_netscape_folder_names (const char *original_name) +{ + int i; - while (importer->result == -1 || g_main_context_pending(NULL)) - g_main_context_iteration(NULL, TRUE); - } while (importer->more); - bonobo_object_unref((BonoboObject *)importer->listener); - CORBA_exception_free (&ev); + for (i=0;netscape_special_folders[i].orig;i++) + if (strcmp(netscape_special_folders[i].orig, original_name) == 0) + return netscape_special_folders[i].new; - return FALSE; + return original_name; } -typedef struct { - NsImporter *importer; - char *parent; - char *path; - char *foldername; -} NetscapeCreateDirectoryData; - static void -import_next (NsImporter *importer) +netscape_import_import(struct _mail_msg *mm) { - NetscapeCreateDirectoryData *data; - -trynext: - if (importer->dir_list) { - char *folder; - GList *l; - int ok; - - l = importer->dir_list; - data = l->data; - - folder = g_build_filename(data->parent, data->foldername, NULL); - - importer->dir_list = l->next; - g_list_free_1(l); - - ok = netscape_import_file (importer, data->path, folder); - g_free (folder); - g_free (data->parent); - g_free (data->path); - g_free (data->foldername); - g_free (data); - if (!ok) - goto trynext; - } else { - bonobo_object_unref((BonoboObject *)importer->ii); - } + struct _netscape_import_msg *m = (struct _netscape_import_msg *) mm; + + if (m->importer->do_mail) + mail_importer_import_folders_sync(nsmail_dir, netscape_special_folders, MAIL_IMPORTER_MOZFMT, m->importer->cancel); } -/* We don't allow any mail to be imported into a reservered Evolution folder name */ -static char *reserved_names[] = { - N_("Trash"), - N_("Calendar"), - N_("Contacts"), - N_("Tasks"), - NULL -}; - -static char * -fix_netscape_folder_names (const char *original_name) +static void +netscape_import_imported(struct _mail_msg *mm) { - int i; - - for (i = 0; reserved_names[i] != NULL; i++) { - if (strcmp (original_name, _(reserved_names[i])) == 0) { - return g_strdup_printf ("Netscape-%s", - _(reserved_names[i])); - } - } - - if (strcmp (original_name, "Unsent Messages") == 0) { - return g_strdup ("Outbox"); - } - - return g_strdup (original_name); } -/* This function basically flattens the tree structure. - It makes a list of all the directories that are to be imported. */ static void -scan_dir (NsImporter *importer, - const char *orig_parent, - const char *dirname) +netscape_import_free(struct _mail_msg *mm) { - DIR *nsmail; - struct stat buf; - struct dirent *current; - char *str; - - nsmail = opendir (dirname); - if (nsmail == NULL) { - d(g_warning ("Could not open %s\nopendir returned: %s", - dirname, g_strerror (errno))); - return; - } +} - str = g_strdup_printf (_("Scanning %s"), dirname); - gtk_label_set_text (GTK_LABEL (importer->label), str); - g_free (str); +static struct _mail_msg_op netscape_import_op = { + netscape_import_describe, + netscape_import_import, + netscape_import_imported, + netscape_import_free, +}; - while (gtk_events_pending ()) { - gtk_main_iteration (); - } +static int +mail_importer_netscape_import(NsImporter *importer) +{ + struct _netscape_import_msg *m; + int id; - current = readdir (nsmail); - while (current) { - char *fullname, *foldername; + m = mail_msg_new(&netscape_import_op, NULL, sizeof (*m)); + m->importer = importer; - /* Ignore things which start with . - which should be ., .., and the summaries. */ - if (current->d_name[0] =='.') { - current = readdir (nsmail); - continue; - } + id = m->msg.seq; - if (*orig_parent == '/') { - foldername = fix_netscape_folder_names (current->d_name); - } else { - foldername = g_strdup (current->d_name); - } + /* Need to do these in gui thread, and should be quick anyway */ + if (m->importer->do_mail && m->importer->do_filters) + netscape_import_filters(m->importer); + if (m->importer->do_settings) + netscape_import_accounts(m->importer); + + e_thread_put(mail_thread_queued, (EMsg *) m); - fullname = g_concat_dir_and_file (dirname, current->d_name); - if (stat (fullname, &buf) == -1) { - d(g_warning ("Could not stat %s\nstat returned:%s", - fullname, g_strerror (errno))); - current = readdir (nsmail); - g_free (fullname); - continue; - } + return id; +} - if (S_ISREG (buf.st_mode)) { - char *sbd, *parent; - NetscapeCreateDirectoryData *data; +static void +netscape_status(CamelOperation *op, const char *what, int pc, void *data) +{ + NsImporter *importer = data; + + if (pc == CAMEL_OPERATION_START) + pc = 0; + else if (pc == CAMEL_OPERATION_END) + pc = 100; + + g_mutex_lock(importer->status_lock); + g_free(importer->status_what); + importer->status_what = g_strdup(what); + importer->status_pc = pc; + g_mutex_unlock(importer->status_lock); +} - d(g_print ("File: %s\n", fullname)); +static gboolean +netscape_status_timeout(void *data) +{ + NsImporter *importer = data; + int pc; + char *what; - data = g_new0 (NetscapeCreateDirectoryData, 1); - data->importer = importer; - data->parent = g_strdup (orig_parent); - data->path = g_strdup (fullname); - data->foldername = g_strdup (foldername); + if (!importer->status_what) + return TRUE; - importer->dir_list = g_list_append (importer->dir_list, - data); + g_mutex_lock(importer->status_lock); + what = importer->status_what; + importer->status_what = NULL; + pc = importer->status_pc; + g_mutex_unlock(importer->status_lock); + gtk_progress_bar_set_fraction((GtkProgressBar *)importer->progressbar, (gfloat)(pc/100.0)); + gtk_progress_bar_set_text((GtkProgressBar *)importer->progressbar, what); - parent = g_concat_dir_and_file (orig_parent, - data->foldername); - - /* Check if a .sbd folder exists */ - sbd = g_strconcat (fullname, ".sbd", NULL); - if (g_file_exists (sbd)) { - scan_dir (importer, parent, sbd); - } - - g_free (parent); - g_free (sbd); - } - - g_free (fullname); - g_free (foldername); - current = readdir (nsmail); - } + return TRUE; } - static void -netscape_create_structure (EvolutionIntelligentImporter *ii, - void *closure) +netscape_create_structure (EvolutionIntelligentImporter *ii, void *closure) { NsImporter *importer = closure; - GConfClient *gconf = gconf_client_get_default(); - g_return_if_fail (nsmail_dir != NULL); - - /* Reference our object so when the shell release_unrefs us - we will still exist and not go byebye */ - bonobo_object_ref (BONOBO_OBJECT (ii)); - - netscape_store_settings (importer); - - /* Create a dialog if we're going to be active */ - /* Importing mail filters is not a criterion because it makes - little sense to import the filters but not the mail folders. */ - if (importer->do_settings == TRUE || - importer->do_mail == TRUE) { + if (importer->do_settings || importer->do_mail) { importer->dialog = create_importer_gui (importer); gtk_widget_show_all (importer->dialog); - while (gtk_events_pending ()) { - gtk_main_iteration (); - } - } - - if (importer->do_settings == TRUE) { - gconf_client_set_bool(gconf, "/apps/evolution/importer/netscape/settings-imported", TRUE, NULL); -#warning "import netscape accounts" - /*netscape_import_accounts (importer);*/ - } - - if (importer->do_mail == TRUE) { - - /* Import the mail filters if needed ... */ - if (importer->do_filters == TRUE) { - gconf_client_set_bool(gconf, "/apps/evolution/importer/netscape/filters-imported", TRUE, NULL); - gtk_label_set_text (GTK_LABEL (importer->label), - _("Scanning mail filters")); + importer->status_timeout_id = g_timeout_add(100, netscape_status_timeout, importer); + importer->cancel = camel_operation_new(netscape_status, importer); - netscape_import_filters (importer); - } - - gconf_client_set_bool(gconf, "/apps/evolution/importer/netscape/mail-imported", TRUE, NULL); + mail_msg_wait(mail_importer_netscape_import(importer)); - /* Scan the nsmail folder and find out what folders - need to be imported */ + camel_operation_unref(importer->cancel); + g_source_remove(importer->status_timeout_id); + importer->status_timeout_id = 0; - gtk_label_set_text (GTK_LABEL (importer->label), - _("Scanning directory")); - while (gtk_events_pending ()) { - gtk_main_iteration (); - } - - scan_dir (importer, "/", nsmail_dir); - - /* Import them */ - gtk_label_set_text (GTK_LABEL (importer->label), - _("Starting import")); - while (gtk_events_pending ()) { - gtk_main_iteration (); - } - import_next (importer); - } - - if (importer->do_mail == FALSE) { - /* Destroy it here if we weren't importing mail - otherwise the mail importer destroys itself - once the mail in imported */ - bonobo_object_unref (BONOBO_OBJECT (ii)); + if (importer->do_settings) + importer->done_settings = TRUE; + if (importer->do_mail) + importer->done_mail = TRUE; + if (importer->do_filters) + importer->done_filters = TRUE; } - bonobo_object_unref (BONOBO_OBJECT (ii)); + netscape_store_settings(importer); + + bonobo_object_unref(BONOBO_OBJECT(ii)); } static void @@ -2027,9 +1820,10 @@ netscape_destroy_cb (NsImporter *importer, GObject *object) { netscape_store_settings (importer); - if (importer->importer != CORBA_OBJECT_NIL) { - bonobo_object_release_unref (importer->importer, NULL); - } + if (importer->status_timeout_id) + g_source_remove(importer->status_timeout_id); + g_free(importer->status_what); + g_mutex_free(importer->status_lock); if (importer->dialog) gtk_widget_destroy(importer->dialog); @@ -2106,33 +1900,21 @@ netscape_intelligent_importer_new(void) EvolutionIntelligentImporter *importer; BonoboControl *control; NsImporter *netscape; - CORBA_Environment ev; char *message = N_("Evolution has found Netscape mail files.\n" "Would you like them to be imported into Evolution?"); netscape = g_new0 (NsImporter, 1); - - CORBA_exception_init (&ev); - + netscape->status_lock = g_mutex_new(); netscape_restore_settings (netscape); - - netscape->importer = bonobo_activation_activate_from_id (MBOX_IMPORTER_IID, 0, NULL, &ev); - if (ev._major != CORBA_NO_EXCEPTION) { - g_warning ("Could not start MBox importer\n%s", CORBA_exception_id (&ev)); - CORBA_exception_free (&ev); - return NULL; - } - CORBA_exception_free (&ev); - importer = evolution_intelligent_importer_new (netscape_can_import, netscape_create_structure, "Netscape", _(message), netscape); - g_object_weak_ref(G_OBJECT (importer), (GWeakNotify)netscape_destroy_cb, netscape); + g_object_weak_ref(G_OBJECT(importer), (GWeakNotify)netscape_destroy_cb, netscape); netscape->ii = importer; - control = create_checkboxes_control (netscape); - bonobo_object_add_interface (BONOBO_OBJECT (importer), - BONOBO_OBJECT (control)); - return BONOBO_OBJECT (importer); + control = create_checkboxes_control(netscape); + bonobo_object_add_interface(BONOBO_OBJECT(importer), BONOBO_OBJECT(control)); + + return BONOBO_OBJECT(importer); } diff --git a/mail/importers/pine-importer.c b/mail/importers/pine-importer.c index 9ce7f4520a..519f1beffd 100644 --- a/mail/importers/pine-importer.c +++ b/mail/importers/pine-importer.c @@ -317,7 +317,7 @@ pine_import_import(struct _mail_msg *mm) char *path; path = g_build_filename(g_get_home_dir(), "mail", NULL); - mail_importer_import_folders_sync(path, NULL, pine_special_folders, m->importer->cancel); + mail_importer_import_folders_sync(path, pine_special_folders, 0, m->importer->cancel); g_free(path); } } @@ -430,10 +430,13 @@ pine_destroy_cb (PineImporter *importer, GtkObject *object) if (importer->status_timeout_id) g_source_remove(importer->status_timeout_id); + g_free(importer->status_what); g_mutex_free(importer->status_lock); if (importer->dialog) gtk_widget_destroy(importer->dialog); + + g_free(importer); } /* Fun inity stuff */ @@ -481,11 +484,8 @@ pine_intelligent_importer_new(void) "Would you like to import them into Evolution?"); pine = g_new0 (PineImporter, 1); - pine->status_lock = g_mutex_new(); - - pine_restore_settings (pine); - + pine_restore_settings(pine); importer = evolution_intelligent_importer_new (pine_can_import, pine_create_structure, _("Pine"), @@ -493,8 +493,8 @@ pine_intelligent_importer_new(void) g_object_weak_ref((GObject *)importer, (GWeakNotify)pine_destroy_cb, pine); pine->ii = importer; - control = create_checkboxes_control (pine); - bonobo_object_add_interface (BONOBO_OBJECT (importer), - BONOBO_OBJECT (control)); - return BONOBO_OBJECT (importer); + control = create_checkboxes_control(pine); + bonobo_object_add_interface(BONOBO_OBJECT(importer), BONOBO_OBJECT(control)); + + return BONOBO_OBJECT(importer); } |