aboutsummaryrefslogtreecommitdiffstats
path: root/mail/importers/evolution-outlook-importer.c
diff options
context:
space:
mode:
authorNot Zed <NotZed@Ximian.com>2004-02-13 18:14:30 +0800
committerMichael Zucci <zucchi@src.gnome.org>2004-02-13 18:14:30 +0800
commit39f16a70161b982003faca8b1fea7845a4a4e5fc (patch)
treef757ae0e6cc6957336c07f49781b8bfc50b6f8bc /mail/importers/evolution-outlook-importer.c
parent1f4808666f7070789ada617b9fbb652d4e9512a0 (diff)
downloadgsoc2013-evolution-39f16a70161b982003faca8b1fea7845a4a4e5fc.tar
gsoc2013-evolution-39f16a70161b982003faca8b1fea7845a4a4e5fc.tar.gz
gsoc2013-evolution-39f16a70161b982003faca8b1fea7845a4a4e5fc.tar.bz2
gsoc2013-evolution-39f16a70161b982003faca8b1fea7845a4a4e5fc.tar.lz
gsoc2013-evolution-39f16a70161b982003faca8b1fea7845a4a4e5fc.tar.xz
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/importers/evolution-outlook-importer.c')
-rw-r--r--mail/importers/evolution-outlook-importer.c474
1 files changed, 298 insertions, 176 deletions
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;
+}