/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ /* evolution-outlook-importer.c * * Authors: Iain Holmes * * Copyright (C) 2001 Ximian, Inc. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation; either version 2 of the * License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public * License along with this program; if not, write to the * Free Software Foundation, Inc., 59 Temple Place - Suite 330, * Boston, MA 02111-1307, USA. */ #ifdef HAVE_CONFIG_H #include #endif #include #include #include #include #include "evolution-outlook-importer.h" #include "mail-importer.h" #include "mail-tools.h" #include extern char *evolution_dir; typedef struct { MailImporter importer; char *filename; gboolean oe4; /* Is file OE4 or not? */ FILE *handle; long pos; off_t size; gboolean busy; } OutlookImporter; struct oe_msg_segmentheader { int self; int increase; int include; int next; int usenet; }; typedef struct oe_msg_segmentheader oe_msg_segmentheader; /* EvolutionImporter methods */ /* Based on code from liboe 0.92 (STABLE) Copyright (C) 2000 Stephan B. Nedregård (stephan@micropop.com) Modified 2001 Iain Holmes Copyright (C) 2001 Ximian, Inc. */ static void process_item_fn (EvolutionImporter *eimporter, CORBA_Object listener, void *closure, 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) { FILE *handle; int signature[4]; /* Outlook Express sniffer. Taken from liboe 0.92 (STABLE) Copyright (C) 2000 Stephan B. Nedregård (stephan@micropop.com) */ handle = fopen (filename, "rb"); if (handle == NULL) 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 */ } fclose (handle); return FALSE; /* Can't handle OE 5 yet */ } static void importer_destroy_cb (GtkObject *object, OutlookImporter *oli) { MailImporter *importer; importer = (MailImporter *) oli; if (importer->folder) camel_object_unref (CAMEL_OBJECT (importer->folder)); g_free (oli->filename); if (oli->handle) fclose (oli->handle); g_free (oli); } static gboolean load_file_fn (EvolutionImporter *eimporter, const char *filename, void *closure) { OutlookImporter *oli; MailImporter *importer; struct stat buf; long pos = 0x54; oli = (OutlookImporter *) closure; importer = (MailImporter *) oli; 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; } 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; } oli->size = buf.st_size; /* Set the fposition to the begining */ fseek (oli->handle, pos, SEEK_SET); oli->pos = pos; importer->mstream = NULL; importer->folder = mail_tool_get_local_inbox (NULL); if (importer->folder == NULL){ g_warning ("Bad folder"); return FALSE; } camel_folder_freeze (importer->folder); oli->busy = FALSE; return TRUE; } BonoboObject * outlook_factory_fn (BonoboGenericFactory *_factory, void *closure) { EvolutionImporter *importer; OutlookImporter *oli; oli = g_new0 (OutlookImporter, 1); importer = evolution_importer_new (support_format_fn, load_file_fn, process_item_fn, NULL, oli); gtk_signal_connect (GTK_OBJECT (importer), "destroy", GTK_SIGNAL_FUNC (importer_destroy_cb), oli); return BONOBO_OBJECT (importer); }