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
This commit is contained in:
Not Zed
2004-02-13 10:14:30 +00:00
committed by Michael Zucci
parent 1f4808666f
commit 39f16a7016
8 changed files with 1005 additions and 1191 deletions

View File

@ -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

View File

@ -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);
importer->done_mail = gconf_client_get_bool (gconf, "/apps/evolution/importer/elm/mail", NULL);
g_object_unref(gconf);
}
static void
importer_cb (EvolutionImporterListener *listener,
EvolutionImporterResult result,
gboolean more_items,
void *data)
parse_elm_rc(ElmImporter *importer, const char *elmrc)
{
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;
}
static void
parse_elm_rc (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;
elm_restore_settings(importer);
importer->do_mail = !importer->done_mail;
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (importer->mail), importer->do_mail);
importer->do_mail = !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;
static void
elm_status(CamelOperation *op, const char *what, int pc, void *data)
{
ElmImporter *importer = data;
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);
if (pc == CAMEL_OPERATION_START)
pc = 0;
else if (pc == CAMEL_OPERATION_END)
pc = 100;
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);
}
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);
mail_msg_wait(mail_importer_elm_import(importer));
camel_operation_unref(importer->cancel);
g_source_remove(importer->status_timeout_id);
importer->status_timeout_id = 0;
importer->done_mail = TRUE;
}
elm_store_settings (importer);
if (importer->do_mail == TRUE) {
char *elmdir;
GConfClient *gconf = gconf_client_get_default();
importer->dialog = create_importer_gui (importer);
gtk_widget_show_all (importer->dialog);
while (gtk_events_pending ()) {
gtk_main_iteration ();
}
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);
}
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);
}

View File

@ -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;
GtkWidget *selector;
GtkWidget *label;
GtkWidget *progressbar;
GtkWidget *dialog;
char *uri;
} MboxImporter;
/* EvolutionImporter methods */
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;
g_free(importer->uri);
importer->uri = g_strdup(em_folder_selection_button_get_selection(button));
}
if (importer->folder == NULL) {
GNOME_Evolution_ImporterListener_notifyResult (listener,
GNOME_Evolution_ImporterListener_BAD_FILE,
FALSE, ev);
}
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;
}
static void
create_control_fn(EvolutionImporter *importer, Bonobo_Control *control, void *data)
{
GtkWidget *hbox, *w;
if (!done)
camel_mime_parser_step (mbi->mp, 0, 0);
camel_exception_free (ex);
hbox = gtk_hbox_new(FALSE, FALSE);
GNOME_Evolution_ImporterListener_notifyResult (listener,
GNOME_Evolution_ImporterListener_OK,
!done, ev);
return;
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);
/* 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..."));
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);
importer->status_timeout_id = g_timeout_add(100, mbox_status_timeout, importer);
importer->cancel = camel_operation_new(mbox_status, importer);
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;
fail:
camel_object_unref (mbi->mp);
mbi->mp = NULL;
return FALSE;
}
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);
}

View File

@ -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 */
gboolean busy;
GtkWidget *selector;
GtkWidget *label;
GtkWidget *progressbar;
GtkWidget *dialog;
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)
{
OutlookImporter *importer = data;
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);
}
static void
importer_destroy_cb (void *data, GObject *object)
outlook_status(CamelOperation *op, const char *what, int pc, void *data)
{
OutlookImporter *oli = data;
MailImporter *importer = data;
OutlookImporter *importer = data;
if (importer->folder)
camel_object_unref (importer->folder);
if (pc == CAMEL_OPERATION_START)
pc = 0;
else if (pc == CAMEL_OPERATION_END)
pc = 100;
g_free (oli->filename);
if (oli->handle)
fclose (oli->handle);
g_free (oli);
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;
}

View File

@ -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);
}

View File

@ -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

File diff suppressed because it is too large Load Diff

View File

@ -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);
}