aboutsummaryrefslogtreecommitdiffstats
path: root/camel/providers
diff options
context:
space:
mode:
authorNotZed <NotZed@HelixCode.com>2000-04-21 07:48:45 +0800
committerMichael Zucci <zucchi@src.gnome.org>2000-04-21 07:48:45 +0800
commit383f245d39b8b806a4b6ce4dea7b0ab7f1658450 (patch)
treeb6447bbcd6bd8c4b31582a343ce062e8d2c548c4 /camel/providers
parent6b5b1f6de926a4c9dec95dbd55ae53a5b30fb6a5 (diff)
downloadgsoc2013-evolution-383f245d39b8b806a4b6ce4dea7b0ab7f1658450.tar
gsoc2013-evolution-383f245d39b8b806a4b6ce4dea7b0ab7f1658450.tar.gz
gsoc2013-evolution-383f245d39b8b806a4b6ce4dea7b0ab7f1658450.tar.bz2
gsoc2013-evolution-383f245d39b8b806a4b6ce4dea7b0ab7f1658450.tar.lz
gsoc2013-evolution-383f245d39b8b806a4b6ce4dea7b0ab7f1658450.tar.xz
gsoc2013-evolution-383f245d39b8b806a4b6ce4dea7b0ab7f1658450.tar.zst
gsoc2013-evolution-383f245d39b8b806a4b6ce4dea7b0ab7f1658450.zip
MERGE NEW_PARSER branch into HEAD, fixed conflicts.
2000-04-20 NotZed <NotZed@HelixCode.com> * MERGE NEW_PARSER branch into HEAD, fixed conflicts. * gmime-content-field.c (_print_parameter): Duh, removed again (@@#$@ cvs merge). * camel-mime-utils.c (header_content_type_is): Constify. (header_content_type_unref): Killed a couple warnings. * camel-folder.c (_init): Removed more log crap. * providers/Makefile.am (SUBDIRS): Removed nntp, pending fixes for summary changes. * providers/mbox/camel-mbox-folder.c (_get_message_by_number): Fixed for new summary interface. Added a warning for using this broken api. (_get_message_by_uid): Fixed for message new with session vanishing. svn path=/trunk/; revision=2531
Diffstat (limited to 'camel/providers')
-rw-r--r--camel/providers/Makefile.am2
-rw-r--r--camel/providers/mbox/Makefile.am6
-rw-r--r--camel/providers/mbox/camel-mbox-folder.c543
-rw-r--r--camel/providers/mbox/camel-mbox-folder.h7
-rw-r--r--camel/providers/mbox/camel-mbox-search.c35
-rw-r--r--camel/providers/mbox/camel-mbox-summary.c1556
-rw-r--r--camel/providers/mbox/camel-mbox-summary.h115
-rw-r--r--camel/providers/mbox/camel-mbox-utils.c52
8 files changed, 1470 insertions, 846 deletions
diff --git a/camel/providers/Makefile.am b/camel/providers/Makefile.am
index 888a5d7bb3..7c520a8b8b 100644
--- a/camel/providers/Makefile.am
+++ b/camel/providers/Makefile.am
@@ -1,6 +1,6 @@
## Process this file with automake to produce Makefile.in
-SUBDIRS = mbox pop3 sendmail smtp nntp
+SUBDIRS = mbox pop3 sendmail smtp
# these ones are disabled for the moment.
# MH maildir imap smtp
diff --git a/camel/providers/mbox/Makefile.am b/camel/providers/mbox/Makefile.am
index e3234ce228..4dbe3ed93d 100644
--- a/camel/providers/mbox/Makefile.am
+++ b/camel/providers/mbox/Makefile.am
@@ -24,22 +24,22 @@ libcamelmbox_la_SOURCES = \
camel-mbox-parser.c \
camel-mbox-provider.c \
camel-mbox-store.c \
- camel-mbox-summary.c \
camel-mbox-search.c \
+ camel-mbox-summary.c \
camel-mbox-utils.c
libcamelmboxinclude_HEADERS = \
camel-mbox-folder.h \
camel-mbox-parser.h \
camel-mbox-store.h \
- camel-mbox-summary.h \
camel-mbox-search.h \
+ camel-mbox-summary.h \
camel-mbox-utils.h
-
libcamelmbox_la_LDFLAGS = -version-info 0:0:0 -rpath $(libdir)
libcamelmbox_la_LIBADD = $(top_builddir)/e-util/libeutil.la $(top_builddir)/libibex/libibex.la $(UNICODE_LIBS)
#libcamelmbox_la_LIBADD = $(top_builddir)/libibex/libibex.la $(UNICODE_LIBS)
EXTRA_DIST =
+
diff --git a/camel/providers/mbox/camel-mbox-folder.c b/camel/providers/mbox/camel-mbox-folder.c
index 9cd055a658..2fa3ddc9da 100644
--- a/camel/providers/mbox/camel-mbox-folder.c
+++ b/camel/providers/mbox/camel-mbox-folder.c
@@ -2,9 +2,10 @@
/* camel-mbox-folder.c : Abstract class for an email folder */
/*
- * Author : Bertrand Guiheneuf <bertrand@helixcode.com>
+ * Authors: Bertrand Guiheneuf <bertrand@helixcode.com>
+ * Michael Zucchi <notzed@helixcode.com>
*
- * Copyright (C) 1999 Helix Code .
+ * Copyright (C) 1999, 2000 Helix Code Inc.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
@@ -48,6 +49,8 @@
#include "camel-exception.h"
+#define d(x)
+
static CamelFolderClass *parent_class=NULL;
/* Returns the class for a CamelMboxFolder */
@@ -59,8 +62,6 @@ static CamelFolderClass *parent_class=NULL;
static void _init (CamelFolder *folder, CamelStore *parent_store,
CamelFolder *parent_folder, const gchar *name,
gchar separator, CamelException *ex);
-static void _set_name(CamelFolder *folder, const gchar *name, CamelException *ex);
-
static void _open (CamelFolder *folder, CamelFolderOpenMode mode, CamelException *ex);
static void _close (CamelFolder *folder, gboolean expunge, CamelException *ex);
@@ -80,6 +81,8 @@ static void _copy_message_to (CamelFolder *folder, CamelMimeMessage *message, Ca
static const gchar *_get_message_uid (CamelFolder *folder, CamelMimeMessage *message, CamelException *ex);
#endif
+GPtrArray *summary_get_message_info (CamelFolder *folder, int first, int count);
+
static void _finalize (GtkObject *object);
static void
@@ -94,7 +97,6 @@ camel_mbox_folder_class_init (CamelMboxFolderClass *camel_mbox_folder_class)
/* virtual method overload */
camel_folder_class->init = _init;
- camel_folder_class->set_name = _set_name;
camel_folder_class->open = _open;
camel_folder_class->close = _close;
camel_folder_class->exists = _exists;
@@ -117,12 +119,12 @@ camel_mbox_folder_class_init (CamelMboxFolderClass *camel_mbox_folder_class)
camel_folder_class->search_complete = camel_mbox_folder_search_complete;
camel_folder_class->search_cancel = camel_mbox_folder_search_cancel;
+ camel_folder_class->get_message_info = summary_get_message_info;
+
gtk_object_class->finalize = _finalize;
}
-
-
static void
_finalize (GtkObject *object)
{
@@ -134,10 +136,6 @@ _finalize (GtkObject *object)
GTK_OBJECT_CLASS (parent_class)->finalize (object);
}
-
-
-
-
GtkType
camel_mbox_folder_get_type (void)
{
@@ -162,154 +160,73 @@ camel_mbox_folder_get_type (void)
return camel_mbox_folder_type;
}
-
-
-
-
-
static void
_init (CamelFolder *folder, CamelStore *parent_store,
CamelFolder *parent_folder, const gchar *name, gchar separator,
CamelException *ex)
{
+ CamelMboxFolder *mbox_folder = (CamelMboxFolder *)folder;
+ const gchar *root_dir_path;
+
/* call parent method */
parent_class->init (folder, parent_store, parent_folder,
name, separator, ex);
- if (camel_exception_get_id (ex)) return;
+ if (camel_exception_get_id (ex))
+ return;
/* we assume that the parent init
method checks for the existance of @folder */
-
folder->can_hold_messages = TRUE;
folder->can_hold_folders = TRUE;
folder->has_summary_capability = TRUE;
folder->has_uid_capability = TRUE;
folder->has_search_capability = TRUE;
- folder->summary = NULL;
-}
-
+ mbox_folder->summary = NULL;
-/* internal method used to :
- - test for the existence of a summary file
- - test the sync between the summary and the mbox file
- - load the summary or create it if necessary
-*/
-static void
-_check_get_or_maybe_generate_summary_file (CamelMboxFolder *mbox_folder,
- CamelException *ex)
-{
- CamelFolder *folder = CAMEL_FOLDER (mbox_folder);
- CamelMboxSummary *summ;
- GArray *message_info_array;
- gint mbox_file_fd;
- guint32 next_uid;
- guint32 file_size;
- struct stat st;
-
- folder->summary = NULL;
-
- /* Test for the existence and up-to-dateness of the summary file. */
- if (access (mbox_folder->summary_file_path, F_OK) == 0) {
- summ = camel_mbox_summary_load (mbox_folder->summary_file_path,
- ex);
- if (summ) {
- if (stat (mbox_folder->folder_file_path, &st) == 0 &&
- summ->mbox_file_size == st.st_size &&
- summ->mbox_modtime == st.st_mtime)
- folder->summary = CAMEL_FOLDER_SUMMARY (summ);
- else
- gtk_object_destroy (GTK_OBJECT (summ));
- } else {
- /* Bad summary file */
- if (camel_exception_get_id (ex) !=
- CAMEL_EXCEPTION_FOLDER_SUMMARY_INVALID)
- return;
- camel_exception_clear (ex);
- }
- }
-
- /* In the case where the summary does not exist (or was the
- * wrong version), or is not in sync with the mbox file,
- * regenerate it.
- */
- if (folder->summary == NULL) {
- /* Parse the mbox folder and get some information
- * about the messages.
- */
- mbox_file_fd = open (mbox_folder->folder_file_path, O_RDONLY);
- if (mbox_file_fd != -1) {
- message_info_array =
- camel_mbox_parse_file (mbox_file_fd, "From ",
- 0, &file_size,
- &next_uid, TRUE,
- NULL, 0, ex);
- close (mbox_file_fd);
- if (camel_exception_get_id (ex))
- return;
-
- next_uid = camel_mbox_write_xev (mbox_folder,
- mbox_folder->folder_file_path,
- message_info_array,
- &file_size,
- next_uid, ex);
- if (camel_exception_get_id (ex)) {
- /* ** FIXME : free the preparsed information */
- return;
- }
+ /* now set the name info */
+ g_free (mbox_folder->folder_file_path);
+ g_free (mbox_folder->folder_dir_path);
+ g_free (mbox_folder->index_file_path);
- summ = CAMEL_MBOX_SUMMARY (gtk_object_new (camel_mbox_summary_get_type (), NULL));
- summ->message_info = parsed_information_to_mbox_summary (message_info_array);
- summ->nb_message = summ->message_info->len;
- summ->next_uid = next_uid;
- summ->mbox_file_size = file_size;
- /* **FIXME : Free the parsed information structure */
- } else {
- summ = CAMEL_MBOX_SUMMARY (gtk_object_new (camel_mbox_summary_get_type (), NULL));
- summ->message_info = g_array_new (FALSE, FALSE, sizeof (CamelMboxSummaryInformation));
- summ->nb_message = 0;
- summ->next_uid = 0;
- summ->mbox_file_size = 0;
- }
+ root_dir_path = camel_mbox_store_get_toplevel_dir (CAMEL_MBOX_STORE(folder->parent_store));
- folder->summary = CAMEL_FOLDER_SUMMARY (summ);
- }
+ mbox_folder->folder_file_path = g_strdup_printf ("%s/%s", root_dir_path, folder->full_name);
+ mbox_folder->summary_file_path = g_strdup_printf ("%s/%s-ev-summary", root_dir_path, folder->full_name);
+ mbox_folder->folder_dir_path = g_strdup_printf ("%s/%s.sdb", root_dir_path, folder->full_name);
+ mbox_folder->index_file_path = g_strdup_printf ("%s/%s.ibex", root_dir_path, folder->full_name);
}
-
-
static void
_open (CamelFolder *folder, CamelFolderOpenMode mode, CamelException *ex)
{
CamelMboxFolder *mbox_folder = CAMEL_MBOX_FOLDER (folder);
+ /* call parent class */
+ parent_class->open (folder, mode, ex);
+ if (camel_exception_get_id(ex))
+ return;
+
mbox_folder->index = ibex_open(mbox_folder->index_file_path, O_CREAT|O_RDWR, 0600);
if (mbox_folder->index == NULL) {
g_warning("Could not open/create index file: %s: indexing will not function",
strerror(errno));
}
- /* call parent class */
- parent_class->open (folder, mode, ex);
- if (camel_exception_get_id(ex))
+ mbox_folder->summary = camel_mbox_summary_new(mbox_folder->summary_file_path, mbox_folder->folder_file_path, mbox_folder->index);
+ if (mbox_folder->summary == NULL) {
+ camel_exception_set (ex,
+ CAMEL_EXCEPTION_FOLDER_INVALID, /* FIXME: right error code */
+ "Could not create summary");
return;
-
-#if 0
- /* get (or create) uid list */
- if (!(mbox_load_uid_list (mbox_folder) > 0))
- mbox_generate_uid_list (mbox_folder);
-#endif
-
- _check_get_or_maybe_generate_summary_file (mbox_folder, ex);
+ }
+ camel_mbox_summary_load(mbox_folder->summary);
}
-
static void
_close (CamelFolder *folder, gboolean expunge, CamelException *ex)
{
CamelMboxFolder *mbox_folder = CAMEL_MBOX_FOLDER (folder);
- CamelMboxSummary *mbox_summary = CAMEL_MBOX_SUMMARY (folder->summary);
- struct stat st;
/* call parent implementation */
parent_class->close (folder, expunge, ex);
@@ -317,47 +234,15 @@ _close (CamelFolder *folder, gboolean expunge, CamelException *ex)
/* save index */
if (mbox_folder->index) {
ibex_close(mbox_folder->index);
+ mbox_folder->index = NULL;
}
-
- /* Update the summary and save it to disk */
- if (stat (mbox_folder->folder_file_path, &st) == 0) {
- mbox_summary->mbox_file_size = st.st_size;
- mbox_summary->mbox_modtime = st.st_mtime;
- }
- camel_mbox_summary_save (mbox_summary,
- mbox_folder->summary_file_path, ex);
-}
-
-
-
-
-static void
-_set_name (CamelFolder *folder, const gchar *name, CamelException *ex)
-{
- CamelMboxFolder *mbox_folder = CAMEL_MBOX_FOLDER (folder);
- const gchar *root_dir_path;
-
- /* call default implementation */
- parent_class->set_name (folder, name, ex);
- if (camel_exception_get_id (ex)) return;
-
- g_free (mbox_folder->folder_file_path);
- g_free (mbox_folder->folder_dir_path);
- g_free (mbox_folder->index_file_path);
-
- root_dir_path = camel_mbox_store_get_toplevel_dir (CAMEL_MBOX_STORE(folder->parent_store));
-
- mbox_folder->folder_file_path = g_strdup_printf ("%s/%s", root_dir_path, folder->full_name);
- mbox_folder->summary_file_path = g_strdup_printf ("%s/%s-ev-summary", root_dir_path, folder->full_name);
- mbox_folder->folder_dir_path = g_strdup_printf ("%s/%s.sdb", root_dir_path, folder->full_name);
- mbox_folder->index_file_path = g_strdup_printf ("%s/%s.ibex", root_dir_path, folder->full_name);
+ camel_mbox_summary_save (mbox_folder->summary);
+ camel_mbox_summary_unref (mbox_folder->summary);
+ mbox_folder->summary = NULL;
}
-
-
-
-
+/* FIXME: clean up this snot */
static gboolean
_exists (CamelFolder *folder, CamelException *ex)
{
@@ -420,18 +305,11 @@ _exists (CamelFolder *folder, CamelException *ex)
return exists;
}
-
-
-
-
-
-
-
+/* FIXME: clean up this snot */
static gboolean
_create (CamelFolder *folder, CamelException *ex)
{
CamelMboxFolder *mbox_folder = CAMEL_MBOX_FOLDER (folder);
- CamelMboxSummary *summary;
const gchar *folder_file_path, *folder_dir_path;
mode_t dir_mode = S_IRWXU;
gint mkdir_error;
@@ -480,13 +358,6 @@ _create (CamelFolder *folder, CamelException *ex)
close (creat_fd);
- /* create the summary object */
- summary = CAMEL_MBOX_SUMMARY (gtk_object_new (camel_mbox_summary_get_type (), NULL));
- summary->nb_message = 0;
- summary->next_uid = 1;
- summary->mbox_file_size = 0;
- summary->message_info = g_array_new (FALSE, FALSE, sizeof (CamelMboxSummaryInformation));
-
return TRUE;
/* exception handling for io errors */
@@ -505,7 +376,7 @@ _create (CamelFolder *folder, CamelException *ex)
}
-
+/* FIXME: cleanup */
static gboolean
_delete (CamelFolder *folder, gboolean recurse, CamelException *ex)
{
@@ -605,9 +476,7 @@ _delete (CamelFolder *folder, gboolean recurse, CamelException *ex)
return TRUE;
}
-
-
-
+/* TODO: remove this */
gboolean
_delete_messages (CamelFolder *folder, CamelException *ex)
{
@@ -616,7 +485,6 @@ _delete_messages (CamelFolder *folder, CamelException *ex)
const gchar *folder_file_path;
gboolean folder_already_exists;
int creat_fd;
-
g_assert(folder!=NULL);
/* in the case where the folder does not exist,
@@ -667,7 +535,7 @@ _delete_messages (CamelFolder *folder, CamelException *ex)
}
-
+/* FIXME: cleanup */
static GList *
_list_subfolders (CamelFolder *folder, CamelException *ex)
{
@@ -786,138 +654,133 @@ _list_subfolders (CamelFolder *folder, CamelException *ex)
return NULL;
}
-
-
-
static gint
_get_message_count (CamelFolder *folder, CamelException *ex)
{
- gint message_count;
+ CamelMboxFolder *mbox_folder = (CamelMboxFolder *)folder;
g_assert (folder);
- g_assert (folder->summary);
+ g_assert (mbox_folder->summary);
- message_count = CAMEL_MBOX_SUMMARY (folder->summary)->nb_message;
-
- return message_count;
+ return camel_mbox_summary_message_count(mbox_folder->summary);
}
+/*
+ This is a lazy append.
+ Basically, messages are appended to the end of the mbox, and probably assigned
+ a new uid (they wont be if copying from a source folder which doesn't have
+ a uid - which wont happen with the current summariser).
+
+ Indexing/summarising happens when the mbox is next queried.
+
+ Should this set a flag up for subsequent updating??
+*/
+
+/* FIXME: this may need some tweaking for performance? */
static void
_append_message (CamelFolder *folder, CamelMimeMessage *message, CamelException *ex)
{
- CamelMboxFolder *mbox_folder = CAMEL_MBOX_FOLDER (folder);
- CamelMboxSummary *summary = CAMEL_MBOX_SUMMARY (folder->summary);
+ CamelMboxFolder *mbox_folder = CAMEL_MBOX_FOLDER (folder), *source_folder;
CamelStream *output_stream;
- guint32 tmp_file_size;
- guint32 next_uid;
- gint tmp_file_fd;
- GArray *message_info_array;
- GArray *mbox_summary_info;
- gchar *tmp_message_filename;
- gint fd1, fd2;
- int i;
-
- tmp_message_filename = g_strdup_printf ("%s.tmp",
- mbox_folder->folder_file_path);
-
- /* write the message itself */
- output_stream = camel_stream_fs_new_with_name (tmp_message_filename,
- CAMEL_STREAM_FS_WRITE);
- if (output_stream != NULL) {
- camel_stream_write_string (output_stream, "From - \n");
- camel_data_wrapper_write_to_stream (CAMEL_DATA_WRAPPER (message), output_stream);
- }
- camel_stream_close (output_stream);
- gtk_object_unref (GTK_OBJECT (output_stream));
-
- /* at this point we have saved the message to a
- temporary file, now, we have to add the x-evolution
- field and also update the main summary */
-
- /*
- First : parse the mbox file, but only from the
- position where the message has been added,
- wich happens to be the last postion in the
- mbox file before we added the message.
- This position is still stored in the summary
- for the moment
- */
- next_uid = summary->next_uid;
- tmp_file_fd = open (tmp_message_filename, O_RDONLY);
- message_info_array =
- camel_mbox_parse_file (tmp_file_fd, "From - ", 0,
- &tmp_file_size, &next_uid, TRUE,
- NULL, 0, ex);
-
- close (tmp_file_fd);
-
- /* get the value of the last available UID
- as saved in the summary file, again */
- next_uid = summary->next_uid;
-
- /* make sure all our of message info's have 0 uid - ignore any
- set elsewhere */
- for (i=0;i<message_info_array->len;i++) {
- g_array_index(message_info_array, CamelMboxParserMessageInfo, i).uid = 0;
- }
+ struct stat st;
+ off_t seek;
+ char *xev;
+ guint32 uid;
- /*
- OK, this is not very efficient, we should not use the same
- method as for parsing an entire mail file,
- but I have no time to write a simpler parser
- */
- next_uid = camel_mbox_write_xev (mbox_folder, tmp_message_filename,
- message_info_array, &tmp_file_size, next_uid, ex);
-
- if (camel_exception_get_id (ex)) {
- /* ** FIXME : free the preparsed information */
+ if (stat(mbox_folder->folder_file_path, &st) != 0) {
+ camel_exception_setv (ex,
+ CAMEL_EXCEPTION_FOLDER_INSUFFICIENT_PERMISSION, /* FIXME: what code? */
+ "Cannot append to mbox file: %s", strerror (errno));
return;
}
- mbox_summary_info =
- parsed_information_to_mbox_summary (message_info_array);
+ /* are we coming from an mbox folder? then we can optimise somewhat ... */
+ if (message->folder && IS_CAMEL_MBOX_FOLDER(message->folder)) {
+ CamelMboxMessageInfo *info;
+ int sfd, dfd;
+ off_t pos;
- /* store the number of messages as well as the summary array */
- summary->nb_message += 1;
- summary->next_uid = next_uid;
+ /* FIXME: this is pretty ugly - we lookup the message info in the source folder, copy it,
+ then go back and paste in its real uid. */
+ source_folder = (CamelMboxFolder *)message->folder;
+ info = camel_mbox_summary_uid(source_folder->summary, message->message_uid);
- ((CamelMboxSummaryInformation *)(mbox_summary_info->data))->position +=
- summary->mbox_file_size;
- summary->mbox_file_size += tmp_file_size;
+ d(printf("Copying message directly from %s to %s\n", source_folder->folder_file_path, mbox_folder->folder_file_path));
+ d(printf("start = %d, xev = %d\n", ((CamelMboxMessageContentInfo *)info->info.content)->pos, info->xev_offset));
- camel_mbox_summary_append_entries (summary, mbox_summary_info);
- g_array_free (mbox_summary_info, TRUE);
-
+ sfd = open(source_folder->folder_file_path, O_RDONLY);
+ dfd = open(mbox_folder->folder_file_path, O_RDWR|O_CREAT, 0600);
+ if (lseek(dfd, st.st_size, SEEK_SET) != st.st_size) {
+ camel_exception_setv (ex,
+ CAMEL_EXCEPTION_FOLDER_INSUFFICIENT_PERMISSION, /* FIXME: what code? */
+ "Cannot append to mbox file: %s", strerror (errno));
+ close(sfd);
+ close(dfd);
+ return;
+ }
+ write(dfd, "From - \n", strlen("From - \n"));
+ camel_mbox_summary_copy_block
+ (sfd, dfd, ((CamelMboxMessageContentInfo *)info->info.content)->pos,
+ ((CamelMboxMessageContentInfo *)info->info.content)->endpos - ((CamelMboxMessageContentInfo *)info->info.content)->pos);
+ if (info->xev_offset != -1) {
+ pos = st.st_size + (info->xev_offset - ((CamelMboxMessageContentInfo *)info->info.content)->pos) + strlen("From - \n");
+ d(printf("Inserting new uid at %d\n", (int)pos));
+ if (pos != lseek(dfd, pos, SEEK_SET)) {
+ ftruncate(dfd, st.st_size);
+ camel_exception_setv (ex,
+ CAMEL_EXCEPTION_FOLDER_INSUFFICIENT_PERMISSION, /* FIXME: what code? */
+ "Cannot append to mbox file: %s", strerror (errno));
+ close(sfd);
+ close(dfd);
+ return;
+ }
+ uid = camel_mbox_summary_next_uid(mbox_folder->summary);
+ xev = g_strdup_printf("X-Evolution: %08x-%04x", uid, 0);
+ write(dfd, xev, strlen(xev)); /* FIXME: check return */
+ d(printf("header = %s\n", xev));
+ g_free(xev);
+ }
+ close(sfd);
+ close(dfd);
+ return;
+ }
- /* append the temporary file message to the mbox file */
- fd1 = open (tmp_message_filename, O_RDONLY);
- fd2 = open (mbox_folder->folder_file_path,
- O_WRONLY | O_CREAT | O_APPEND,
- 0600);
+ /* its not an mbox folder, so lets do it the slow way ... */
+ output_stream = camel_stream_fs_new_with_name (mbox_folder->folder_file_path, CAMEL_STREAM_FS_WRITE);
+ if (output_stream == NULL) {
+ camel_exception_setv (ex,
+ CAMEL_EXCEPTION_FOLDER_INSUFFICIENT_PERMISSION, /* FIXME: what code? */
+ "Cannot append to mbox file: %s", strerror (errno));
+ return;
+ }
- if (fd2 == -1) {
+ seek = camel_seekable_stream_seek((CamelSeekableStream *)output_stream, st.st_size, SEEK_SET);
+ if (seek != st.st_size) {
camel_exception_setv (ex,
- CAMEL_EXCEPTION_FOLDER_INSUFFICIENT_PERMISSION,
- "could not open the mbox folder file for appending the message\n"
- "\t%s\n"
- "Full error is : %s\n",
- mbox_folder->folder_file_path,
- strerror (errno));
+ CAMEL_EXCEPTION_FOLDER_INSUFFICIENT_PERMISSION, /* FIXME: what code? */
+ "Cannot seek to position in mbox file: %s", strerror (errno));
+ gtk_object_unref ((GtkObject *)output_stream);
return;
}
- camel_mbox_copy_file_chunk (fd1,
- fd2,
- tmp_file_size,
- ex);
- close (fd1);
- close (fd2);
+ /* assign a new x-evolution header */
+ /* FIXME: save flags? */
+ camel_medium_remove_header((CamelMedium *)message, "X-Evolution");
+ uid = camel_mbox_summary_next_uid(mbox_folder->summary);
+ xev = g_strdup_printf("%08x-%04x", uid, 0);
+ camel_medium_add_header((CamelMedium *)message, "X-Evolution", xev);
+ g_free(xev);
+
+ camel_stream_write_string (output_stream, "From - \n");
+ /* FIXME: does this return an error? IT HAS TO FOR THIS TO BE RELIABLE */
+ camel_data_wrapper_write_to_stream (CAMEL_DATA_WRAPPER (message), output_stream);
+ camel_stream_close (output_stream);
- /* remove the temporary file */
- unlink (tmp_message_filename);
+ /* TODO: update the summary so it knows a new message is there to summarise/index */
+ /* This is only a performance improvement, the summary is *only* a cache */
- g_free (tmp_message_filename);
+ gtk_object_unref (GTK_OBJECT (output_stream));
}
@@ -926,109 +789,95 @@ _append_message (CamelFolder *folder, CamelMimeMessage *message, CamelException
static GList *
_get_uid_list (CamelFolder *folder, CamelException *ex)
{
- GArray *message_info_array;
- CamelMboxSummaryInformation *message_info;
GList *uid_list = NULL;
- int i;
-
- message_info_array =
- CAMEL_MBOX_SUMMARY (folder->summary)->message_info;
-
- for (i=0; i<message_info_array->len; i++) {
- message_info = (CamelMboxSummaryInformation *)(message_info_array->data) + i;
- uid_list = g_list_prepend (uid_list, g_strdup_printf ("%u", message_info->uid));
+ CamelMboxFolder *mbox_folder = (CamelMboxFolder *)folder;
+ int i, count;
+
+ /* FIXME: how are these allocated strings ever free'd? */
+ count = camel_mbox_summary_message_count(mbox_folder->summary);
+ for (i=0;i<count;i++) {
+ CamelMboxMessageInfo *info = camel_mbox_summary_index(mbox_folder->summary, i);
+ uid_list = g_list_prepend(uid_list, g_strdup(info->info.uid));
}
return uid_list;
}
-
-
-
static CamelMimeMessage *
_get_message_by_number (CamelFolder *folder, gint number, CamelException *ex)
{
- GArray *message_info_array;
- CamelMboxSummaryInformation *message_info;
- char uidbuf[20];
+ CamelMboxFolder *mbox_folder = (CamelMboxFolder *)folder;
+ CamelMboxMessageInfo *info;
- message_info_array =
- CAMEL_MBOX_SUMMARY (folder->summary)->message_info;
+ g_warning("YOUR CODE SHOULD NOT BE GETTING MESSAGES BY NUMBER, CHANGE IT");
- if (number > message_info_array->len) {
+ info = camel_mbox_summary_index(mbox_folder->summary, number);
+ if (info == NULL) {
camel_exception_setv (ex, CAMEL_EXCEPTION_FOLDER_INVALID,
"No such message %d in folder `%s'.",
number, folder->name);
return NULL;
}
- message_info =
- (CamelMboxSummaryInformation *)(message_info_array->data) +
- (number - 1);
- sprintf (uidbuf, "%lu", message_info->uid);
-
- return _get_message_by_uid (folder, uidbuf, ex);
+ return _get_message_by_uid (folder, info->info.uid, ex);
}
-
static CamelMimeMessage *
_get_message_by_uid (CamelFolder *folder, const gchar *uid, CamelException *ex)
{
-
CamelMboxFolder *mbox_folder = CAMEL_MBOX_FOLDER (folder);
- GArray *message_info_array;
- CamelMboxSummaryInformation *message_info = NULL;
- guint32 searched_uid;
- int i;
- gboolean uid_found;
CamelStream *message_stream;
CamelMimeMessage *message = NULL;
CamelStore *parent_store;
+ CamelMboxMessageInfo *info;
- searched_uid = strtoul (uid, NULL, 10);
-
- message_info_array =
- CAMEL_MBOX_SUMMARY (folder->summary)->message_info;
- i=0;
- uid_found = FALSE;
-
- /* first, look for the message that has the searched uid */
- while ((i<message_info_array->len) && (!uid_found)) {
- message_info = (CamelMboxSummaryInformation *)(message_info_array->data) + i;
- uid_found = (message_info->uid == searched_uid);
- i++;
+ /* get the parent store */
+ parent_store = camel_folder_get_parent_store (folder, ex);
+ if (camel_exception_get_id (ex)) {
+ return NULL;
}
-
- /* if the uid was not found, raise an exception and return */
- if (!uid_found) {
+
+ /* get the message summary info */
+ info = camel_mbox_summary_uid(mbox_folder->summary, uid);
+
+ if (info == NULL) {
camel_exception_setv (ex,
CAMEL_EXCEPTION_FOLDER_INVALID_UID,
"uid %s not found in the folder",
uid);
return NULL;
}
-
- /* at this point, the message_info structure
- contains the informations concerning the
- message that was searched for */
-
- /* create a stream bound to the message */
+
+ /* if this has no content, its an error in the library */
+ g_assert(info->info.content);
+
+ /* FIXME: more checks below */
+ /* create a stream bound to the message position/size */
message_stream = camel_stream_fs_new_with_name_and_bounds (mbox_folder->folder_file_path,
CAMEL_STREAM_FS_READ,
- message_info->position,
- message_info->position + message_info->size);
+ ((CamelMboxMessageContentInfo *)info->info.content)->pos,
+ ((CamelMboxMessageContentInfo *)info->info.content)->endpos);
+ message = camel_mime_message_new();
+ camel_data_wrapper_set_input_stream (CAMEL_DATA_WRAPPER (message), message_stream);
+ /* init other fields? */
+ message->folder = folder;
+ message->message_uid = g_strdup(uid);
- /* get the parent store */
- parent_store = camel_folder_get_parent_store (folder, ex);
- if (camel_exception_get_id (ex)) {
- gtk_object_unref (GTK_OBJECT (message_stream));
- return NULL;
- }
-
-
- message = camel_mime_message_new ();
- camel_data_wrapper_set_input_stream (CAMEL_DATA_WRAPPER (message), message_stream);
-
return message;
}
+
+/* get message info for a range of messages */
+GPtrArray *summary_get_message_info (CamelFolder *folder, int first, int count)
+{
+ GPtrArray *array = g_ptr_array_new();
+ int i, maxcount;
+ CamelMboxFolder *mbox_folder = (CamelMboxFolder *)folder;
+
+ maxcount = camel_mbox_summary_message_count(mbox_folder->summary);
+ maxcount = MAX(count, maxcount);
+ for (i=first;i<maxcount;i++)
+ g_ptr_array_add(array, g_ptr_array_index(mbox_folder->summary->messages, i));
+
+ return array;
+}
diff --git a/camel/providers/mbox/camel-mbox-folder.h b/camel/providers/mbox/camel-mbox-folder.h
index 52d3fa6e70..f74c51a6c3 100644
--- a/camel/providers/mbox/camel-mbox-folder.h
+++ b/camel/providers/mbox/camel-mbox-folder.h
@@ -35,8 +35,8 @@ extern "C" {
#include <gtk/gtk.h>
#include "camel-folder.h"
-#include "camel-mbox-summary.h"
#include "libibex/ibex.h"
+#include "camel-mbox-summary.h"
/* #include "camel-store.h" */
@@ -45,7 +45,6 @@ extern "C" {
#define CAMEL_MBOX_FOLDER_CLASS(k) (GTK_CHECK_CLASS_CAST ((k), CAMEL_MBOX_FOLDER_TYPE, CamelMboxFolderClass))
#define IS_CAMEL_MBOX_FOLDER(o) (GTK_CHECK_TYPE((o), CAMEL_MBOX_FOLDER_TYPE))
-
typedef struct {
CamelFolder parent_object;
@@ -54,11 +53,11 @@ typedef struct {
gchar *folder_dir_path; /* contains the subfolders */
gchar *index_file_path; /* index of body contents */
- GList *uid_array;
-
ibex *index; /* index for this folder */
int search_id; /* next search id */
GList *searches; /* current searches */
+
+ CamelMboxSummary *summary;
} CamelMboxFolder;
diff --git a/camel/providers/mbox/camel-mbox-search.c b/camel/providers/mbox/camel-mbox-search.c
index 1a584b8db6..1e134476e5 100644
--- a/camel/providers/mbox/camel-mbox-search.c
+++ b/camel/providers/mbox/camel-mbox-search.c
@@ -84,10 +84,9 @@ struct _searchcontext {
ibex *index; /* index of content for this folder */
#endif
- CamelFolderSummary *summary;
- const GArray *message_info;
+ CamelMboxSummary *summary;
- CamelMessageInfo *message_current; /* when performing a (match operation */
+ CamelMboxMessageInfo *message_current; /* when performing a (match operation */
};
struct _glib_sux_donkeys {
@@ -115,7 +114,7 @@ func_body_contains(struct _ESExp *f, int argc, struct _ESExpResult **argv, void
if (ctx->index) {
for (i=0;i<argc && !truth;i++) {
if (argv[i]->type == ESEXP_RES_STRING) {
- truth = ibex_find_name(ctx->index, ctx->message_current->uid, argv[i]->value.string);
+ truth = ibex_find_name(ctx->index, ctx->message_current->info.uid, argv[i]->value.string);
} else {
g_warning("Invalid type passed to body-contains match function");
}
@@ -189,19 +188,19 @@ func_match_all(struct _ESExp *f, int argc, struct _ESExpTerm **argv, void *data)
r = e_sexp_result_new(ESEXP_RES_ARRAY_PTR);
r->value.ptrarray = g_ptr_array_new();
- for (i=0;i<ctx->message_info->len;i++) {
+ for (i=0;i<ctx->summary->messages->len;i++) {
if (argc>0) {
- ctx->message_current = &g_array_index(ctx->message_info, CamelMessageInfo, i);
+ ctx->message_current = g_ptr_array_index(ctx->summary->messages, i);
r1 = e_sexp_term_eval(f, argv[0]);
if (r1->type == ESEXP_RES_BOOL) {
if (r1->value.bool)
- g_ptr_array_add(r->value.ptrarray, ctx->message_current->uid);
+ g_ptr_array_add(r->value.ptrarray, ctx->message_current->info.uid);
} else {
g_warning("invalid syntax, matches require a single bool result");
}
e_sexp_result_free(r1);
} else {
- g_ptr_array_add(r->value.ptrarray, ctx->message_current->uid);
+ g_ptr_array_add(r->value.ptrarray, ctx->message_current->info.uid);
}
}
ctx->message_current = NULL;
@@ -221,27 +220,28 @@ func_header_contains(struct _ESExp *f, int argc, struct _ESExpResult **argv, voi
/* are we inside a match-all? */
if (ctx->message_current && argc>1
&& argv[0]->type == ESEXP_RES_STRING) {
- char *headername, *header;
+ char *headername, *header = NULL;
+ char strbuf[32];
int i;
/* only a subset of headers are supported .. */
headername = argv[0]->value.string;
if (!strcasecmp(headername, "subject")) {
- header = ctx->message_current->subject;
+ header = ctx->message_current->info.subject;
} else if (!strcasecmp(headername, "date")) {
- header = ctx->message_current->sent_date;
+ sprintf(strbuf, "%d", (int)ctx->message_current->info.date_sent);
+ header = strbuf;
} else if (!strcasecmp(headername, "from")) {
- header = ctx->message_current->sender;
+ header = ctx->message_current->info.from;
} else {
g_warning("Performing query on unknown header: %s", headername);
- header = NULL;
}
if (header) {
for (i=1;i<argc && !truth;i++) {
if (argv[i]->type == ESEXP_RES_STRING
&& strstr(header, argv[i]->value.string)) {
- printf("%s got a match with %s of %s\n", ctx->message_current->uid, header, argv[i]->value.string);
+ printf("%s got a match with %s of %s\n", ctx->message_current->info.uid, header, argv[i]->value.string);
truth = TRUE;
break;
}
@@ -276,6 +276,7 @@ int camel_mbox_folder_search_by_expression(CamelFolder *folder, const char *expr
GList *matches = NULL;
ESExp *f;
ESExpResult *r;
+ CamelMboxFolder *mbox_folder = (CamelMboxFolder *)folder;
/* setup our expression evaluator */
f = e_sexp_new();
@@ -286,7 +287,7 @@ int camel_mbox_folder_search_by_expression(CamelFolder *folder, const char *expr
/* setup out context */
ctx->folder = folder;
- ctx->summary = camel_folder_get_summary(folder, ex);
+ ctx->summary = mbox_folder->summary;
if (ctx->summary == NULL || camel_exception_get_id (ex)) {
printf ("Cannot get summary\n"
@@ -296,10 +297,7 @@ int camel_mbox_folder_search_by_expression(CamelFolder *folder, const char *expr
return -1;
}
- gtk_object_ref((GtkObject *)ctx->summary);
-
/* FIXME: the index should be global to the folder */
- ctx->message_info = CAMEL_MBOX_SUMMARY(ctx->summary)->message_info;
ctx->message_current = NULL;
ctx->index = CAMEL_MBOX_FOLDER(folder)->index;
if (!ctx->index) {
@@ -337,7 +335,6 @@ int camel_mbox_folder_search_by_expression(CamelFolder *folder, const char *expr
printf("no result!\n");
}
- gtk_object_unref((GtkObject *)ctx->summary);
gtk_object_unref((GtkObject *)f);
i = ctx->id;
diff --git a/camel/providers/mbox/camel-mbox-summary.c b/camel/providers/mbox/camel-mbox-summary.c
index e15bb13b03..11f1c5779a 100644
--- a/camel/providers/mbox/camel-mbox-summary.c
+++ b/camel/providers/mbox/camel-mbox-summary.c
@@ -1,420 +1,1258 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
-
-/*
- * Author : Bertrand Guiheneuf <bertrand@helixcode.com>
+/*
+ * Copyright (C) 2000 Helix Code Inc.
*
- * Copyright (C) 1999 - 2000 Helix Code .
-
- * 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.
+ * Authors: Michael Zucchi <notzed@helixcode.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library 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.
+ * 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 Library 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
+ * You should have received a copy of the GNU Library General Public
+ * License along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
-
-#include <config.h>
-
-#include "camel-exception.h"
-#include "camel-mbox-folder.h"
-#include "camel-mbox-summary.h"
-#include "md5-utils.h"
-
-
-#include <sys/stat.h>
-#include <unistd.h>
#include <sys/types.h>
+#include <sys/stat.h>
#include <fcntl.h>
-#include <dirent.h>
+#include <unistd.h>
+#include <sys/uio.h>
+
#include <stdio.h>
#include <string.h>
+
+#include <gtk/gtk.h>
+
+#include <camel/camel-mime-parser.h>
+#include <camel/camel-mime-filter.h>
+#include <camel/camel-mime-filter-basic.h>
+#include <camel/camel-mime-filter-charset.h>
+#include <camel/camel-mime-filter-index.h>
+
+#include <camel/camel-mime-utils.h>
+
+#include "camel-mbox-summary.h"
+
#include <errno.h>
+#include <ctype.h>
#include <netinet/in.h>
-static CamelFolderSummaryClass *parent_class = NULL;
+#define d(x)
-static int count_messages (CamelFolderSummary *summary);
-static int count_subfolders (CamelFolderSummary *summary);
-static GPtrArray *get_subfolder_info (CamelFolderSummary *summary,
- int first, int count);
-static GPtrArray *get_message_info (CamelFolderSummary *summary,
- int first, int count);
-static void finalize (GtkObject *object);
+#define CAMEL_MBOX_SUMMARY_VERSION 2
-static void
-camel_mbox_summary_class_init (CamelMboxSummaryClass *camel_mbox_summary_class)
+static int safe_write(int fd, char *buffer, size_t towrite);
+static void camel_mbox_summary_add(CamelMboxSummary *s, CamelMboxMessageInfo *info);
+
+/*
+ Disk file format?
+
+ message uid
+message-block
+ date:
+ date received?
+
+ subject: (unicode encoded)
+ from: (unicode encoded)
+ to: (unicode)
+
+ content-block
+
+content-block
+ content-type: ; params;
+ content-id:
+ content-description:
+ content-transfer-encoding:
+ message-start:
+ header-size:
+ body-size:
+
+ message-block
+ multipart-block
+
+ */
+
+/* pah, i dont care, its almost no code and it works, dont need a glist */
+struct _node {
+ struct _node *next;
+};
+
+static struct _node *
+my_list_append(struct _node **list, struct _node *n)
+{
+ struct _node *ln = (struct _node *)list;
+ while (ln->next)
+ ln = ln->next;
+ n->next = 0;
+ ln->next = n;
+ return n;
+}
+
+static int
+my_list_size(struct _node **list)
+{
+ int len = 0;
+ struct _node *ln = (struct _node *)list;
+ while (ln->next) {
+ ln = ln->next;
+ len++;
+ }
+ return len;
+}
+
+/* low-level io functions */
+static int
+encode_int (FILE *out, gint32 value)
+{
+ int i;
+
+ for (i=28;i>0;i-=7) {
+ if (value >= (1<<i)) {
+ unsigned int c = (value>>i) & 0x7f;
+ if (fputc(c, out) == -1)
+ return -1;
+ }
+ }
+ return fputc(value | 0x80, out);
+}
+
+static gint32
+decode_int (FILE *in)
{
- GtkObjectClass *gtk_object_class =
- GTK_OBJECT_CLASS (camel_mbox_summary_class);
- CamelFolderSummaryClass *camel_folder_summary_class =
- CAMEL_FOLDER_SUMMARY_CLASS (camel_mbox_summary_class);
+ gint32 value=0, v;
- parent_class = gtk_type_class (camel_folder_summary_get_type ());
+ /* until we get the last byte, keep decoding 7 bits at a time */
+ while ( ((v = fgetc(in)) & 0x80) == 0 && v!=EOF) {
+ value |= v;
+ value <<= 7;
+ }
+ value |= (v&0x7f);
+ return value;
+}
- /* virtual method override */
- camel_folder_summary_class->count_messages = count_messages;
- camel_folder_summary_class->count_subfolders = count_subfolders;
- camel_folder_summary_class->get_subfolder_info = get_subfolder_info;
- camel_folder_summary_class->get_message_info = get_message_info;
+static int
+encode_fixed_int (FILE *out, gint32 value)
+{
+ guint32 save;
- gtk_object_class->finalize = finalize;
+ save = htonl(value);
+ return fwrite(&save, sizeof(save), 1, out);
}
+static gint32
+decode_fixed_int (FILE *out)
+{
+ guint32 save;
-GtkType
-camel_mbox_summary_get_type (void)
+ if (fread(&save, sizeof(save), 1, out) != -1) {
+ return ntohl(save);
+ } else {
+ return -1;
+ }
+}
+
+/* should be sorted, for binary search */
+/* This is a tokenisation mechanism for strings written to the
+ summary - to save space.
+ This list can have at most 31 words. */
+static char * tokens[] = {
+ "7bit",
+ "8bit",
+ "alternative",
+ "application",
+ "base64",
+ "boundary",
+ "charset",
+ "filename",
+ "html",
+ "image",
+ "iso-8859-1",
+ "iso-8859-8",
+ "message",
+ "mixed",
+ "multipart",
+ "name",
+ "octet-stream",
+ "parallel",
+ "plain",
+ "quoted-printable",
+ "rfc822",
+ "text",
+ "us-ascii", /* 23 words */
+};
+
+#define tokens_len (sizeof(tokens)/sizeof(tokens[0]))
+
+/* baiscally ...
+ 0 = null
+ 1-tokens_len == tokens[id-1]
+ >=32 string, length = n-32
+*/
+
+static int
+encode_string (FILE *out, char *str)
{
- static GtkType camel_mbox_summary_type = 0;
+ if (str == NULL) {
+ return encode_int(out, 0);
+ } else {
+ int len = strlen(str);
+ int i, token=-1;
+
+ if (len <= 16) {
+ char lower[32];
+
+ for (i=0;i<len;i++)
+ lower[i] = tolower(str[i]);
+ lower[i] = 0;
+ for (i=0;i<tokens_len;i++) {
+ if (!strcmp(tokens[i], lower)) {
+ token = i;
+ break;
+ }
+ }
+ }
+ if (token != -1) {
+ return encode_int(out, token+1);
+ } else {
+ if (encode_int(out, len+32) == -1)
+ return -1;
+ return fwrite(str, len, 1, out);
+ }
+ }
+ return 0;
+}
- if (!camel_mbox_summary_type) {
- GtkTypeInfo camel_mbox_summary_info =
- {
- "CamelMboxSummary",
- sizeof (CamelMboxSummary),
- sizeof (CamelMboxSummaryClass),
- (GtkClassInitFunc) camel_mbox_summary_class_init,
- (GtkObjectInitFunc) NULL,
- /* reserved_1 */ NULL,
- /* reserved_2 */ NULL,
- (GtkClassInitFunc) NULL,
- };
+static char *
+decode_string (FILE *in)
+{
+ char *ret;
+ int len;
+
+ len = decode_int(in);
- camel_mbox_summary_type = gtk_type_unique (camel_folder_summary_get_type (), &camel_mbox_summary_info);
+ if (len<32) {
+ if (len <= 0) {
+ ret = NULL;
+ } else if (len<= tokens_len) {
+ ret = g_strdup(tokens[len-1]);
+ } else {
+ g_warning("Invalid token encountered: %d", len);
+ ret = NULL;
+ }
+ } else if (len > 10240) {
+ g_warning("Got broken string header length: %d bytes", len);
+ ret = NULL;
+ } else {
+ len -= 32;
+ ret = g_malloc(len+1);
+ if (fread(ret, len, 1, in) == -1) {
+ g_free(ret);
+ return NULL;
+ }
+ ret[len]=0;
}
- return camel_mbox_summary_type;
+ return ret;
}
+
+
+/* allocation functions */
+
static void
-finalize (GtkObject *object)
+body_part_dump(CamelMboxMessageContentInfo *bs, int depth)
{
- CamelMboxSummary *summary = CAMEL_MBOX_SUMMARY (object);
- CamelMboxSummaryInformation *info;
- int i;
+ CamelMboxMessageContentInfo *c;
+ char *prefix;
- for (i = 0; i < summary->message_info->len; i++) {
- info = &(((CamelMboxSummaryInformation *)summary->message_info->data)[i]);
- g_free (info->headers.subject);
- g_free (info->headers.sender);
- g_free (info->headers.to);
- g_free (info->headers.sent_date);
- g_free (info->headers.received_date);
- g_free (info->headers.uid);
+ if (bs == NULL)
+ return;
+
+ prefix = alloca(depth*2+1);
+ memset(prefix, ' ', depth*2);
+ prefix[depth*2]=0;
+ printf("%scontent-range: %d %d %d\n", prefix, (int)bs->pos, (int)bs->bodypos, (int)bs->endpos);
+ printf("%scontent-type: %s/%s\n", prefix, bs->info.type?bs->info.type->type:"?", bs->info.type?bs->info.type->subtype:"?");
+ printf("%scontent-id: %s\n", prefix, bs->info.id);
+ printf("%scontent-description: %s\n", prefix, bs->info.description);
+ printf("%scontent-transfer-encoding: %s\n", prefix, bs->info.encoding);
+ c = (CamelMboxMessageContentInfo *)bs->info.childs;
+ while (c) {
+ printf("%s -- \n", prefix);
+ body_part_dump(c, depth+1);
+ c = (CamelMboxMessageContentInfo *)c->info.next;
}
- g_array_free (summary->message_info, TRUE);
+}
- GTK_OBJECT_CLASS (parent_class)->finalize (object);
-}
+static void
+message_struct_dump(CamelMboxMessageInfo *ms)
+{
+ char *tmp;
-static int
-count_messages (CamelFolderSummary *summary)
+ if (ms == NULL) {
+ printf("Empty message?\n");
+ return;
+ }
+
+ printf("Subject: %s\n", ms->info.subject);
+ printf("From: %s\n", ms->info.from);
+ printf("To: %s\n", ms->info.to);
+ tmp = header_format_date(ms->info.date_sent, 0);
+ printf("Date: %s\n", tmp);
+ g_free(tmp);
+ tmp = header_format_date(ms->info.date_received, 0);
+ printf("Date-Received: %s\n", tmp);
+ g_free(tmp);
+ printf("UID: %08x-%04x\n", atoi(ms->info.uid), ms->info.flags);
+ printf(" -- content ->\n");
+ body_part_dump((CamelMboxMessageContentInfo *)ms->info.content, 1);
+}
+
+static CamelMboxMessageContentInfo *
+body_part_new(CamelMimeParser *mp, CamelMboxMessageContentInfo *parent, int start, int body)
{
- return CAMEL_MBOX_SUMMARY (summary)->nb_message;
+ CamelMboxMessageContentInfo *bs;
+
+ bs = g_malloc0(sizeof(*bs));
+
+ bs->info.parent = (CamelMessageContentInfo *)parent;
+
+ bs->info.type = camel_mime_parser_content_type(mp);
+ header_content_type_ref(bs->info.type);
+
+ bs->info.id = header_msgid_decode(camel_mime_parser_header(mp, "content-id", NULL));
+ bs->info.description = header_decode_string(camel_mime_parser_header(mp, "content-description", NULL));
+ bs->info.encoding = header_content_encoding_decode(camel_mime_parser_header(mp, "content-transfer-encoding", NULL));
+
+ /* not sure what to set here? */
+ bs->pos = start;
+ bs->bodypos = body;
+ bs->endpos = -1;
+
+ if (parent)
+ my_list_append((struct _node **)&parent->info.childs, (struct _node *)bs);
+
+ return bs;
+}
+
+static CamelMboxMessageInfo *
+message_struct_new(CamelMimeParser *mp, CamelMboxMessageContentInfo *parent, int start, int body, off_t xev_offset)
+{
+ CamelMboxMessageInfo *ms;
+
+ ms = g_malloc0(sizeof(*ms));
+
+ /* FIXME: what about cc, sender vs from? */
+ ms->info.subject = g_strdup(camel_mime_parser_header(mp, "subject", NULL));
+ ms->info.from = g_strdup(camel_mime_parser_header(mp, "from", NULL));
+ ms->info.to = g_strdup(camel_mime_parser_header(mp, "to", NULL));
+
+ ms->info.date_sent = header_decode_date(camel_mime_parser_header(mp, "date", NULL), NULL);
+ ms->info.date_received = 0;
+
+ ms->info.content = (CamelMessageContentInfo *)body_part_new(mp, parent, start, body);
+ ms->xev_offset = xev_offset;
+ return ms;
+}
+
+static void
+body_part_free(CamelMboxMessageContentInfo *bs)
+{
+ CamelMboxMessageContentInfo *c, *cn;
+
+ c = (CamelMboxMessageContentInfo *)bs->info.childs;
+ while (c) {
+ cn = (CamelMboxMessageContentInfo *)c->info.next;
+ body_part_free(c);
+ c = cn;
+ }
+ g_free(bs->info.id);
+ g_free(bs->info.description);
+ g_free(bs->info.encoding);
+ header_content_type_unref(bs->info.type);
+ g_free(bs);
+}
+
+static void
+message_struct_free(CamelMboxMessageInfo *ms)
+{
+ g_free(ms->info.subject);
+ g_free(ms->info.to);
+ g_free(ms->info.from);
+ body_part_free((CamelMboxMessageContentInfo *)ms->info.content);
+ g_free(ms);
+}
+
+
+/* IO functions */
+static CamelMboxMessageContentInfo *
+body_part_load(FILE *in)
+{
+ CamelMboxMessageContentInfo *bs = NULL, *c;
+ struct _header_content_type *ct;
+ char *type;
+ char *subtype;
+ int i, count;
+
+ d(printf("got content-block\n"));
+ bs = g_malloc0(sizeof(*bs));
+ bs->pos = decode_int(in);
+ bs->bodypos = bs->pos + decode_int(in);
+ bs->endpos = bs->pos + decode_int(in);
+
+ /* do content type */
+ d(printf("got content-type\n"));
+ type = decode_string(in);
+ subtype = decode_string(in);
+
+ ct = header_content_type_new(type, subtype);
+ bs->info.type = ct;
+ count = decode_int(in);
+ d(printf("getting %d params\n", count));
+ for (i=0;i<count;i++) {
+ char *name = decode_string(in);
+ char *value = decode_string(in);
+
+ d(printf(" %s = \"%s\"\n", name, value));
+
+ header_content_type_set_param(ct, name, value);
+ /* FIXME: do this so we dont have to double alloc/free */
+ g_free(name);
+ g_free(value);
+ }
+
+ d(printf("got content-id\n"));
+ bs->info.id = decode_string(in);
+ d(printf("got content-description\n"));
+ bs->info.description = decode_string(in);
+ d(printf("got content-encoding\n"));
+ bs->info.encoding = decode_string(in);
+
+ count = decode_int(in);
+ d(printf("got children, %d\n", count));
+ for (i=0;i<count;i++) {
+ c = body_part_load(in);
+ if (c) {
+ my_list_append((struct _node **)&bs->info.childs, (struct _node *)c);
+ c->info.parent = (CamelMessageContentInfo *)bs;
+ } else {
+ printf("Cannot load child\n");
+ }
+ }
+
+ return bs;
}
static int
-count_subfolders (CamelFolderSummary *summary)
+body_part_save(FILE *out, CamelMboxMessageContentInfo *bs)
{
- /* XXX */
- g_warning ("CamelMboxSummary::count_subfolders not implemented");
+ CamelMboxMessageContentInfo *c, *cn;
+ struct _header_content_type *ct;
+ struct _header_param *hp;
+
+ encode_int(out, bs->pos);
+ encode_int(out, bs->bodypos - bs->pos);
+ encode_int(out, bs->endpos - bs->pos);
+
+ ct = bs->info.type;
+ if (ct) {
+ encode_string(out, ct->type);
+ encode_string(out, ct->subtype);
+ encode_int(out, my_list_size((struct _node **)&ct->params));
+ hp = ct->params;
+ while (hp) {
+ encode_string(out, hp->name);
+ encode_string(out, hp->value);
+ hp = hp->next;
+ }
+ } else {
+ encode_string(out, NULL);
+ encode_string(out, NULL);
+ encode_int(out, 0);
+ }
+ encode_string(out, bs->info.id);
+ encode_string(out, bs->info.description);
+ encode_string(out, bs->info.encoding);
+
+ encode_int(out, my_list_size((struct _node **)&bs->info.childs));
+
+ c = (CamelMboxMessageContentInfo *)bs->info.childs;
+ while (c) {
+ cn = (CamelMboxMessageContentInfo *)c->info.next;
+ body_part_save(out, c);
+ c = cn;
+ }
+
return 0;
}
-static GPtrArray *
-get_subfolder_info (CamelFolderSummary *summary, int first, int count)
+static CamelMboxMessageInfo *
+message_struct_load(FILE *in)
{
- /* XXX */
- g_warning ("CamelMboxSummary::count_subfolders not implemented");
+ CamelMboxMessageInfo *ms;
+
+ ms = g_malloc0(sizeof(*ms));
+
+ ms->info.uid = g_strdup_printf("%u", decode_int(in));
+ ms->info.flags = decode_int(in);
+ ms->info.date_sent = decode_int(in);
+ ms->info.date_received = decode_int(in);
+ ms->xev_offset = decode_int(in);
+ ms->info.subject = decode_string(in);
+ ms->info.from = decode_string(in);
+ ms->info.to = decode_string(in);
+ ms->info.content = (CamelMessageContentInfo *)body_part_load(in);
+
+ return ms;
+}
+
+static int
+message_struct_save(FILE *out, CamelMboxMessageInfo *ms)
+{
+ encode_int(out, strtoul(ms->info.uid, NULL, 10));
+ encode_int(out, ms->info.flags);
+ encode_int(out, ms->info.date_sent);
+ encode_int(out, ms->info.date_received);
+ encode_int(out, ms->xev_offset);
+ encode_string(out, ms->info.subject);
+ encode_string(out, ms->info.from);
+ encode_string(out, ms->info.to);
+ body_part_save(out, (CamelMboxMessageContentInfo *)ms->info.content);
+
return 0;
}
-static GPtrArray *
-get_message_info (CamelFolderSummary *summary, int first, int count)
+static unsigned int
+header_evolution_decode(const char *in, unsigned int *uid, unsigned int *flags)
{
- CamelMboxSummary *mbox_summary = CAMEL_MBOX_SUMMARY (summary);
- CamelMboxSummaryInformation *info;
- GPtrArray *arr;
+ char *header;
+ if (in
+ && (header = header_decode_token(&in))) {
+ if (strlen(header) == strlen("00000000-0000")
+ && sscanf(header, "%08x-%04x", uid, flags) == 2) {
+ g_free(header);
+ return *uid;
+ }
+ g_free(header);
+ }
- /* XXX bounds check */
+ return ~0;
+}
+
+static int
+safe_write(int fd, char *buffer, size_t towrite)
+{
+ size_t donelen;
+ size_t len;
- arr = g_ptr_array_new ();
- for (; count; count--) {
- info = &((CamelMboxSummaryInformation *)mbox_summary->message_info->data)[first++];
- g_ptr_array_add (arr, info);
+ donelen = 0;
+ while (donelen < towrite) {
+ len = write(fd, buffer + donelen, towrite - donelen);
+ if (len == -1) {
+ if (errno == EINTR || errno == EAGAIN)
+ continue;
+ return -1;
+ }
+ donelen += len;
}
+ return donelen;
+}
- return arr;
-}
-
-/**
- * camel_mbox_summary_save:
- * @summary:
- * @filename:
- * @ex:
- *
- * save the summary into a file
- **/
-void
-camel_mbox_summary_save (CamelMboxSummary *summary, const gchar *filename,
- CamelException *ex)
-{
- CamelMboxSummaryInformation *msg_info;
- guint cur_msg;
- guint field_length;
- gint fd;
- gint write_result; /* XXX use this */
- guint32 data;
-
- fd = open (filename, O_WRONLY | O_CREAT | O_TRUNC,
- S_IRUSR | S_IWUSR);
- if (fd == -1) {
- camel_exception_setv (ex, CAMEL_EXCEPTION_FOLDER_INSUFFICIENT_PERMISSION,
- "could not create the mbox summary "
- "file\n\t%s\nFull error is : %s\n",
- filename,
- strerror (errno));
- return;
+static int
+header_write(int fd, struct _header_raw *header, unsigned int uid, unsigned int flags)
+{
+ struct iovec iv[3];
+ int outlen = 0;
+
+ iv[1].iov_base = ":";
+ iv[1].iov_len = 1;
+
+ while (header) {
+ if (strcasecmp(header->name, "x-evolution")) {
+ int len;
+
+ iv[0].iov_base = header->name;
+ iv[0].iov_len = strlen(header->name);
+ iv[2].iov_base = header->value;
+ iv[2].iov_len = strlen(header->value);
+
+ do {
+ len = writev(fd, iv, 3);
+ } while (len == -1 && errno == EINTR);
+
+ if (len == -1)
+ return -1;
+ outlen += len;
+ }
+ header = header->next;
}
- /* We write the file out in network byte order, not because
- * that makes sense, but because it's easy.
- */
-
- data = htonl (CAMEL_MBOX_SUMMARY_VERSION);
- write (fd, &data, sizeof (data));
-
- data = htonl (summary->nb_message);
- write (fd, &data, sizeof (data));
- data = htonl (summary->next_uid);
- write (fd, &data, sizeof (data));
- data = htonl (summary->mbox_file_size);
- write (fd, &data, sizeof (data));
- data = htonl (summary->mbox_modtime);
- write (fd, &data, sizeof (data));
-
- for (cur_msg = 0; cur_msg < summary->nb_message; cur_msg++) {
- msg_info = (CamelMboxSummaryInformation *)
- (summary->message_info->data) + cur_msg;
-
- /* Write meta-info. */
- data = htonl (msg_info->position);
- write (fd, &data, sizeof (data));
- data = htonl (msg_info->size);
- write (fd, &data, sizeof (data));
- data = htonl (msg_info->x_evolution_offset);
- write (fd, &data, sizeof (data));
- data = htonl (msg_info->uid);
- write (fd, &data, sizeof (data));
- write (fd, &msg_info->status, 1);
-
- /* Write subject. */
- if (msg_info->headers.subject)
- field_length = strlen (msg_info->headers.subject);
- else
- field_length = 0;
- data = htonl (field_length);
- write (fd, &data, sizeof (data));
- if (msg_info->headers.subject)
- write (fd, msg_info->headers.subject, field_length);
-
- /* Write sender. */
- if (msg_info->headers.sender)
- field_length = strlen (msg_info->headers.sender);
- else
- field_length = 0;
- data = htonl (field_length);
- write (fd, &data, sizeof (data));
- if (msg_info->headers.sender)
- write (fd, msg_info->headers.sender, field_length);
-
- /* Write to. */
- if (msg_info->headers.to)
- field_length = strlen (msg_info->headers.to);
- else
- field_length = 0;
- data = htonl (field_length);
- write (fd, &data, sizeof (data));
- if (msg_info->headers.to)
- write (fd, msg_info->headers.to, field_length);
-
- /* Write sent date. */
- if (msg_info->headers.sent_date)
- field_length = strlen (msg_info->headers.sent_date);
- else
- field_length = 0;
- data = htonl (field_length);
- write (fd, &data, sizeof (data));
- if (msg_info->headers.sent_date)
- write (fd, msg_info->headers.sent_date, field_length);
-
- /* Write received date. */
- if (msg_info->headers.received_date)
- field_length = strlen (msg_info->headers.received_date);
+ return outlen;
+}
+
+/* returns -1 on error, else number of bytes written */
+int
+camel_mbox_summary_copy_block(int fromfd, int tofd, off_t readpos, size_t bytes)
+{
+ char buffer[4096];
+ int written = 0;
+ off_t pos, newpos;
+
+ pos = lseek(fromfd, 0, SEEK_CUR);
+ if (pos == -1)
+ return -1;
+
+ newpos = lseek(fromfd, readpos, SEEK_SET);
+ if (newpos == -1 || newpos != readpos)
+ goto error;
+
+ d(printf("oldpos = %d; copying %d from %d\n", (int)pos, (int)bytes, (int)readpos));
+
+ while (bytes>0) {
+ int toread, towrite, donelen;
+
+ toread = bytes;
+ if (bytes>4096)
+ toread = 4096;
else
- field_length = 0;
- data = htonl (field_length);
- write (fd, &data, sizeof (data));
- if (msg_info->headers.received_date)
- write (fd, msg_info->headers.received_date, field_length);
+ toread = bytes;
+ reread:
+ towrite = read(fromfd, buffer, toread);
+ if (towrite == -1) {
+ if (errno == EINTR || errno == EAGAIN)
+ goto reread;
+ goto error;
+ }
+
+ /* check for 'end of file' */
+ if (towrite == 0)
+ break;
+
+ if ( (donelen = safe_write(tofd, buffer, towrite)) == -1)
+ goto error;
+
+ written += donelen;
+ bytes -= donelen;
+ }
+
+ d(printf("written %d bytes\n", written));
+
+ newpos = lseek(fromfd, pos, SEEK_SET);
+ if (newpos == -1 || newpos != pos);
+ return -1;
+
+ return written;
+
+error:
+ lseek(fromfd, pos, SEEK_SET);
+ return -1;
+}
+
+#define SAVEIT
+
+static int index_folder(CamelMboxSummary *s, int startoffset)
+{
+ CamelMimeParser *mp;
+ int fd;
+ int fdout;
+ int state;
+
+ int toplevel = FALSE;
+ const char *xev;
+ char *data;
+ int datalen;
+
+ int enc_id=-1;
+ int chr_id=-1;
+ int idx_id=-1;
+ struct _header_content_type *ct;
+ int doindex=FALSE;
+ CamelMimeFilterCharset *mfc = NULL;
+ CamelMimeFilterIndex *mfi = NULL;
+ CamelMimeFilterBasic *mf64 = NULL, *mfqp = NULL;
+
+ CamelMboxMessageContentInfo *body = NULL, *parent = NULL;
+ CamelMboxMessageInfo *message = NULL;
+
+ int from_end = 0; /* start of message */
+ int from = 0; /* start of headers */
+ int last_write = 0; /* last written position */
+ int eof;
+ int write_offset = 0; /* how much does the dest differ from the source pos */
+ int old_offset = 0;
+
+ guint32 newuid;
+ off_t xevoffset = -1;
+
+ char *tmpname;
+
+ printf("indexing %s (%s) from %d\n", s->folder_path, s->summary_path, startoffset);
+
+ fd = open(s->folder_path, O_RDONLY);
+ if (fd==-1) {
+ perror("Can't open folder");
+ return -1;
}
- close (fd);
-}
-
-
-
-/**
- * camel_mbox_summary_load:
- * @filename:
- * @ex:
- *
- * load the summary from a file
- *
- * Return value:
- **/
-CamelMboxSummary *
-camel_mbox_summary_load (const gchar *filename, CamelException *ex)
-{
- CamelMboxSummaryInformation *msg_info;
- guint cur_msg;
- guint field_length;
- gint fd;
- CamelMboxSummary *summary;
- gint read_result;
- guint32 data;
-
- fd = open (filename, O_RDONLY);
- if (fd == -1) {
- camel_exception_setv (ex, CAMEL_EXCEPTION_FOLDER_INSUFFICIENT_PERMISSION,
- "could not open the mbox summary file\n"
- "\t%s\nFull error is : %s\n",
- filename, strerror (errno));
- return NULL;
+ tmpname = g_strdup_printf("%s.tmp", s->folder_path);
+
+ fdout = open(tmpname, O_WRONLY|O_CREAT|O_TRUNC, 0600);
+ if (fdout==-1) {
+ perror("Can't open output");
+ g_free(tmpname);
+ return -1;
}
- /* Verify version number. */
- read (fd, &data, sizeof(data));
- data = ntohl (data);
-
- if (data != CAMEL_MBOX_SUMMARY_VERSION) {
- camel_exception_setv (ex, CAMEL_EXCEPTION_FOLDER_SUMMARY_INVALID,
- "This folder summary was written by "
- "%s version of this software.",
- data < CAMEL_MBOX_SUMMARY_VERSION ?
- "an older" : "a newer");
- return NULL;
+ mp = camel_mime_parser_new();
+ camel_mime_parser_init_with_fd(mp, fd);
+ camel_mime_parser_scan_from(mp, TRUE);
+
+ /* FIXME: cleaner fail code */
+ if (startoffset > 0) {
+ if (camel_mime_parser_seek(mp, startoffset, SEEK_SET) != startoffset) {
+ g_free(tmpname);
+ gtk_object_unref((GtkObject *)mp);
+ return -1;
+ }
}
- summary = CAMEL_MBOX_SUMMARY (gtk_object_new (camel_mbox_summary_get_type (), NULL));
-
- read (fd, &data, sizeof(data));
- summary->nb_message = ntohl (data);
- read (fd, &data, sizeof(data));
- summary->next_uid = ntohl (data);
- read (fd, &data, sizeof(data));
- summary->mbox_file_size = ntohl (data);
- read (fd, &data, sizeof(data));
- summary->mbox_modtime = ntohl (data);
-
- summary->message_info =
- g_array_new (FALSE, FALSE,
- sizeof (CamelMboxSummaryInformation));
- g_array_set_size (summary->message_info, summary->nb_message);
-
- for (cur_msg = 0; cur_msg < summary->nb_message; cur_msg++) {
- msg_info = (CamelMboxSummaryInformation *)
- (summary->message_info->data) + cur_msg;
-
- /* Read the meta-info. */
- read (fd, &data, sizeof(data));
- msg_info->position = ntohl (data);
- read (fd, &data, sizeof(data));
- msg_info->size = ntohl (data);
- read (fd, &data, sizeof(data));
- msg_info->x_evolution_offset = ntohl (data);
- read (fd, &data, sizeof(data));
- msg_info->uid = ntohl (data);
- msg_info->headers.uid = g_strdup_printf ("%d", msg_info->uid);
- read (fd, &msg_info->status, 1);
-
- /* Read the subject. */
- read (fd, &field_length, sizeof (field_length));
- field_length = ntohl (field_length);
- if (field_length > 0) {
- msg_info->headers.subject =
- g_new0 (gchar, field_length + 1);
- read (fd, msg_info->headers.subject, field_length);
- } else
- msg_info->headers.subject = NULL;
-
- /* Read the sender. */
- read (fd, &field_length, sizeof (field_length));
- field_length = ntohl (field_length);
- if (field_length > 0) {
- msg_info->headers.sender =
- g_new0 (gchar, field_length + 1);
- read (fd, msg_info->headers.sender, field_length);
- } else
- msg_info->headers.sender = NULL;
-
- /* Read the "to" field. */
- read (fd, &field_length, sizeof (field_length));
- field_length = ntohl (field_length);
- if (field_length > 0) {
- msg_info->headers.to =
- g_new0 (gchar, field_length + 1);
- read (fd, msg_info->headers.to, field_length);
- } else
- msg_info->headers.to = NULL;
-
- /* Read the sent date field. */
- read (fd, &field_length, sizeof (field_length));
- field_length = ntohl (field_length);
- if (field_length > 0) {
- msg_info->headers.sent_date =
- g_new0 (gchar, field_length + 1);
- read (fd, msg_info->headers.sent_date, field_length);
- } else
- msg_info->headers.sent_date = NULL;
-
- /* Read the received date field. */
- read (fd, &field_length, sizeof (field_length));
- field_length = ntohl (field_length);
- if (field_length > 0) {
- msg_info->headers.received_date =
- g_new0 (gchar, field_length + 1);
- read (fd, msg_info->headers.received_date,
- field_length);
- } else
- msg_info->headers.received_date = NULL;
- }
-
- close (fd);
- return summary;
-}
-
-
-/**
- * camel_mbox_summary_append_entries:
- * @summary:
- * @entries:
- *
- * append an entry to a summary
- **/
-void
-camel_mbox_summary_append_entries (CamelMboxSummary *summary, GArray *entries)
-{
-
- summary->message_info = g_array_append_vals (summary->message_info,
- entries->data,
- entries->len);
+ mfi = camel_mime_filter_index_new_ibex(s->index);
+
+ while ( (state = camel_mime_parser_step(mp, &data, &datalen)) != HSCAN_EOF ) {
+ switch(state) {
+ case HSCAN_FROM: /* starting a new message content */
+ /* save the current position */
+ d(printf("from = %d\n", (int)camel_mime_parser_tell(mp)));
+ toplevel = FALSE;
+ from = camel_mime_parser_tell(mp);
+ break;
+
+ case HSCAN_FROM_END:
+ d(printf("from-end = %d\n", (int)camel_mime_parser_tell(mp)));
+ d(printf("message from %d to %d\n", from_end, (int)camel_mime_parser_tell(mp)));
+ from_end = camel_mime_parser_tell(mp);
+ break;
+
+ case HSCAN_MESSAGE:
+ case HSCAN_MULTIPART:
+ case HSCAN_HEADER: /* starting a new header */
+ newuid=~0;
+ if (!toplevel) {
+ char name[32];
+ unsigned int olduid, oldflags;
+ int headerlen;
+ int docopy = FALSE;
+
+ /* check for X-Evolution header ... if its there, nothing to do (skip content) */
+ xev = camel_mime_parser_header(mp, "x-evolution", &xevoffset);
+ if (xev) {
+ d(printf("An x-evolution header exists at: %d = %s\n", xevoffset + write_offset, xev));
+ xevoffset = xevoffset + write_offset;
+ if (header_evolution_decode(xev, &olduid, &oldflags) != ~0) {
+ d(printf(" uid = %d = %x\n", olduid, olduid));
+ newuid = olduid;
+#if 0
+ while (camel_mime_parser_step(mp, &data, &datalen) != HSCAN_FROM_END)
+ ;
+ break;
+#endif
+ } else {
+ printf("Invalid xev header? I need to write out a new one ...\n");
+ }
+ }
+
+ toplevel = TRUE;
+
+ /* assign a new uid for this message */
+ if (newuid == ~0) {
+ newuid = s->nextuid++;
+ docopy = TRUE;
+ } else {
+ /* make sure we account for this uid when assigning uid's */
+ /* this really needs a pre-scan pass ... *sigh* */
+ camel_mbox_summary_set_uid(s, newuid);
+ }
+
+ /* setup index name for this uid */
+ sprintf(name, "%x", newuid);
+ camel_mime_filter_index_set_name(mfi, name);
+ /* remove all references to this name from the index */
+ if (s->index)
+ ibex_unindex(s->index, name);
+
+ d(printf("Message content starts at %d\n", camel_mime_parser_tell(mp)));
+
+ if (docopy) {
+ /* now, copy over bits of mbox from last write, and insert the X-Evolution header (at the top of headers) */
+ /* if we already have a valid x-evolution header, use that, dont need to copy */
+ camel_mbox_summary_copy_block(fd, fdout, last_write, from-last_write);
+ last_write = from;
+
+ headerlen = header_write(fdout, camel_mime_parser_headers_raw(mp), newuid, 0);
+ sprintf(name, "X-Evolution: %08x-%04x\n\n", newuid, 0);
+ safe_write(fdout, name, strlen(name));
+ d(printf("new X-Evolution at %d\n", headerlen + from + write_offset));
+ xevoffset = headerlen + from + write_offset;
+ old_offset = write_offset;
+
+ write_offset += (headerlen - (camel_mime_parser_tell(mp)-from)) + strlen(name);
+ last_write = camel_mime_parser_tell(mp);
+ }
+ } else {
+ old_offset = write_offset;
+ }
+
+ /* we only care about the rest for actual content parts */
+ /* TODO: Cleanup, this is a huge mess */
+ if (state != HSCAN_HEADER) {
+ if (message == NULL) {
+ message = message_struct_new(mp, parent, camel_mime_parser_tell_start_headers(mp)+old_offset, camel_mime_parser_tell(mp)+write_offset, xevoffset);
+ parent = (CamelMboxMessageContentInfo *)message->info.content;
+ if (newuid != ~0) {
+ message->info.uid = g_strdup_printf("%u", newuid);
+ } else {
+ g_warning("This shouldn't happen?");
+ }
+ } else {
+ parent = body_part_new(mp, parent, camel_mime_parser_tell_start_headers(mp)+old_offset, camel_mime_parser_tell(mp)+write_offset);
+ }
+ break;
+ }
+
+ if (message == NULL) {
+ message = message_struct_new(mp, parent, camel_mime_parser_tell_start_headers(mp)+old_offset, camel_mime_parser_tell(mp)+write_offset, xevoffset);
+ body = (CamelMboxMessageContentInfo *)message->info.content;
+ if (newuid != ~0) {
+ message->info.uid = g_strdup_printf("%u", newuid);
+ } else {
+ g_warning("This shouldn't happen?");
+ }
+ } else {
+ body = body_part_new(mp, parent, camel_mime_parser_tell_start_headers(mp)+old_offset, camel_mime_parser_tell(mp)+write_offset);
+ }
+
+ /* check headers for types that we can index */
+ ct = camel_mime_parser_content_type(mp);
+ if (header_content_type_is(ct, "text", "*")) {
+ char *encoding;
+ const char *charset;
+
+ /* TODO: The filters should all be cached, so they aren't recreated between
+ messages/message parts */
+ encoding = header_content_encoding_decode(camel_mime_parser_header(mp, "content-transfer-encoding", NULL));
+ if (encoding) {
+ if (!strcasecmp(encoding, "base64")) {
+ d(printf("Adding decoding filter for base64\n"));
+ if (mf64 == NULL)
+ mf64 = camel_mime_filter_basic_new_type(CAMEL_MIME_FILTER_BASIC_BASE64_DEC);
+ enc_id = camel_mime_parser_filter_add(mp, (CamelMimeFilter *)mf64);
+ } else if (!strcasecmp(encoding, "quoted-printable")) {
+ d(printf("Adding decoding filter for quoted-printable\n"));
+ if (mfqp == NULL)
+ mfqp = camel_mime_filter_basic_new_type(CAMEL_MIME_FILTER_BASIC_QP_DEC);
+ enc_id = camel_mime_parser_filter_add(mp, (CamelMimeFilter *)mfqp);
+ }
+ g_free(encoding);
+ }
+
+ charset = header_content_type_param(ct, "charset");
+ if (charset!=NULL
+ && !(strcasecmp(charset, "us-ascii")==0
+ || strcasecmp(charset, "utf-8")==0)) {
+ d(printf("Adding conversion filter from %s to utf-8\n", charset));
+ if (mfc == NULL)
+ mfc = camel_mime_filter_charset_new_convert(charset, "utf-8");
+ if (mfc) {
+ chr_id = camel_mime_parser_filter_add(mp, (CamelMimeFilter *)mfc);
+ } else {
+ g_warning("Cannot convert '%s' to 'utf-8', message display may be corrupt", charset);
+ }
+ }
+
+ doindex = TRUE;
+
+ /* and this filter actually does the indexing */
+ idx_id = camel_mime_parser_filter_add(mp, (CamelMimeFilter *)mfi);
+ } else {
+ doindex = FALSE;
+ }
+ break;
+
+ /* fixme, this needs thought *sigh* */
+ case HSCAN_MESSAGE_END:
+ case HSCAN_MULTIPART_END:
+ if (parent) {
+ parent->endpos = camel_mime_parser_tell(mp)+write_offset;
+ if (parent->info.parent == NULL) {
+ camel_mbox_summary_add(s, message);
+ message = NULL;
+ parent = NULL;
+ } else {
+ parent = (CamelMboxMessageContentInfo *)parent->info.parent;
+ }
+ }
+ break;
+
+ case HSCAN_BODY:
+ if (doindex) {
+ d(printf("Got content to index:\n%.*s", datalen, data));
+ }
+ break;
+
+ case HSCAN_BODY_END:
+ if (body) {
+ body->endpos = camel_mime_parser_tell(mp)+write_offset;
+ if (body->info.parent == NULL) {
+ camel_mbox_summary_add(s, message);
+ message = NULL;
+ }
+ }
+
+ d(printf("end of content, removing decoders\n"));
+ if (enc_id != -1) {
+ camel_mime_parser_filter_remove(mp, enc_id);
+ enc_id = -1;
+ }
+ if (chr_id != -1) {
+ camel_mime_parser_filter_remove(mp, chr_id);
+ chr_id = -1;
+ }
+ if (idx_id != -1) {
+ camel_mime_parser_filter_remove(mp, idx_id);
+ idx_id = -1;
+ }
+ break;
+ }
+ }
+
+ /* did we actually write anything out? Then rename and be done with it. */
+ if (last_write>0) {
+ eof = camel_mime_parser_tell(mp);
+ camel_mbox_summary_copy_block(fd, fdout, last_write, eof-last_write);
+
+ if (close(fdout) == -1) {
+ perror("Could not close output file");
+ unlink(tmpname);
+ } else {
+ printf("renaming %s to %s\n", tmpname, s->folder_path);
+ if (rename(tmpname, s->folder_path) == -1) {
+ perror("Error renaming file");
+ unlink(tmpname);
+ }
+ }
+ } else {
+ /* no, then dont bother touching the inbox */
+ printf("No written changes to mbox, removing tmp file\n");
+ close(fdout);
+ unlink(tmpname);
+ }
+
+ close(fd);
+
+ if (mf64) gtk_object_unref((GtkObject *)mf64);
+ if (mfqp) gtk_object_unref((GtkObject *)mfqp);
+ if (mfc) gtk_object_unref((GtkObject *)mfc);
+ if (mfi) gtk_object_unref((GtkObject *)mfi);
+
+ /* force an index sync? */
+ if (s->index) {
+ ibex_write(s->index);
+ }
+
+ gtk_object_unref((GtkObject *)mp);
+
+ /* and finally ... update the summary sync info */
+ {
+ struct stat st;
+
+ if (stat(s->folder_path, &st) == 0) {
+ s->time = st.st_mtime;
+ s->size = st.st_size;
+ }
+ }
+
+ g_free(tmpname);
+
+ return 0;
+}
+
+CamelMboxSummary *camel_mbox_summary_new(const char *summary, const char *folder, ibex *index)
+{
+ CamelMboxSummary *s;
+
+ s = g_malloc0(sizeof(*s));
+
+ s->dirty = TRUE;
+ s->folder_path = g_strdup(folder);
+ s->summary_path = g_strdup(summary);
+ /* FIXME: refcount index? */
+ s->index = index;
+
+ s->messages = g_ptr_array_new();
+ s->message_uid = g_hash_table_new(g_str_hash, g_str_equal);
+
+ /* always force an update */
+ s->time = 0;
+ s->size = 0;
+
+ s->nextuid = 1;
+
+ /* TODO: force an initial load right now? */
+
+ return s;
+}
+
+void camel_mbox_summary_unref(CamelMboxSummary *s)
+{
+ g_warning("Unimplemented function, mbox_summary_unref");
+}
+
+/* check that the summary is uptodate, TRUE means it is uptodate */
+int camel_mbox_summary_check(CamelMboxSummary *s)
+{
+ struct stat st;
+
+ /* no folder at all? */
+ if (stat(s->folder_path, &st) != 0)
+ return FALSE;
+
+ return (st.st_size == s->size) && (st.st_mtime == s->time);
+}
+
+static void camel_mbox_summary_add(CamelMboxSummary *s, CamelMboxMessageInfo *info)
+{
+ if (info->info.uid == NULL) {
+ info->info.uid = g_strdup_printf("%u", s->nextuid++);
+ }
+ if (g_hash_table_lookup(s->message_uid, info->info.uid)) {
+ g_error("Trying to insert message with clashing uid's");
+ }
+ d(printf("adding %s\n", info->info.uid));
+ g_ptr_array_add(s->messages, info);
+ g_hash_table_insert(s->message_uid, info->info.uid, info);
+ s->dirty = TRUE;
+}
+
+static int summary_header_read(FILE *fp, guint32 *version, time_t *time, size_t *size, guint32 *nextuid)
+{
+ fseek(fp, 0, SEEK_SET);
+ *version = decode_fixed_int(fp);
+ *time = decode_fixed_int(fp);
+ *size = decode_fixed_int(fp);
+ *nextuid = decode_fixed_int(fp);
+ return ferror(fp);
+}
+
+static void
+summary_clear(CamelMboxSummary *s)
+{
+ int i;
+
+ for (i=0;i<s->messages->len;i++) {
+ message_struct_free(g_ptr_array_index(s->messages, i));
+ }
+ g_ptr_array_free(s->messages, TRUE);
+ g_hash_table_destroy(s->message_uid);
+
+ s->messages = g_ptr_array_new();
+ s->message_uid = g_hash_table_new(g_str_hash, g_str_equal);
+}
+
+int camel_mbox_summary_load(CamelMboxSummary *s)
+{
+ struct stat st;
+ FILE *fp;
+ int i, total;
+ CamelMboxMessageInfo *info;
+
+ summary_clear(s);
+
+ if ((fp = fopen(s->summary_path, "r")) == NULL) {
+ g_warning("Loading non-existant summary, generating summary for folder: %s: %s", s->summary_path, strerror(errno));
+ index_folder(s, 0);
+ camel_mbox_summary_save(s);
+ } else {
+ guint32 version, nextuid;
+ time_t time;
+ size_t size;
+
+ if (stat(s->folder_path, &st) != 0) {
+ g_warning("Uh, no folder anyway, aborting");
+ fclose(fp);
+ return -1;
+ }
+
+ if (summary_header_read(fp, &version, &time, &size, &nextuid) != 0
+ || version != CAMEL_MBOX_SUMMARY_VERSION) {
+ g_warning("Summary missing or version mismatch, reloading summary");
+ fclose(fp);
+ index_folder(s, 0);
+ camel_mbox_summary_save(s);
+ return 0;
+ }
+
+ s->nextuid = MAX(s->nextuid, nextuid);
+ s->time = time;
+ s->size = size;
+ total = decode_fixed_int(fp);
+
+ if (time != st.st_mtime || size != st.st_size) {
+ /* if its grown, then just index the new stuff, and load the rest from the summary */
+ if (size < st.st_size) {
+ g_warning("Indexing/summarizing from start position: %d", size);
+
+ d(printf("loading %d items from summary file\n", total));
+ for (i=0;i<total;i++) {
+ info = message_struct_load(fp);
+ if (info) {
+ camel_mbox_summary_add(s, info);
+ } else {
+ break;
+ }
+ }
+ fclose(fp);
+ s->dirty = FALSE;
+ index_folder(s, size); /* if it adds any, it'll dirtify it */
+ camel_mbox_summary_save(s);
+ } else {
+ g_warning("Folder changed/smaller, reindexing everything");
+ index_folder(s, 0);
+ camel_mbox_summary_save(s);
+ fclose(fp);
+ }
+ return 0;
+ }
+
+ printf("loading %d items from summary file\n", total);
+ for (i=0;i<total;i++) {
+ info = message_struct_load(fp);
+ if (info) {
+ camel_mbox_summary_add(s, info);
+ } else {
+ break;
+ }
+ }
+ fclose(fp);
+ s->dirty = FALSE;
+ }
+ return 0;
+}
+
+static int summary_header_write(FILE *fp, CamelMboxSummary *s)
+{
+ fseek(fp, 0, SEEK_SET);
+ encode_fixed_int(fp, CAMEL_MBOX_SUMMARY_VERSION);
+ encode_fixed_int(fp, s->time);
+ /* if we're dirty, then dont *really* save it ... */
+ if (s->dirty)
+ encode_fixed_int(fp, 0);
+ else
+ encode_fixed_int(fp, s->size);
+ encode_fixed_int(fp, s->nextuid);
+ fflush(fp);
+ return ferror(fp);
+}
+
+static int summary_header_save(CamelMboxSummary *s)
+{
+ int fd;
+ FILE *fp;
+
+ fd = open(s->summary_path, O_WRONLY|O_CREAT, 0600);
+ if (fd == -1)
+ return -1;
+ fp = fdopen(fd, "w");
+ if (fp == NULL)
+ return -1;
+
+ summary_header_write(fp, s);
+ return fclose(fp);
+}
+
+int camel_mbox_summary_save(CamelMboxSummary *s)
+{
+ int i, fd;
+ FILE *fp;
+
+ printf("saving summary? %s\n", s->summary_path);
+
+ /* FIXME: error checking */
+ if (s->dirty) {
+ printf("yes\n");
+ fd = open(s->summary_path, O_WRONLY|O_CREAT|O_TRUNC, 0600);
+ if (fd == -1)
+ return -1;
+ fp = fdopen(fd, "w");
+ if (fp == NULL)
+ return -1;
+
+ s->dirty = FALSE;
+
+ summary_header_write(fp, s);
+ encode_fixed_int(fp, s->messages->len);
+
+ printf("message count = %d\n", s->messages->len);
+
+ for (i=0;i<s->messages->len;i++) {
+ message_struct_save(fp, g_ptr_array_index(s->messages, i));
+ }
+ fclose(fp);
+ } else {
+ printf("no\n");
+ }
+ return 0;
+}
+
+CamelMboxMessageInfo *camel_mbox_summary_uid(CamelMboxSummary *s, const char *uid)
+{
+ return g_hash_table_lookup(s->message_uid, uid);
+}
+
+CamelMboxMessageInfo *camel_mbox_summary_index(CamelMboxSummary *s, int index)
+{
+ return g_ptr_array_index(s->messages, index);
+}
+
+int camel_mbox_summary_message_count(CamelMboxSummary *s)
+{
+ return s->messages->len;
+}
+
+guint32 camel_mbox_summary_next_uid(CamelMboxSummary *s)
+{
+ guint32 uid = s->nextuid++;
+
+ summary_header_save(s);
+ return uid;
+}
+
+guint32 camel_mbox_summary_set_uid(CamelMboxSummary *s, guint32 uid)
+{
+ if (s->nextuid < uid) {
+ s->nextuid = uid;
+ summary_header_save(s);
+ }
+ return s->nextuid;
+}
+
+#if 0
+int main(int argc, char **argv)
+{
+ if (argc<2) {
+ printf("usage: %s mbox\n", argv[0]);
+ return 1;
+ }
+
+ gtk_init(&argc, &argv);
+
+ index_folder(argv[1]);
+
+ return 0;
}
+#endif
diff --git a/camel/providers/mbox/camel-mbox-summary.h b/camel/providers/mbox/camel-mbox-summary.h
index f8570f15c0..80b59ef54f 100644
--- a/camel/providers/mbox/camel-mbox-summary.h
+++ b/camel/providers/mbox/camel-mbox-summary.h
@@ -1,85 +1,78 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
-
-/*
- *
- * Author : Bertrand Guiheneuf <bertrand@helixcode.com>
+/*
+ * Copyright (C) 2000 Helix Code Inc.
*
- * Copyright (C) 1999 Helix Code (http://www.helixcode.com).
+ * Authors: Michael Zucchi <notzed@helixcode.com>
*
- * 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 free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library 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.
+ * 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 Library 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
+ * You should have received a copy of the GNU Library General Public
+ * License along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
-#ifndef MBOX_SUMMARY_H
-#define MBOX_SUMMARY_H 1
-
-#include <camel-folder-summary.h>
-
-#define CAMEL_MBOX_SUMMARY_TYPE (camel_mbox_summary_get_type ())
-#define CAMEL_MBOX_SUMMARY(obj) (GTK_CHECK_CAST((obj), CAMEL_MBOX_SUMMARY_TYPE, CamelMboxSummary))
-#define CAMEL_MBOX_SUMMARY_CLASS(k) (GTK_CHECK_CLASS_CAST ((k), CAMEL_MBOX_SUMMARY_TYPE, CamelMboxSummaryClass))
-#define CAMEL_IS_MBOX_SUMMARY(o) (GTK_CHECK_TYPE((o), CAMEL_MBOX_SUMMARY_TYPE))
-
-
-#define CAMEL_MBOX_SUMMARY_VERSION 1
+#ifndef _CAMEL_MBOX_SUMMARY_H
+#define _CAMEL_MBOX_SUMMARY_H
+#include <glib.h>
+#include <camel/camel-folder.h>
+#include <libibex/ibex.h>
typedef struct {
- CamelMessageInfo headers;
+ CamelMessageContentInfo info;
- guint32 position;
- guint size;
- guint x_evolution_offset;
- guint32 uid;
- guchar status;
+ /* position in stream of this part */
+ off_t pos;
+ off_t bodypos;
+ off_t endpos;
+} CamelMboxMessageContentInfo;
-} CamelMboxSummaryInformation;
-
-
-/* this contains informations about the whole mbox file */
typedef struct {
- CamelFolderSummary parent_object;
+ CamelMessageInfo info;
- guint nb_message; /* number of messages in the summary */
- guint32 next_uid;
- guint32 mbox_file_size;
- guint32 mbox_modtime;
+ /* position of the xev header, if one exists */
+ off_t xev_offset;
+} CamelMboxMessageInfo;
- GArray *message_info; /* array of CamelMboxSummaryInformation */
+typedef struct {
+ int dirty; /* if anything has changed */
-} CamelMboxSummary;
+ char *folder_path;
+ char *summary_path;
+ ibex *index;
-typedef struct {
- CamelFolderSummaryClass parent_class;
+ GPtrArray *messages; /* array of messages matching mbox order */
+ GHashTable *message_uid; /* index to messages by uid */
-} CamelMboxSummaryClass;
+ int nextuid;
+ time_t time; /* time/size of folder's last update */
+ size_t size;
+} CamelMboxSummary;
-GtkType camel_mbox_summary_get_type (void);
+CamelMboxSummary *camel_mbox_summary_new(const char *summary, const char *folder, ibex *index);
+void camel_mbox_summary_unref(CamelMboxSummary *);
-void camel_mbox_summary_save (CamelMboxSummary *summary,
- const gchar *filename, CamelException *ex);
-CamelMboxSummary *camel_mbox_summary_load (const gchar *filename,
- CamelException *ex);
+int camel_mbox_summary_load(CamelMboxSummary *);
+int camel_mbox_summary_save(CamelMboxSummary *);
+int camel_mbox_summary_check(CamelMboxSummary *);
-gboolean camel_mbox_summary_check_sync (gchar *summary_filename,
- gchar *mbox_filename,
- CamelException *ex);
+guint32 camel_mbox_summary_next_uid(CamelMboxSummary *);
+/* set the minimum uid */
+guint32 camel_mbox_summary_set_uid(CamelMboxSummary *s, guint32 uid);
-void camel_mbox_summary_append_entries (CamelMboxSummary *summary,
- GArray *entries);
+CamelMboxMessageInfo *camel_mbox_summary_uid(CamelMboxSummary *s, const char *uid);
+CamelMboxMessageInfo *camel_mbox_summary_index(CamelMboxSummary *, int index);
+int camel_mbox_summary_message_count(CamelMboxSummary *);
+/* TODO: should be in a utility library */
+int camel_mbox_summary_copy_block(int fromfd, int tofd, off_t readpos, size_t bytes);
-#endif /* MBOX_SUMMARY_H */
+#endif /* ! _CAMEL_MBOX_SUMMARY_H */
diff --git a/camel/providers/mbox/camel-mbox-utils.c b/camel/providers/mbox/camel-mbox-utils.c
index cd7da089e9..31710468b6 100644
--- a/camel/providers/mbox/camel-mbox-utils.c
+++ b/camel/providers/mbox/camel-mbox-utils.c
@@ -520,55 +520,3 @@ camel_mbox_write_xev (CamelMboxFolder *folder,
g_free (tmp_file_name_secure);
return next_free_uid;
}
-
-
-
-
-
-
-GArray *
-parsed_information_to_mbox_summary (GArray *parsed_information)
-{
- guint cur_msg;
- CamelMboxParserMessageInfo *cur_msg_info;
- GArray *mbox_summary;
- CamelMboxSummaryInformation *cur_sum_info;
-
- mbox_summary = g_array_new (FALSE, FALSE, sizeof (CamelMboxSummaryInformation));
- mbox_summary = g_array_set_size (mbox_summary, parsed_information->len);
-
- for (cur_msg = 0; cur_msg < parsed_information->len; cur_msg++) {
-
- cur_msg_info = (CamelMboxParserMessageInfo *)(parsed_information->data) + cur_msg;
- cur_sum_info = (CamelMboxSummaryInformation *)(mbox_summary->data) + cur_msg;
-
- cur_sum_info->position = cur_msg_info->message_position;
-
- cur_sum_info->size = cur_msg_info->size;
-
- cur_sum_info->x_evolution_offset = cur_msg_info->x_evolution_offset;
-
- cur_sum_info->uid = cur_msg_info->uid;
- cur_sum_info->headers.uid = g_strdup_printf ("%d",
- cur_sum_info->uid);
-
- cur_sum_info->status = cur_msg_info->status;
-
- cur_sum_info->headers.subject = cur_msg_info->subject;
- cur_msg_info->subject = NULL;
-
- cur_sum_info->headers.sender = cur_msg_info->from;
- cur_msg_info->from = NULL;
-
- cur_sum_info->headers.to = cur_msg_info->to;
- cur_msg_info->to = NULL;
-
- /* XXX I'm guessing one of these is wrong. */
- cur_sum_info->headers.received_date = cur_msg_info->date;
- cur_sum_info->headers.sent_date = g_strdup (cur_msg_info->date);
- cur_msg_info->date = NULL;
-
- }
-
- return mbox_summary;
-}