From 6de256c2a2b23f30d35e4a2213ad5839bf141d06 Mon Sep 17 00:00:00 2001 From: Not Zed Date: Sun, 24 Dec 2000 00:46:20 +0000 Subject: Lock the command channel while searching. (imap_body_contains): If 2000-12-24 Not Zed * providers/imap/camel-imap-search.c (imap_body_contains): Lock the command channel while searching. (imap_body_contains): If performing a whole uid search, then add references to our own summary items, dont look it up in the folder. This way they can't vanish unexpectedly. * providers/imap/camel-imap-folder.h (CamelImapFolder): Added a private field. * providers/imap/camel-imap-private.h: Added lock for imap searches. * Merge from camel-mt-branch. * providers/imap/camel-imap-folder.c (imap_update_summary): Merge fix, use the folder->summary. (imap_get_message_flags, imap_set_message_flags, imap_get_message_user_flag, imap_set_message_user_flag): Removed again. (camel_imap_folder_init): Setup private data/lock. (imap_finalize): Free private data/search lock. (imap_search_free): Lock the search_lock. (imap_search_by_expression): Lock the search lock when using the search object. Also copy/ref hte summary, rather than getting it directly. (imap_refresh_info): Free any info lookups. Use folder->summary not imap_folder->summary. And lock around commands. svn path=/trunk/; revision=7150 --- camel/providers/local/Makefile.am | 3 + camel/providers/local/camel-local-folder.c | 263 +++++--------------------- camel/providers/local/camel-local-folder.h | 2 +- camel/providers/local/camel-local-private.h | 60 ++++++ camel/providers/local/camel-local-summary.c | 159 +--------------- camel/providers/local/camel-maildir-folder.c | 7 +- camel/providers/local/camel-maildir-summary.c | 34 +++- camel/providers/local/camel-mbox-folder.c | 58 +++++- camel/providers/local/camel-mbox-summary.c | 21 +- camel/providers/local/camel-mh-folder.c | 7 +- camel/providers/local/camel-mh-summary.c | 31 ++- 11 files changed, 231 insertions(+), 414 deletions(-) create mode 100644 camel/providers/local/camel-local-private.h (limited to 'camel/providers/local') diff --git a/camel/providers/local/Makefile.am b/camel/providers/local/Makefile.am index 1f250b04cd..2e95021334 100644 --- a/camel/providers/local/Makefile.am +++ b/camel/providers/local/Makefile.am @@ -47,6 +47,9 @@ libcamellocalinclude_HEADERS = \ camel-maildir-store.h \ camel-maildir-summary.h +noinst_HEADERS = \ + camel-local-private.h + libcamellocal_la_LDFLAGS = -version-info 0:0:0 libcamellocal_la_LIBADD = $(top_builddir)/e-util/libeutil.la $(top_builddir)/libibex/libibex.la $(UNICODE_LIBS) diff --git a/camel/providers/local/camel-local-folder.c b/camel/providers/local/camel-local-folder.c index 931c95a114..116a10ea7d 100644 --- a/camel/providers/local/camel-local-folder.c +++ b/camel/providers/local/camel-local-folder.c @@ -42,6 +42,8 @@ #include "camel-mime-filter-from.h" #include "camel-exception.h" +#include "camel-local-private.h" + #define d(x) /*(printf("%s(%d): ", __FILE__, __LINE__),(x))*/ static CamelFolderClass *parent_class = NULL; @@ -55,30 +57,11 @@ static int local_lock(CamelLocalFolder *lf, CamelLockType type, CamelException * static void local_unlock(CamelLocalFolder *lf); static void local_sync(CamelFolder *folder, gboolean expunge, CamelException *ex); -static gint local_get_message_count(CamelFolder *folder); -static gint local_get_unread_message_count(CamelFolder *folder); - -static GPtrArray *local_get_uids(CamelFolder *folder); -static GPtrArray *local_get_summary(CamelFolder *folder); -#if 0 -static void local_append_message(CamelFolder *folder, CamelMimeMessage * message, const CamelMessageInfo * info, CamelException *ex); -static CamelMimeMessage *local_get_message(CamelFolder *folder, const gchar * uid, CamelException *ex); -#endif static void local_expunge(CamelFolder *folder, CamelException *ex); -static const CamelMessageInfo *local_get_message_info(CamelFolder *folder, const char *uid); - static GPtrArray *local_search_by_expression(CamelFolder *folder, const char *expression, CamelException *ex); static void local_search_free(CamelFolder *folder, GPtrArray * result); -static guint32 local_get_message_flags(CamelFolder *folder, const char *uid); -static void local_set_message_flags(CamelFolder *folder, const char *uid, guint32 flags, guint32 set); -static gboolean local_get_message_user_flag(CamelFolder *folder, const char *uid, const char *name); -static void local_set_message_user_flag(CamelFolder *folder, const char *uid, const char *name, gboolean value); -static const char *local_get_message_user_tag(CamelFolder *folder, const char *uid, const char *name); -static void local_set_message_user_tag(CamelFolder *folder, const char *uid, const char *name, const char *value); - - static void local_finalize(CamelObject * object); static void @@ -92,26 +75,11 @@ camel_local_folder_class_init(CamelLocalFolderClass * camel_local_folder_class) /* virtual method overload */ camel_folder_class->sync = local_sync; - camel_folder_class->get_message_count = local_get_message_count; - camel_folder_class->get_unread_message_count = local_get_unread_message_count; - camel_folder_class->get_uids = local_get_uids; - camel_folder_class->free_uids = camel_folder_free_deep; - camel_folder_class->get_summary = local_get_summary; - camel_folder_class->free_summary = camel_folder_free_nop; camel_folder_class->expunge = local_expunge; camel_folder_class->search_by_expression = local_search_by_expression; camel_folder_class->search_free = local_search_free; - camel_folder_class->get_message_info = local_get_message_info; - - camel_folder_class->get_message_flags = local_get_message_flags; - camel_folder_class->set_message_flags = local_set_message_flags; - camel_folder_class->get_message_user_flag = local_get_message_user_flag; - camel_folder_class->set_message_user_flag = local_set_message_user_flag; - camel_folder_class->get_message_user_tag = local_get_message_user_tag; - camel_folder_class->set_message_user_tag = local_set_message_user_tag; - camel_local_folder_class->lock = local_lock; camel_local_folder_class->unlock = local_unlock; } @@ -129,18 +97,25 @@ local_init(gpointer object, gpointer klass) CAMEL_MESSAGE_DELETED | CAMEL_MESSAGE_DRAFT | CAMEL_MESSAGE_FLAGGED | CAMEL_MESSAGE_SEEN | CAMEL_MESSAGE_USER; - local_folder->summary = NULL; + folder->summary = NULL; local_folder->search = NULL; + + local_folder->priv = g_malloc0(sizeof(*local_folder->priv)); +#ifdef ENABLE_THREADS + local_folder->priv->search_lock = g_mutex_new(); +#endif } static void local_finalize(CamelObject * object) { CamelLocalFolder *local_folder = CAMEL_LOCAL_FOLDER(object); + CamelFolder *folder = (CamelFolder *)object; - if (local_folder->summary) { - camel_local_summary_sync(local_folder->summary, FALSE, local_folder->changes, NULL); - camel_object_unref((CamelObject *)local_folder->summary); + if (folder->summary) { + camel_local_summary_sync((CamelLocalSummary *)folder->summary, FALSE, local_folder->changes, NULL); + camel_object_unref((CamelObject *)folder->summary); + folder->summary = NULL; } if (local_folder->search) { @@ -160,6 +135,11 @@ local_finalize(CamelObject * object) g_free(local_folder->index_path); camel_folder_change_info_free(local_folder->changes); + +#ifdef ENABLE_THREADS + g_mutex_free(local_folder->priv->search_lock); +#endif + g_free(local_folder->priv); } CamelType camel_local_folder_get_type(void) @@ -228,8 +208,8 @@ camel_local_folder_construct(CamelLocalFolder *lf, CamelStore *parent_store, con lf->flags = flags; - lf->summary = CLOCALF_CLASS(lf)->create_summary(lf->summary_path, lf->folder_path, lf->index); - if (camel_local_summary_load(lf->summary, forceindex, ex) == -1) { + folder->summary = (CamelFolderSummary *)CLOCALF_CLASS(lf)->create_summary(lf->summary_path, lf->folder_path, lf->index); + if (camel_local_summary_load((CamelLocalSummary *)folder->summary, forceindex, ex) == -1) { camel_object_unref (CAMEL_OBJECT (folder)); return NULL; } @@ -289,7 +269,7 @@ local_sync(CamelFolder *folder, gboolean expunge, CamelException *ex) return; /* if sync fails, we'll pass it up on exit through ex */ - camel_local_summary_sync(lf->summary, expunge, lf->changes, ex); + camel_local_summary_sync((CamelLocalSummary *)folder->summary, expunge, lf->changes, ex); camel_local_folder_unlock(lf); if (camel_folder_change_info_changed(lf->changes)) { @@ -300,8 +280,8 @@ local_sync(CamelFolder *folder, gboolean expunge, CamelException *ex) /* force save of metadata */ if (lf->index) ibex_save(lf->index); - if (lf->summary) - camel_folder_summary_save(CAMEL_FOLDER_SUMMARY(lf->summary)); + if (folder->summary) + camel_folder_summary_save(folder->summary); } static void @@ -310,203 +290,48 @@ local_expunge(CamelFolder *folder, CamelException *ex) d(printf("expunge\n")); /* Just do a sync with expunge, serves the same purpose */ - camel_folder_sync(folder, TRUE, ex); -} - -/* - The following functions all work off the summary, so the default operations provided - in camel-local-folder will suffice for all subclasses. They may want to - snoop various operations to ensure the status remains synced, or just wait - for the sync operation -*/ -static gint -local_get_message_count(CamelFolder *folder) -{ - CamelLocalFolder *local_folder = CAMEL_LOCAL_FOLDER(folder); - - g_return_val_if_fail(local_folder->summary != NULL, -1); - - return camel_folder_summary_count(CAMEL_FOLDER_SUMMARY(local_folder->summary)); -} - -static gint -local_get_unread_message_count(CamelFolder *folder) -{ - CamelLocalFolder *local_folder = CAMEL_LOCAL_FOLDER(folder); - CamelMessageInfo *info; - GPtrArray *infolist; - gint i, max, count = 0; - - g_return_val_if_fail(local_folder->summary != NULL, -1); - - max = camel_folder_summary_count(CAMEL_FOLDER_SUMMARY(local_folder->summary)); - if (max == -1) - return -1; - - infolist = local_get_summary(folder); - - for (i = 0; i < infolist->len; i++) { - info = (CamelMessageInfo *) g_ptr_array_index(infolist, i); - if (!(info->flags & CAMEL_MESSAGE_SEEN)) - count++; - } - - return count; + /* call the callback directly, to avoid locking problems */ + CAMEL_FOLDER_CLASS (CAMEL_OBJECT_GET_CLASS(folder))->sync(folder, TRUE, ex); } static GPtrArray * -local_get_uids(CamelFolder *folder) -{ - GPtrArray *array; - CamelLocalFolder *local_folder = CAMEL_LOCAL_FOLDER(folder); - int i, count; - - count = camel_folder_summary_count(CAMEL_FOLDER_SUMMARY(local_folder->summary)); - array = g_ptr_array_new(); - g_ptr_array_set_size(array, count); - for (i = 0; i < count; i++) { - CamelMessageInfo *info = camel_folder_summary_index(CAMEL_FOLDER_SUMMARY(local_folder->summary), i); - - array->pdata[i] = g_strdup(camel_message_info_uid(info)); - } - - return array; -} - -GPtrArray * -local_get_summary(CamelFolder *folder) +local_search_by_expression(CamelFolder *folder, const char *expression, CamelException *ex) { CamelLocalFolder *local_folder = CAMEL_LOCAL_FOLDER(folder); + GPtrArray *summary, *matches; - return CAMEL_FOLDER_SUMMARY(local_folder->summary)->messages; -} - -/* get a single message info, by uid */ -static const CamelMessageInfo * -local_get_message_info(CamelFolder *folder, const char *uid) -{ - CamelLocalFolder *local_folder = CAMEL_LOCAL_FOLDER(folder); + /* NOTE: could get away without the search lock by creating a new + search object each time */ - return camel_folder_summary_uid(CAMEL_FOLDER_SUMMARY(local_folder->summary), uid); -} - -static GPtrArray * -local_search_by_expression(CamelFolder *folder, const char *expression, CamelException *ex) -{ - CamelLocalFolder *local_folder = CAMEL_LOCAL_FOLDER(folder); + CAMEL_LOCAL_FOLDER_LOCK(folder, search_lock); - if (local_folder->search == NULL) { + if (local_folder->search == NULL) local_folder->search = camel_folder_search_new(); - } camel_folder_search_set_folder(local_folder->search, folder); - if (local_folder->summary) { - /* FIXME: dont access summary array directly? */ - camel_folder_search_set_summary(local_folder->search, - CAMEL_FOLDER_SUMMARY(local_folder->summary)->messages); - } - camel_folder_search_set_body_index(local_folder->search, local_folder->index); + summary = camel_folder_get_summary(folder); + camel_folder_search_set_summary(local_folder->search, summary); - return camel_folder_search_execute_expression(local_folder->search, expression, ex); -} - -static void -local_search_free(CamelFolder *folder, GPtrArray * result) -{ - CamelLocalFolder *local_folder = CAMEL_LOCAL_FOLDER(folder); - - camel_folder_search_free_result(local_folder->search, result); -} - -static guint32 -local_get_message_flags(CamelFolder *folder, const char *uid) -{ - CamelMessageInfo *info; - CamelLocalFolder *mf = CAMEL_LOCAL_FOLDER(folder); - - info = camel_folder_summary_uid(CAMEL_FOLDER_SUMMARY(mf->summary), uid); - g_return_val_if_fail(info != NULL, 0); - - return info->flags; -} - -static void -local_set_message_flags(CamelFolder *folder, const char *uid, guint32 flags, guint32 set) -{ - CamelMessageInfo *info; - CamelLocalFolder *mf = CAMEL_LOCAL_FOLDER(folder); - guint32 new; - - info = camel_folder_summary_uid(CAMEL_FOLDER_SUMMARY(mf->summary), uid); - g_return_if_fail(info != NULL); - - new = (info->flags & ~flags) | (set & flags); - if (new == info->flags) - return; - - info->flags = new | CAMEL_MESSAGE_FOLDER_FLAGGED; - camel_folder_summary_touch(CAMEL_FOLDER_SUMMARY(mf->summary)); - - camel_object_trigger_event(CAMEL_OBJECT(folder), "message_changed", (char *) uid); -} + matches = camel_folder_search_execute_expression(local_folder->search, expression, ex); -static gboolean -local_get_message_user_flag(CamelFolder *folder, const char *uid, const char *name) -{ - CamelMessageInfo *info; - CamelLocalFolder *mf = CAMEL_LOCAL_FOLDER(folder); + CAMEL_LOCAL_FOLDER_UNLOCK(folder, search_lock); - info = camel_folder_summary_uid(CAMEL_FOLDER_SUMMARY(mf->summary), uid); - g_return_val_if_fail(info != NULL, FALSE); + camel_folder_free_summary(folder, summary); - return camel_flag_get(&info->user_flags, name); + return matches; } static void -local_set_message_user_flag(CamelFolder *folder, const char *uid, const char *name, gboolean value) -{ - CamelMessageInfo *info; - CamelLocalFolder *mf = CAMEL_LOCAL_FOLDER(folder); - - info = camel_folder_summary_uid(CAMEL_FOLDER_SUMMARY(mf->summary), uid); - g_return_if_fail(info != NULL); - - if (!camel_flag_set(&info->user_flags, name, value)) - return; - - info->flags |= CAMEL_MESSAGE_FOLDER_FLAGGED|CAMEL_MESSAGE_FOLDER_XEVCHANGE; - camel_folder_summary_touch(CAMEL_FOLDER_SUMMARY(mf->summary)); - camel_object_trigger_event(CAMEL_OBJECT(folder), "message_changed", (char *) uid); -} - -static const char * -local_get_message_user_tag(CamelFolder *folder, const char *uid, const char *name) -{ - CamelMessageInfo *info; - CamelLocalFolder *mf = CAMEL_LOCAL_FOLDER(folder); - - info = camel_folder_summary_uid(CAMEL_FOLDER_SUMMARY(mf->summary), uid); - g_return_val_if_fail(info != NULL, FALSE); - - return camel_tag_get(&info->user_tags, name); -} - -static void -local_set_message_user_tag(CamelFolder *folder, const char *uid, const char *name, const char *value) +local_search_free(CamelFolder *folder, GPtrArray * result) { - CamelMessageInfo *info; - CamelLocalFolder *mf = CAMEL_LOCAL_FOLDER(folder); + CamelLocalFolder *local_folder = CAMEL_LOCAL_FOLDER(folder); - info = camel_folder_summary_uid(CAMEL_FOLDER_SUMMARY(mf->summary), uid); - g_return_if_fail(info != NULL); + /* we need to lock this free because of the way search_free_result works */ + /* FIXME: put the lock inside search_free_result */ + CAMEL_LOCAL_FOLDER_LOCK(folder, search_lock); - if (!camel_tag_set(&info->user_tags, name, value)) - return; + camel_folder_search_free_result(local_folder->search, result); - info->flags |= CAMEL_MESSAGE_FOLDER_FLAGGED|CAMEL_MESSAGE_FOLDER_XEVCHANGE; - camel_folder_summary_touch(CAMEL_FOLDER_SUMMARY(mf->summary)); - camel_object_trigger_event(CAMEL_OBJECT(folder), "message_changed", (char *) uid); + CAMEL_LOCAL_FOLDER_UNLOCK(folder, search_lock); } - - diff --git a/camel/providers/local/camel-local-folder.h b/camel/providers/local/camel-local-folder.h index 4fa65420d4..7c975c8f7a 100644 --- a/camel/providers/local/camel-local-folder.h +++ b/camel/providers/local/camel-local-folder.h @@ -43,6 +43,7 @@ extern "C" { typedef struct { CamelFolder parent_object; + struct _CamelLocalFolderPrivate *priv; guint32 flags; /* open mode flags */ @@ -55,7 +56,6 @@ typedef struct { char *index_path; /* where the index file lives */ ibex *index; /* index for this folder */ - CamelLocalSummary *summary; CamelFolderSearch *search; /* used to run searches, we just use the real thing (tm) */ CamelFolderChangeInfo *changes; /* used to store changes to the folder during processing */ } CamelLocalFolder; diff --git a/camel/providers/local/camel-local-private.h b/camel/providers/local/camel-local-private.h new file mode 100644 index 0000000000..1d1a89ea27 --- /dev/null +++ b/camel/providers/local/camel-local-private.h @@ -0,0 +1,60 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- + * camel-local-private.h: Private info for local provider. + * + * Authors: Michael Zucchi + * + * Copyright 1999, 2000 Helix Code, Inc. (http://www.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 distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + * USA + */ + +#ifndef CAMEL_PRIVATE_H +#define CAMEL_PRIVATE_H 1 + +#ifdef __cplusplus +extern "C" { +#pragma } +#endif /* __cplusplus }*/ + +/* need a way to configure and save this data, if this header is to + be installed. For now, dont install it */ + +#include "config.h" + +#ifdef ENABLE_THREADS +#include +#endif + +struct _CamelLocalFolderPrivate { +#ifdef ENABLE_THREADS + GMutex *search_lock; /* for locking the search object */ +#endif +}; + +#ifdef ENABLE_THREADS +#define CAMEL_LOCAL_FOLDER_LOCK(f, l) (g_mutex_lock(((CamelLocalFolder *)f)->priv->l)) +#define CAMEL_LOCAL_FOLDER_UNLOCK(f, l) (g_mutex_unlock(((CamelLocalFolder *)f)->priv->l)) +#else +#define CAMEL_LOCAL_FOLDER_LOCK(f, l) +#define CAMEL_LOCAL_FOLDER_UNLOCK(f, l) +#endif + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* CAMEL_H */ + diff --git a/camel/providers/local/camel-local-summary.c b/camel/providers/local/camel-local-summary.c index 1377ff43a8..869b7c712a 100644 --- a/camel/providers/local/camel-local-summary.c +++ b/camel/providers/local/camel-local-summary.c @@ -42,19 +42,7 @@ struct _CamelLocalSummaryPrivate { #define _PRIVATE(o) (((CamelLocalSummary *)(o))->priv) -#if 0 -static int summary_header_load (CamelFolderSummary *, FILE *); -static int summary_header_save (CamelFolderSummary *, FILE *); -#endif - static CamelMessageInfo * message_info_new (CamelFolderSummary *, struct _header_raw *); -static CamelMessageInfo * message_info_new_from_parser (CamelFolderSummary *, CamelMimeParser *); -static CamelMessageInfo * message_info_new_from_message(CamelFolderSummary *s, CamelMimeMessage *msg); -#if 0 -static CamelMessageInfo * message_info_load (CamelFolderSummary *, FILE *); -static int message_info_save (CamelFolderSummary *, FILE *, CamelMessageInfo *); -#endif -/*static void message_info_free (CamelFolderSummary *, CamelMessageInfo *);*/ static int local_summary_decode_x_evolution(CamelLocalSummary *cls, const char *xev, CamelMessageInfo *mi); static char *local_summary_encode_x_evolution(CamelLocalSummary *cls, const CamelMessageInfo *mi); @@ -67,7 +55,6 @@ static CamelMessageInfo *local_summary_add(CamelLocalSummary *cls, CamelMimeMess static void camel_local_summary_class_init (CamelLocalSummaryClass *klass); static void camel_local_summary_init (CamelLocalSummary *obj); static void camel_local_summary_finalise (CamelObject *obj); - static CamelFolderSummaryClass *camel_local_summary_parent; CamelType @@ -95,16 +82,7 @@ camel_local_summary_class_init(CamelLocalSummaryClass *klass) camel_local_summary_parent = CAMEL_FOLDER_SUMMARY_CLASS(camel_type_get_global_classfuncs(camel_folder_summary_get_type())); - /*sklass->summary_header_load = summary_header_load; - sklass->summary_header_save = summary_header_save;*/ - sklass->message_info_new = message_info_new; - sklass->message_info_new_from_parser = message_info_new_from_parser; - sklass->message_info_new_from_message = message_info_new_from_message; - - /*sklass->message_info_load = message_info_load; - sklass->message_info_save = message_info_save;*/ - /*sklass->message_info_free = message_info_free;*/ klass->load = local_summary_load; klass->check = local_summary_check; @@ -288,6 +266,7 @@ camel_local_summary_check(CamelLocalSummary *cls, CamelFolderChangeInfo *changei for (i=0;isummary_header_load(s, in) == -1) - return -1; - - return camel_folder_summary_decode_uint32(in, &mbs->folder_size); -} - -static int -summary_header_save(CamelFolderSummary *s, FILE *out) -{ - CamelLocalSummary *mbs = CAMEL_LOCAL_SUMMARY(s); - - if (((CamelFolderSummaryClass *)camel_local_summary_parent)->summary_header_save(s, out) == -1) - return -1; - - return camel_folder_summary_encode_uint32(out, mbs->folder_size); -} - -static int -header_evolution_decode(const char *in, guint32 *uid, guint32 *flags) -{ - char *header; - - if (in && (header = header_token_decode(in))) { - if (strlen (header) == strlen ("00000000-0000") - && sscanf (header, "%08x-%04x", uid, flags) == 2) { - g_free(header); - return *uid; - } - g_free(header); - } - - return -1; -} - -static char * -header_evolution_encode(guint32 uid, guint32 flags) -{ - return g_strdup_printf("%08x-%04x", uid, flags & 0xffff); -} -#endif - static int local_summary_check(CamelLocalSummary *cls, CamelFolderChangeInfo *changeinfo, CamelException *ex) { - /* FIXME: sync index here */ + /* FIXME: sync index here ? */ return 0; } @@ -623,90 +555,3 @@ message_info_new(CamelFolderSummary *s, struct _header_raw *h) return mi; } - -static CamelMessageInfo * message_info_new_from_message(CamelFolderSummary *s, CamelMimeMessage *msg) -{ - CamelMessageInfo *mi; - /*CamelLocalSummary *cls = (CamelLocalSummary *)s;*/ - - mi = ((CamelFolderSummaryClass *)camel_local_summary_parent)->message_info_new_from_message(s, msg); -#if 0 - if (mi) { - - if (mi->uid == NULL) { - d(printf("no uid assigned yet, assigning one\n")); - mi->uid = camel_folder_summary_next_uid_string(s); - mi->flags |= CAMEL_MESSAGE_FOLDER_FLAGGED | CAMEL_MESSAGE_FOLDER_NOXEV; - } - - if (cls->index - && (cls->index_force - || !ibex_contains_name(cls->index, mi->uid))) { - d(printf("Am indexing message %s\n", mi->uid)); - camel_folder_summary_set_index(s, cls->index); - } else { - d(printf("Not indexing message %s\n", mi->uid)); - camel_folder_summary_set_index(s, NULL); - } - } -#endif - return mi; -} - -static CamelMessageInfo * -message_info_new_from_parser(CamelFolderSummary *s, CamelMimeParser *mp) -{ - CamelMessageInfo *mi; - /*CamelLocalSummary *mbs = CAMEL_LOCAL_SUMMARY(s);*/ - - mi = ((CamelFolderSummaryClass *)camel_local_summary_parent)->message_info_new_from_parser(s, mp); - if (mi) { -#if 0 - /* do we want to index this message as we add it, as well? */ - if (mbs->index - && (mbs->index_force - || !ibex_contains_name(mbs->index, mi->uid))) { - d(printf("Am indexing message %s\n", mi->uid)); - camel_folder_summary_set_index(s, mbs->index); - } else { - d(printf("Not indexing message %s\n", mi->uid)); - camel_folder_summary_set_index(s, NULL); - } -#endif - } - - return mi; -} - -#if 0 -static CamelMessageInfo * -message_info_load(CamelFolderSummary *s, FILE *in) -{ - CamelMessageInfo *mi; - - io(printf("loading local message info\n")); - - mi = ((CamelFolderSummaryClass *)camel_local_summary_parent)->message_info_load(s, in); - if (mi) { - guint32 position; - CamelLocalMessageInfo *mbi = (CamelLocalMessageInfo *)mi; - - camel_folder_summary_decode_uint32(in, &position); - mbi->frompos = position; - } - - return mi; -} - -static int -message_info_save(CamelFolderSummary *s, FILE *out, CamelMessageInfo *mi) -{ - CamelLocalMessageInfo *mbi = (CamelLocalMessageInfo *)mi; - - io(printf("saving local message info\n")); - - ((CamelFolderSummaryClass *)camel_local_summary_parent)->message_info_save(s, out, mi); - - return camel_folder_summary_encode_uint32(out, mbi->frompos); -} -#endif diff --git a/camel/providers/local/camel-maildir-folder.c b/camel/providers/local/camel-maildir-folder.c index d4771db5b8..c4d347d083 100644 --- a/camel/providers/local/camel-maildir-folder.c +++ b/camel/providers/local/camel-maildir-folder.c @@ -131,7 +131,7 @@ static void maildir_append_message(CamelFolder * folder, CamelMimeMessage * mess d(printf("Appending message\n")); /* add it to the summary/assign the uid, etc */ - mi = camel_local_summary_add(lf->summary, message, info, lf->changes, ex); + mi = camel_local_summary_add((CamelLocalSummary *)folder->summary, message, info, lf->changes, ex); if (camel_exception_is_set(ex)) { return; } @@ -191,7 +191,7 @@ static CamelMimeMessage *maildir_get_message(CamelFolder * folder, const gchar * d(printf("getting message: %s\n", uid)); /* get the message summary info */ - if ((info = camel_folder_summary_uid((CamelFolderSummary *)lf->summary, uid)) == NULL) { + if ((info = camel_folder_summary_uid(folder->summary, uid)) == NULL) { camel_exception_setv(ex, CAMEL_EXCEPTION_FOLDER_INVALID_UID, _("Cannot get message: %s\n %s"), uid, _("No such message")); return NULL; } @@ -200,6 +200,9 @@ static CamelMimeMessage *maildir_get_message(CamelFolder * folder, const gchar * /* what do we do if the message flags (and :info data) changes? filename mismatch - need to recheck I guess */ name = g_strdup_printf("%s/cur/%s", lf->folder_path, camel_maildir_info_filename(mdi)); + + camel_folder_summary_info_free(folder->summary, info); + if ((message_stream = camel_stream_fs_new_with_name(name, O_RDONLY, 0)) == NULL) { camel_exception_setv(ex, CAMEL_EXCEPTION_FOLDER_INVALID_UID, _("Cannot get message: %s\n %s"), name, g_strerror(errno)); diff --git a/camel/providers/local/camel-maildir-summary.c b/camel/providers/local/camel-maildir-summary.c index 8d421d5fdd..a65adafc0f 100644 --- a/camel/providers/local/camel-maildir-summary.c +++ b/camel/providers/local/camel-maildir-summary.c @@ -33,6 +33,7 @@ #include +#include "camel-private.h" #include "e-util/e-memory.h" #define d(x) /*(printf("%s(%d): ", __FILE__, __LINE__),(x))*/ @@ -474,6 +475,7 @@ remove_summary(char *key, CamelMessageInfo *info, CamelLocalSummary *cls) if (cls->index) ibex_unindex(cls->index, (char *)camel_message_info_uid(info)); camel_folder_summary_remove((CamelFolderSummary *)cls, info); + camel_folder_summary_info_free((CamelFolderSummary *)cls, info); } static int @@ -551,33 +553,47 @@ maildir_summary_check(CamelLocalSummary *cls, CamelFolderChangeInfo *changes, Ca if (info == NULL || (cls->index && (!ibex_contains_name(cls->index, uid)))) { /* need to add this file to the summary */ if (info != NULL) { - g_hash_table_remove(left, uid); + CamelMessageInfo *old = g_hash_table_lookup(left, camel_message_info_uid(info)); + if (old) { + g_hash_table_remove(left, uid); + camel_folder_summary_info_free((CamelFolderSummary *)cls, old); + } camel_folder_summary_remove((CamelFolderSummary *)cls, info); + camel_folder_summary_info_free((CamelFolderSummary *)cls, info); } camel_maildir_summary_add(cls, d->d_name, forceindex); } else { const char *filename; + CamelMessageInfo *old; - g_hash_table_remove(left, camel_message_info_uid(info)); + old = g_hash_table_lookup(left, camel_message_info_uid(info)); + if (old) { + camel_folder_summary_info_free((CamelFolderSummary *)cls, old); + g_hash_table_remove(left, camel_message_info_uid(info)); + } mdi = (CamelMaildirMessageInfo *)info; filename = camel_maildir_info_filename(mdi); /* TODO: only store the extension in the mdi->filename struct, not the whole lot */ if (filename == NULL || strcmp(filename, d->d_name) != 0) { #ifdef DOESTRV +#warning "cannot modify the estrv after its been setup, for mt-safe code" d(printf("filename changed: %s to %s\n", filename, d->d_name)); /* need to update the summary hash string reference since it might (will) change */ + CAMEL_SUMMARY_LOCK(s, summary_lock); g_hash_table_remove(s->messages_uid, uid); info->strings = e_strv_set_ref(info->strings, CAMEL_MAILDIR_INFO_FILENAME, d->d_name); /* we need to re-pack as well */ info->strings = e_strv_pack(info->strings); g_hash_table_insert(s->messages_uid, (char *)camel_message_info_uid(info), info); + CAMEL_SUMMARY_UNLOCK(s, summary_lock); #else g_free(mdi->filename); mdi->filename = g_strdup(d->d_name); #endif } + camel_folder_summary_info_free((CamelFolderSummary *)cls, info); } g_free(uid); } @@ -597,9 +613,10 @@ maildir_summary_check(CamelLocalSummary *cls, CamelFolderChangeInfo *changes, Ca continue; /* already in summary? shouldn't happen, but just incase ... */ - if (camel_folder_summary_uid((CamelFolderSummary *)cls, name)) + if ((info = camel_folder_summary_uid((CamelFolderSummary *)cls, name))) { + camel_folder_summary_info_free((CamelFolderSummary *)cls, info); newname = destname = camel_folder_summary_next_uid_string(s); - else { + } else { newname = NULL; destname = name; } @@ -633,7 +650,9 @@ maildir_summary_check(CamelLocalSummary *cls, CamelFolderChangeInfo *changes, Ca g_free(cur); /* sort the summary based on receive time, since the directory order is not useful */ + CAMEL_SUMMARY_LOCK(s, summary_lock); qsort(s->messages->pdata, s->messages->len, sizeof(CamelMessageInfo *), sort_receive_cmp); + CAMEL_SUMMARY_UNLOCK(s, summary_lock); /* FIXME: move this up a class? */ @@ -699,12 +718,18 @@ maildir_summary_sync(CamelLocalSummary *cls, gboolean expunge, CamelFolderChange /* we'll assume it didn't work, but dont change anything else */ g_free(newname); } else { + /* TODO: If this is made mt-safe, then this code could be a problem, since + the estrv is being modified. + Sigh, this may mean the maildir name has to be cached another way */ #ifdef DOESTRV +#warning "cannot modify the estrv after its been setup, for mt-safe code" + CAMEL_SUMMARY_LOCK(s, summary_lock); /* need to update the summary hash ref */ g_hash_table_remove(s->messages_uid, camel_message_info_uid(info)); info->strings = e_strv_set_ref_free(info->strings, CAMEL_MAILDIR_INFO_FILENAME, newname); info->strings = e_strv_pack(info->strings); g_hash_table_insert(s->messages_uid, (char *)camel_message_info_uid(info), info); + CAMEL_SUMMARY_UNLOCK(s, summary_lock); #else g_free(mdi->filename); mdi->filename = newname; @@ -719,6 +744,7 @@ maildir_summary_sync(CamelLocalSummary *cls, gboolean expunge, CamelFolderChange /* strip FOLDER_MESSAGE_FLAGED, etc */ info->flags &= 0xffff; } + camel_folder_summary_info_free((CamelFolderSummary *)cls, info); } return 0; } diff --git a/camel/providers/local/camel-mbox-folder.c b/camel/providers/local/camel-mbox-folder.c index 41fb5865b5..14dca0049e 100644 --- a/camel/providers/local/camel-mbox-folder.c +++ b/camel/providers/local/camel-mbox-folder.c @@ -54,6 +54,9 @@ static CamelLocalFolderClass *parent_class = NULL; static int mbox_lock(CamelLocalFolder *lf, CamelLockType type, CamelException *ex); static void mbox_unlock(CamelLocalFolder *lf); +static void mbox_set_message_user_flag(CamelFolder *folder, const char *uid, const char *name, gboolean value); +static void mbox_set_message_user_tag(CamelFolder *folder, const char *uid, const char *name, const char *value); + static void mbox_append_message(CamelFolder *folder, CamelMimeMessage * message, const CamelMessageInfo * info, CamelException *ex); static CamelMimeMessage *mbox_get_message(CamelFolder *folder, const gchar * uid, CamelException *ex); static CamelLocalSummary *mbox_create_summary(const char *path, const char *folder, ibex *index); @@ -74,6 +77,9 @@ camel_mbox_folder_class_init(CamelMboxFolderClass * camel_mbox_folder_class) camel_folder_class->append_message = mbox_append_message; camel_folder_class->get_message = mbox_get_message; + camel_folder_class->set_message_user_flag = mbox_set_message_user_flag; + camel_folder_class->set_message_user_tag = mbox_set_message_user_tag; + lclass->create_summary = mbox_create_summary; lclass->lock = mbox_lock; lclass->unlock = mbox_unlock; @@ -164,7 +170,7 @@ mbox_append_message(CamelFolder *folder, CamelMimeMessage * message, const Camel CamelLocalFolder *lf = (CamelLocalFolder *)folder; CamelStream *output_stream = NULL, *filter_stream = NULL; CamelMimeFilter *filter_from = NULL; - CamelMboxSummary *mbs = (CamelMboxSummary *)lf->summary; + CamelMboxSummary *mbs = (CamelMboxSummary *)folder->summary; CamelMessageInfo *mi; char *fromline = NULL; int fd; @@ -179,12 +185,12 @@ mbox_append_message(CamelFolder *folder, CamelMimeMessage * message, const Camel d(printf("Appending message\n")); /* first, check the summary is correct (updates folder_size too) */ - camel_local_summary_check(lf->summary, lf->changes, ex); + camel_local_summary_check((CamelLocalSummary *)folder->summary, lf->changes, ex); if (camel_exception_is_set(ex)) goto fail; /* add it to the summary/assign the uid, etc */ - mi = camel_local_summary_add(lf->summary, message, info, lf->changes, ex); + mi = camel_local_summary_add((CamelLocalSummary *)folder->summary, message, info, lf->changes, ex); if (camel_exception_is_set(ex)) goto fail; @@ -199,7 +205,7 @@ mbox_append_message(CamelFolder *folder, CamelMimeMessage * message, const Camel /* and we need to set the frompos/XEV explicitly */ ((CamelMboxMessageInfo *)mi)->frompos = mbs->folder_size?mbs->folder_size+1:0; #if 0 - xev = camel_local_summary_encode_x_evolution(lf->summary, mi); + xev = camel_local_summary_encode_x_evolution((CamelLocalSummary *)folder->summary, mi); if (xev) { /* the x-ev header should match the 'current' flags, no problem, so store as much */ camel_medium_set_header((CamelMedium *)message, "X-Evolution", xev); @@ -304,7 +310,7 @@ mbox_get_message(CamelFolder *folder, const gchar * uid, CamelException *ex) retry: /* get the message summary info */ - info = (CamelMboxMessageInfo *) camel_folder_summary_uid((CamelFolderSummary *)lf->summary, uid); + info = (CamelMboxMessageInfo *) camel_folder_summary_uid(folder->summary, uid); if (info == NULL) { camel_exception_setv(ex, CAMEL_EXCEPTION_FOLDER_INVALID_UID, @@ -327,6 +333,7 @@ retry: _("Cannot get message: %s from folder %s\n %s"), uid, lf->folder_path, strerror(errno)); camel_local_folder_unlock(lf); + camel_folder_summary_info_free(folder->summary, (CamelMessageInfo *)info); return NULL; } @@ -345,10 +352,11 @@ retry: camel_mime_parser_state(parser)); camel_object_unref((CamelObject *)parser); + camel_folder_summary_info_free(folder->summary, (CamelMessageInfo *)info); if (!retried) { retried = TRUE; - camel_local_summary_check(lf->summary, lf->changes, ex); + camel_local_summary_check((CamelLocalSummary *)folder->summary, lf->changes, ex); if (!camel_exception_is_set(ex)) goto retry; } @@ -360,6 +368,8 @@ retry: camel_local_folder_unlock(lf); return NULL; } + + camel_folder_summary_info_free(folder->summary, (CamelMessageInfo *)info); message = camel_mime_message_new(); if (camel_mime_part_construct_from_parser((CamelMimePart *)message, parser) == -1) { @@ -386,3 +396,39 @@ retry: return message; } + +static void +mbox_set_message_user_flag(CamelFolder *folder, const char *uid, const char *name, gboolean value) +{ + CamelMessageInfo *info; + + g_return_if_fail(folder->summary != NULL); + + info = camel_folder_summary_uid(folder->summary, uid); + g_return_if_fail(info != NULL); + + if (camel_flag_set(&info->user_flags, name, value)) { + info->flags |= CAMEL_MESSAGE_FOLDER_FLAGGED|CAMEL_MESSAGE_FOLDER_XEVCHANGE; + camel_folder_summary_touch(folder->summary); + camel_object_trigger_event(CAMEL_OBJECT(folder), "message_changed", (char *) uid); + } + camel_folder_summary_info_free(folder->summary, info); +} + +static void +mbox_set_message_user_tag(CamelFolder *folder, const char *uid, const char *name, const char *value) +{ + CamelMessageInfo *info; + + g_return_if_fail(folder->summary != NULL); + + info = camel_folder_summary_uid(folder->summary, uid); + g_return_if_fail(info != NULL); + + if (camel_tag_set(&info->user_tags, name, value)) { + info->flags |= CAMEL_MESSAGE_FOLDER_FLAGGED|CAMEL_MESSAGE_FOLDER_XEVCHANGE; + camel_folder_summary_touch(folder->summary); + camel_object_trigger_event(CAMEL_OBJECT(folder), "message_changed", (char *) uid); + } + camel_folder_summary_info_free(folder->summary, info); +} diff --git a/camel/providers/local/camel-mbox-summary.c b/camel/providers/local/camel-mbox-summary.c index 2dde67b70c..5b62743857 100644 --- a/camel/providers/local/camel-mbox-summary.c +++ b/camel/providers/local/camel-mbox-summary.c @@ -306,6 +306,7 @@ summary_update(CamelLocalSummary *cls, off_t offset, CamelFolderChangeInfo *chan CamelMessageInfo *mi = camel_folder_summary_index(s, i); camel_folder_change_info_add_source(changeinfo, camel_message_info_uid(mi)); + camel_folder_summary_info_free(s, mi); } } @@ -318,6 +319,7 @@ summary_update(CamelLocalSummary *cls, off_t offset, CamelFolderChangeInfo *chan for (i = 0; i < count; i++) { CamelMessageInfo *mi = camel_folder_summary_index(s, i); camel_folder_change_info_add_update(changeinfo, camel_message_info_uid(mi)); + camel_folder_summary_info_free(s, mi); } camel_folder_change_info_build_diff(changeinfo); } @@ -459,7 +461,7 @@ mbox_summary_sync_full(CamelLocalSummary *cls, gboolean expunge, CamelFolderChan CamelFolderSummary *s = (CamelFolderSummary *)mbs; CamelMimeParser *mp = NULL; int i, count; - CamelMboxMessageInfo *info; + CamelMboxMessageInfo *info = NULL; int fd = -1, fdout = -1; char *tmpname = NULL; char *buffer, *xevnew = NULL; @@ -533,6 +535,7 @@ mbox_summary_sync_full(CamelLocalSummary *cls, gboolean expunge, CamelFolderChan /* remove it from the change list */ camel_folder_change_info_remove_uid(changeinfo, uid); camel_folder_summary_remove(s, (CamelMessageInfo *)info); + camel_folder_summary_info_free(s, (CamelMessageInfo *)info); count--; i--; info = NULL; @@ -584,6 +587,8 @@ mbox_summary_sync_full(CamelLocalSummary *cls, gboolean expunge, CamelFolderChan d(printf("we are now at %d, from = %d\n", (int)camel_mime_parser_tell(mp), (int)camel_mime_parser_tell_start_from(mp))); camel_mime_parser_unstep(mp); + camel_folder_summary_info_free(s, (CamelMessageInfo *)info); + info = NULL; } } @@ -634,6 +639,8 @@ mbox_summary_sync_full(CamelLocalSummary *cls, gboolean expunge, CamelFolderChan unlink(tmpname); if (mp) camel_object_unref((CamelObject *)mp); + if (info) + camel_folder_summary_info_free(s, (CamelMessageInfo *)info); return -1; } @@ -646,7 +653,7 @@ mbox_summary_sync_quick(CamelLocalSummary *cls, gboolean expunge, CamelFolderCha CamelFolderSummary *s = (CamelFolderSummary *)mbs; CamelMimeParser *mp = NULL; int i, count; - CamelMboxMessageInfo *info; + CamelMboxMessageInfo *info = NULL; int fd = -1; char *xevnew, *xevtmp; const char *xev; @@ -678,8 +685,11 @@ mbox_summary_sync_quick(CamelLocalSummary *cls, gboolean expunge, CamelFolderCha d(printf("Checking message %s %08x\n", info->info.uid, info->info.flags)); - if ((info->info.flags & CAMEL_MESSAGE_FOLDER_FLAGGED) == 0) + if ((info->info.flags & CAMEL_MESSAGE_FOLDER_FLAGGED) == 0) { + camel_folder_summary_info_free(s, (CamelMessageInfo *)info); + info = NULL; continue; + } d(printf("Updating message %s\n", info->info.uid)); @@ -738,6 +748,7 @@ mbox_summary_sync_quick(CamelLocalSummary *cls, gboolean expunge, CamelFolderCha camel_mime_parser_drop_step(mp); info->info.flags &= 0xffff; + camel_folder_summary_info_free(s, (CamelMessageInfo *)info); } d(printf("Closing folders\n")); @@ -757,9 +768,10 @@ mbox_summary_sync_quick(CamelLocalSummary *cls, gboolean expunge, CamelFolderCha error: if (fd != -1) close(fd); - if (mp) camel_object_unref((CamelObject *)mp); + if (info) + camel_folder_summary_info_free(s, (CamelMessageInfo *)info); return -1; } @@ -792,6 +804,7 @@ mbox_summary_sync(CamelLocalSummary *cls, gboolean expunge, CamelFolderChangeInf quick = FALSE; else work |= (info->flags & CAMEL_MESSAGE_FOLDER_FLAGGED) != 0; + camel_folder_summary_info_free(s, info); } /* yuck i hate this logic, but its to simplify the 'all ok, update summary' and failover cases */ diff --git a/camel/providers/local/camel-mh-folder.c b/camel/providers/local/camel-mh-folder.c index 063e7e939e..fec620edea 100644 --- a/camel/providers/local/camel-mh-folder.c +++ b/camel/providers/local/camel-mh-folder.c @@ -132,7 +132,7 @@ static void mh_append_message(CamelFolder * folder, CamelMimeMessage * message, d(printf("Appending message\n")); /* add it to the summary/assign the uid, etc */ - mi = camel_local_summary_add(lf->summary, message, info, lf->changes, ex); + mi = camel_local_summary_add((CamelLocalSummary *)folder->summary, message, info, lf->changes, ex); if (camel_exception_is_set(ex)) { return; } @@ -179,11 +179,14 @@ static CamelMimeMessage *mh_get_message(CamelFolder * folder, const gchar * uid, d(printf("getting message: %s\n", uid)); /* get the message summary info */ - if ((info = camel_folder_summary_uid((CamelFolderSummary *)lf->summary, uid)) == NULL) { + if ((info = camel_folder_summary_uid(folder->summary, uid)) == NULL) { camel_exception_setv(ex, CAMEL_EXCEPTION_FOLDER_INVALID_UID, _("Cannot get message: %s\n %s"), uid, _("No such message")); return NULL; } + /* we only need it to check the message exists */ + camel_folder_summary_info_free(folder->summary, info); + name = g_strdup_printf("%s/%s", lf->folder_path, uid); if ((message_stream = camel_stream_fs_new_with_name(name, O_RDONLY, 0)) == NULL) { camel_exception_setv(ex, CAMEL_EXCEPTION_FOLDER_INVALID_UID, _("Cannot get message: %s\n %s"), diff --git a/camel/providers/local/camel-mh-summary.c b/camel/providers/local/camel-mh-summary.c index e5f37d879a..c933626653 100644 --- a/camel/providers/local/camel-mh-summary.c +++ b/camel/providers/local/camel-mh-summary.c @@ -37,8 +37,6 @@ #define CAMEL_MH_SUMMARY_VERSION (0x2000) -static CamelMessageInfo *message_info_new(CamelFolderSummary *, struct _header_raw *); - static int mh_summary_check(CamelLocalSummary *cls, CamelFolderChangeInfo *changeinfo, CamelException *ex); static int mh_summary_sync(CamelLocalSummary *cls, gboolean expunge, CamelFolderChangeInfo *changeinfo, CamelException *ex); /*static int mh_summary_add(CamelLocalSummary *cls, CamelMimeMessage *msg, CamelMessageInfo *info, CamelFolderChangeInfo *, CamelException *ex);*/ @@ -84,7 +82,6 @@ camel_mh_summary_class_init (CamelMhSummaryClass *class) parent_class = (CamelLocalSummaryClass *)camel_type_get_global_classfuncs(camel_local_summary_get_type ()); /* override methods */ - sklass->message_info_new = message_info_new; sklass->next_uid_string = mh_summary_next_uid_string; lklass->check = mh_summary_check; @@ -125,20 +122,6 @@ CamelMhSummary *camel_mh_summary_new (const char *filename, const char *mhdir, i return o; } -static CamelMessageInfo *message_info_new(CamelFolderSummary * s, struct _header_raw *h) -{ - CamelMessageInfo *mi; - /*CamelMhSummary *mhs = (CamelMhSummary *)s;*/ - - mi = ((CamelFolderSummaryClass *) parent_class)->message_info_new(s, h); - /* hmm, this isn't quite right */ - if (mi) { - /*mi->uid = mh_summary_next_uid_string(s);*/ - } - - return mi; -} - static char *mh_summary_next_uid_string(CamelFolderSummary *s) { CamelMhSummary *mhs = (CamelMhSummary *)s; @@ -206,6 +189,7 @@ remove_summary(char *key, CamelMessageInfo *info, CamelLocalSummary *cls) if (cls->index) ibex_unindex(cls->index, (char *)camel_message_info_uid(info)); camel_folder_summary_remove((CamelFolderSummary *)cls, info); + camel_folder_summary_info_free((CamelFolderSummary *)cls, info); } static int @@ -256,11 +240,19 @@ mh_summary_check(CamelLocalSummary *cls, CamelFolderChangeInfo *changeinfo, Came if (info != NULL) { g_hash_table_remove(left, camel_message_info_uid(info)); camel_folder_summary_remove((CamelFolderSummary *)cls, info); + camel_folder_summary_info_free((CamelFolderSummary *)cls, info); } camel_mh_summary_add(cls, d->d_name, forceindex); } else { - g_hash_table_remove(left, camel_message_info_uid(info)); - } + const char *uid = camel_message_info_uid(info); + CamelMessageInfo *old = g_hash_table_lookup(left, uid); + + if (old) { + camel_folder_summary_info_free((CamelFolderSummary *)cls, old); + g_hash_table_remove(left, uid); + } + camel_folder_summary_info_free((CamelFolderSummary *)cls, info); + } } } closedir(dir); @@ -394,6 +386,7 @@ mh_summary_sync(CamelLocalSummary *cls, gboolean expunge, CamelFolderChangeInfo g_warning("Problem occured when trying to expunge, ignored"); } } + camel_folder_summary_info_free((CamelFolderSummary *)cls, info); } return 0; -- cgit v1.2.3