aboutsummaryrefslogtreecommitdiffstats
path: root/camel/providers/mbox/camel-mbox-folder.c
diff options
context:
space:
mode:
Diffstat (limited to 'camel/providers/mbox/camel-mbox-folder.c')
-rw-r--r--camel/providers/mbox/camel-mbox-folder.c256
1 files changed, 157 insertions, 99 deletions
diff --git a/camel/providers/mbox/camel-mbox-folder.c b/camel/providers/mbox/camel-mbox-folder.c
index 2420e59f43..64e589cba1 100644
--- a/camel/providers/mbox/camel-mbox-folder.c
+++ b/camel/providers/mbox/camel-mbox-folder.c
@@ -39,16 +39,14 @@
#include "camel-log.h"
#include "camel-stream-buffered-fs.h"
#include "camel-folder-summary.h"
+#include "camel-mbox-summary.h"
+#include "camel-mbox-parser.h"
+#include "camel-mbox-utils.h"
+#include "md5-utils.h"
#include "gmime-utils.h"
#include "camel-exception.h"
-#if 0
-#include "mbox-utils.h"
-#include "mbox-uid.h"
-#include "mbox-summary.h"
-#endif
-
static CamelFolderClass *parent_class=NULL;
/* Returns the class for a CamelMboxFolder */
@@ -68,9 +66,9 @@ static gboolean _create(CamelFolder *folder, CamelException *ex);
static gboolean _delete (CamelFolder *folder, gboolean recurse, CamelException *ex);
static gboolean _delete_messages (CamelFolder *folder, CamelException *ex);
static GList *_list_subfolders (CamelFolder *folder, CamelException *ex);
-#if 0
-static CamelMimeMessage *_get_message_by_number (CamelFolder *folder, gint number, CamelException *ex);
+/* static CamelMimeMessage *_get_message_by_number (CamelFolder *folder, gint number, CamelException *ex);*/
static gint _get_message_count (CamelFolder *folder, CamelException *ex);
+#if 0
static gint _append_message (CamelFolder *folder, CamelMimeMessage *message, CamelException *ex);
static void _expunge (CamelFolder *folder, CamelException *ex);
static void _copy_message_to (CamelFolder *folder, CamelMimeMessage *message, CamelFolder *dest_folder, CamelException *ex);
@@ -90,6 +88,7 @@ camel_mbox_folder_class_init (CamelMboxFolderClass *camel_mbox_folder_class)
parent_class = gtk_type_class (camel_folder_get_type ());
/* virtual method definition */
+
/* virtual method overload */
camel_folder_class->init_with_store = _init_with_store;
camel_folder_class->set_name = _set_name;
@@ -100,9 +99,9 @@ camel_mbox_folder_class_init (CamelMboxFolderClass *camel_mbox_folder_class)
camel_folder_class->delete = _delete;
camel_folder_class->delete_messages = _delete_messages;
camel_folder_class->list_subfolders = _list_subfolders;
-#if 0
- camel_folder_class->get_message_by_number = _get_message_by_number;
+ /* camel_folder_class->get_message_by_number = _get_message_by_number; */
camel_folder_class->get_message_count = _get_message_count;
+#if 0
camel_folder_class->append_message = _append_message;
camel_folder_class->expunge = _expunge;
camel_folder_class->copy_message_to = _copy_message_to;
@@ -167,6 +166,9 @@ camel_mbox_folder_get_type (void)
static void
_init_with_store (CamelFolder *folder, CamelStore *parent_store, CamelException *ex)
{
+ CamelMboxFolder *mbox_folder = CAMEL_MBOX_FOLDER (folder);
+
+
CAMEL_LOG_FULL_DEBUG ("Entering CamelMhFolder::init_with_store\n");
/* call parent method */
@@ -180,14 +182,104 @@ _init_with_store (CamelFolder *folder, CamelStore *parent_store, CamelException
folder->can_hold_folders = TRUE;
folder->has_summary_capability = TRUE;
folder->has_uid_capability = TRUE;
-
- folder->summary = NULL;
+ folder->summary = NULL;
+
+ mbox_folder->folder_file_path = NULL;
+ mbox_folder->summary_file_path = NULL;
+ mbox_folder->folder_dir_path = NULL;
+ mbox_folder->summary = NULL;
+ mbox_folder->uid_array = NULL;
CAMEL_LOG_FULL_DEBUG ("Leaving CamelMhFolder::init_with_store\n");
}
+/* 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)
+{
+ GArray *message_info_array;
+ gboolean summary_file_exists;
+ gboolean summary_file_is_sync;
+ GArray *mbox_summary_info;
+ gint mbox_file_fd;
+ guint32 next_uid;
+
+ /* test for the existence of the summary file */
+ summary_file_exists = (access (mbox_folder->summary_file_path, F_OK) == 0);
+
+ /* if the summary file exists, test if the
+ md5 of the mbox file is still in sync
+ with the one we had computed the last time
+ we saved the summary file */
+ if (summary_file_exists) {
+
+ summary_file_is_sync =
+ camel_mbox_check_summary_sync (mbox_folder->summary_file_path,
+ mbox_folder->folder_file_path,
+ ex);
+ if (camel_exception_get_id (ex)) return;
+ }
+
+
+ /* in the case where the summary does not exist
+ or is not in sync with the mbox file
+ regenerate it */
+ if ( !(summary_file_exists && summary_file_is_sync)) {
+
+ /* parse the mbox folder and get some
+ information about the messages */
+
+ mbox_file_fd = open (mbox_folder->folder_file_path, O_RDONLY);
+ message_info_array = camel_mbox_parse_file (mbox_file_fd,
+ "From - ",
+ 0,
+ &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->folder_file_path,
+ message_info_array, next_uid, ex);
+
+ if (camel_exception_get_id (ex)) {
+ /* ** FIXME : free the preparsed information */
+ return;
+ }
+
+ mbox_summary_info =
+ parsed_information_to_mbox_summary (message_info_array);
+
+ /* **FIXME : Free the parsed information structure */
+
+ /* allocate an internal summary object */
+ mbox_folder->summary = g_new (CamelMboxSummary, 1);
+
+ /* generate the folder md5 signature */
+ md5_get_digest_from_file (mbox_folder->folder_file_path, mbox_folder->summary->md5_digest);
+
+ /* store the number of messages as well as the summary array */
+ mbox_folder->summary->nb_message = mbox_summary_info->len;
+ mbox_folder->summary->next_uid = next_uid;
+ mbox_folder->summary->message_info = mbox_summary_info;
+
+ } else {
+ /* every thing seems ok, just read the summary file from disk */
+ mbox_folder->summary = camel_mbox_load_summary ("ev-summary.mbox", ex);
+ }
+}
@@ -195,37 +287,27 @@ static void
_open (CamelFolder *folder, CamelFolderOpenMode mode, CamelException *ex)
{
CamelMboxFolder *mbox_folder = CAMEL_MBOX_FOLDER (folder);
- struct dirent *dir_entry;
-
-
+ //struct dirent *dir_entry;
+ //struct stat stat_buf;
+
+
if (folder->open_state == FOLDER_OPEN) {
camel_exception_set (ex,
CAMEL_EXCEPTION_FOLDER_INVALID_STATE,
"folder is already open");
return;
}
-
-#if 0
- Here, we need to check for the summary file
- existence and create it if necessary.
+
+
/* get (or create) uid list */
- if (!(mbox_load_uid_list (mbox_folder) > 0))
- mbox_generate_uid_list (mbox_folder);
-
- /* get or create summary */
- /* it is important that it comes after uid list reading/generation */
- if (!(mbox_load_summary (mbox_folder) > 0))
- mbox_generate_summary (folder);
+ //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);
}
-
-
-
-
static void
_close (CamelFolder *folder, gboolean expunge, CamelException *ex)
{
@@ -234,6 +316,9 @@ _close (CamelFolder *folder, gboolean expunge, CamelException *ex)
/* call parent implementation */
parent_class->close (folder, expunge, ex);
+
+ /* save the folder summary on disc */
+ camel_mbox_save_summary (mbox_folder->summary, mbox_folder->summary_file_path, ex);
}
@@ -244,8 +329,8 @@ _set_name (CamelFolder *folder, const gchar *name, CamelException *ex)
{
CamelMboxFolder *mbox_folder = CAMEL_MBOX_FOLDER (folder);
const gchar *root_dir_path;
- gchar *full_name;
- const gchar *parent_full_name;
+ //gchar *full_name;
+ //const gchar *parent_full_name;
gchar separator;
CAMEL_LOG_FULL_DEBUG ("Entering CamelMboxFolder::set_name\n");
@@ -265,6 +350,7 @@ _set_name (CamelFolder *folder, const gchar *name, CamelException *ex)
CAMEL_LOG_FULL_DEBUG ("CamelMboxFolder::separator is %c\n", separator);
mbox_folder->folder_file_path = g_strdup_printf ("%s%c%s", root_dir_path, separator, folder->full_name);
+ mbox_folder->summary_file_path = g_strdup_printf ("%s%c.%s-ev-summary", root_dir_path, separator, folder->full_name);
mbox_folder->folder_dir_path = g_strdup_printf ("%s%c%s.sdb", root_dir_path, separator, folder->full_name);
@@ -313,8 +399,21 @@ _exists (CamelFolder *folder, CamelException *ex)
"undetermined folder directory path. Maybe use set_name ?");
return FALSE;
}
-
+
+
+ /* we should not check for that here */
+#if 0
/* check if the mbox directory exists */
+ access_result = access (mbox_folder->folder_dir_path, F_OK);
+ if (access_result < 0) {
+ CAMEL_LOG_FULL_DEBUG ("CamelMboxFolder::exists errot when executing access on %s\n",
+ mbox_folder->folder_dir_path);
+ CAMEL_LOG_FULL_DEBUG (" Full error text is : %s\n", strerror(errno));
+ camel_exception_set (ex,
+ CAMEL_EXCEPTION_SYSTEM,
+ strerror(errno));
+ return FALSE;
+ }
stat_error = stat (mbox_folder->folder_dir_path, &stat_buf);
if (stat_error == -1) {
CAMEL_LOG_FULL_DEBUG ("CamelMboxFolder::exists when executing stat on %s, stat_error = %d\n",
@@ -327,19 +426,14 @@ _exists (CamelFolder *folder, CamelException *ex)
}
exists = S_ISDIR (stat_buf.st_mode);
if (!exists) return FALSE;
+#endif
+
/* check if the mbox file exists */
stat_error = stat (mbox_folder->folder_file_path, &stat_buf);
- if (stat_error == -1) {
- CAMEL_LOG_FULL_DEBUG ("CamelMboxFolder::exists when executing stat on %s, stat_error = %d\n",
- mbox_folder->folder_file_path, stat_error);
- CAMEL_LOG_FULL_DEBUG (" Full error text is : %s\n", strerror(errno));
- camel_exception_set (ex,
- CAMEL_EXCEPTION_SYSTEM,
- strerror(errno));
+ if (stat_error == -1)
return FALSE;
- }
-
+
exists = S_ISREG (stat_buf.st_mode);
/* we should check the rights here */
@@ -410,7 +504,13 @@ _create (CamelFolder *folder, CamelException *ex)
umask (old_umask);
if (creat_fd == -1) goto io_error;
close (creat_fd);
-
+
+ /* create the summary object */
+ mbox_folder->summary = g_new (CamelMboxSummary, 1);
+ mbox_folder->summary->nb_message = 0;
+ mbox_folder->summary->next_uid = 1;
+ mbox_folder->summary->message_info = g_array_new (FALSE, FALSE, sizeof (CamelMboxSummaryInformation));
+
return TRUE;
/* exception handling for io errors */
@@ -472,7 +572,7 @@ _delete (CamelFolder *folder, gboolean recurse, CamelException *ex)
parent_class->delete (folder, recurse, ex);
- /* get the paths of what we need to delete */
+ /* get the paths of what we need to be deleted */
folder_file_path = mbox_folder->folder_file_path;
folder_dir_path = mbox_folder->folder_file_path;
@@ -638,7 +738,7 @@ _list_subfolders (CamelFolder *folder, CamelException *ex)
struct stat stat_buf;
gint stat_error = 0;
- GList *file_list;
+ //GList *file_list;
gchar *entry_name;
gchar *full_entry_name;
gchar *real_folder_name;
@@ -646,7 +746,7 @@ _list_subfolders (CamelFolder *folder, CamelException *ex)
DIR *dir_handle;
gboolean folder_suffix_found;
- gchar *io_error_text;
+ //gchar *io_error_text;
@@ -701,7 +801,7 @@ _list_subfolders (CamelFolder *folder, CamelException *ex)
CAMEL_LOG_FULL_DEBUG ("CamelMboxFolder::list_subfolders adding "
"%s\n", entry_name);
- /* if the folder is a netscape folder, remove the
+ /* if the folder is a netscape folder, remove the
".sdb" from the name */
real_folder_name = string_prefix (entry_name, ".sdb", &folder_suffix_found);
/* stick here the tests for other folder suffixes if any */
@@ -757,61 +857,19 @@ _list_subfolders (CamelFolder *folder, CamelException *ex)
-
-
-
-
-
-
-#if 0
-
-static CamelMimeMessage *
-_get_message_by_number (CamelFolder *folder, gint number, CamelException *ex)
+static gint
+_get_message_count (CamelFolder *folder, CamelException *ex)
{
- CamelMhFolder *mh_folder = CAMEL_MH_FOLDER(folder);
- const gchar *directory_path;
- gchar *message_name;
- gchar *message_file_name;
- CamelStream *input_stream = NULL;
- CamelMimeMessage *message = NULL;
- GList *message_list = NULL;
-
- g_assert(folder);
-
- directory_path = mh_folder->directory_path;
- if (!directory_path) return NULL;
+ CamelMboxFolder *mbox_folder = CAMEL_MBOX_FOLDER(folder);
+ gint message_count;
-
-
- message_name = g_list_nth_data (mh_folder->file_name_list, number);
+ g_assert (folder);
+ g_assert (mbox_folder->summary);
- if (message_name != NULL) {
- CAMEL_LOG_FULL_DEBUG ("CanelMhFolder::get_message message number = %d, name = %s\n",
- number, message_name);
- message_file_name = g_strdup_printf ("%s/%s", directory_path, message_name);
- input_stream = camel_stream_buffered_fs_new_with_name (message_file_name, CAMEL_STREAM_BUFFERED_FS_READ);
-
- if (input_stream != NULL) {
-#warning use session field here
- message = camel_mime_message_new_with_session ( (CamelSession *)NULL);
- camel_data_wrapper_construct_from_stream ( CAMEL_DATA_WRAPPER (message), input_stream);
- gtk_object_unref (GTK_OBJECT (input_stream));
- message->message_number = number;
- gtk_object_set_data_full (GTK_OBJECT (message), "filename",
- g_strdup (message_name), _filename_free);
-
-#warning Set flags and all this stuff here
- }
- g_free (message_file_name);
+ message_count = mbox_folder->summary->nb_message;
- } else
- CAMEL_LOG_FULL_DEBUG ("CanelMhFolder::get_message message number = %d, not found\n", number);
-
-
- return message;
+ CAMEL_LOG_FULL_DEBUG ("CamelMboxFolder::get_message_count found %d messages\n", message_count);
+ return message_count;
}
-#endif
-
-