aboutsummaryrefslogtreecommitdiffstats
path: root/camel
diff options
context:
space:
mode:
authorbertrand <Bertrand.Guiheneuf@aful.org>1999-08-15 02:50:46 +0800
committerBertrand Guiheneuf <bertrand@src.gnome.org>1999-08-15 02:50:46 +0800
commite579dc553cd47efae4c0064c9bad22fbbc11300e (patch)
treedd29ca061e8960b28fb76a7c580fccc23702b129 /camel
parent920be6e190bf0dd0056a71695cf3350625e8318c (diff)
downloadgsoc2013-evolution-e579dc553cd47efae4c0064c9bad22fbbc11300e.tar.gz
gsoc2013-evolution-e579dc553cd47efae4c0064c9bad22fbbc11300e.tar.zst
gsoc2013-evolution-e579dc553cd47efae4c0064c9bad22fbbc11300e.zip
Implemented deletion/expunge mechanism.
1999-08-14 bertrand <Bertrand.Guiheneuf@aful.org> * tests/ui-tests/store_listing.c (delete_selected_messages): (expunge_selected_folders): Implemented deletion/expunge mechanism. * camel/camel-folder.c (_get_message): Added some debug info. * camel/providers/MH/camel-mh-folder.c (_expunge): implemented and tested. * camel/camel-mime-message.c (_set_flag): changed the old braindead implementation. boolean are inserted in the flag hash table casted as gpointers. * camel/camel-mime-message.c: indentation fix svn path=/trunk/; revision=1114
Diffstat (limited to 'camel')
-rw-r--r--camel/camel-folder.c27
-rw-r--r--camel/camel-mime-message.c108
-rw-r--r--camel/camel-mime-message.h4
-rw-r--r--camel/providers/MH/camel-mh-folder.c120
4 files changed, 187 insertions, 72 deletions
diff --git a/camel/camel-folder.c b/camel/camel-folder.c
index d7319c5017..ef09b061e1 100644
--- a/camel/camel-folder.c
+++ b/camel/camel-folder.c
@@ -779,19 +779,28 @@ _get_message (CamelFolder *folder, gint number)
GList *message_node;
message_node = folder->message_list;
-
+ CAMEL_LOG_FULL_DEBUG ("CamelFolder::get_message Looking for message nummber %d\n", number);
/* look in folder message list if the
* if the message has not already been retreived */
while ((!new_message) && message_node) {
a_message = CAMEL_MIME_MESSAGE (message_node->data);
- CAMEL_LOG_FULL_DEBUG ("CamelFolder::get_message Current message number is %d\n", a_message->message_number);
- if (a_message && (a_message->message_number == number)) {
- CAMEL_LOG_FULL_DEBUG ("CamelFolder::get_message message %d already retreived once: returning %pOK\n",
- number, a_message);
- new_message = a_message;
+
+ if (a_message) {
+ CAMEL_LOG_FULL_DEBUG ("CamelFolder::get_message "
+ "found message number %d in the active list\n",
+ a_message->message_number);
+ if (a_message->message_number == number) {
+ CAMEL_LOG_FULL_DEBUG ("CamelFolder::get_message message "
+ "%d already retreived once: returning %pOK\n",
+ number, a_message);
+ new_message = a_message;
+ }
+ } else {
+ CAMEL_LOG_WARNING ("CamelFolder::get_message "
+ " problem in the active list, a message was NULL\n");
}
message_node = message_node->next;
-
+
CAMEL_LOG_FULL_DEBUG ("CamelFolder::get_message message node = %p\n", message_node);
}
return new_message;
@@ -818,7 +827,9 @@ camel_folder_get_message (CamelFolder *folder, gint number)
/* now put the new message in the list of messages got from
* this folder. If people show concerns about this code being
- * here, we will let the providers do it by themself */
+ * here, we will let the providers do it by themself
+ * Update: I am actually concern. This will go into util routines
+ * and providers will have to do the job themself :) */
if (!new_message) return NULL;
/* if the message has not been already put in
* this folder message list, put it in */
diff --git a/camel/camel-mime-message.c b/camel/camel-mime-message.c
index 3d33f43446..e91b5a3624 100644
--- a/camel/camel-mime-message.c
+++ b/camel/camel-mime-message.c
@@ -88,7 +88,7 @@ _init_header_name_table()
g_hash_table_insert (header_name_table, "To", (gpointer)HEADER_TO);
g_hash_table_insert (header_name_table, "Cc", (gpointer)HEADER_CC);
g_hash_table_insert (header_name_table, "Bcc", (gpointer)HEADER_BCC);
-
+
}
static void
@@ -97,10 +97,10 @@ camel_mime_message_class_init (CamelMimeMessageClass *camel_mime_message_class)
CamelDataWrapperClass *camel_data_wrapper_class = CAMEL_DATA_WRAPPER_CLASS (camel_mime_message_class);
CamelMimePartClass *camel_mime_part_class = CAMEL_MIME_PART_CLASS (camel_mime_message_class);
GtkObjectClass *gtk_object_class = GTK_OBJECT_CLASS (camel_mime_message_class);
-
+
parent_class = gtk_type_class (camel_mime_part_get_type ());
_init_header_name_table();
-
+
received_date_str = "";
sent_date_str = "";
reply_to_str = "Reply-To";
@@ -129,7 +129,7 @@ camel_mime_message_class_init (CamelMimeMessageClass *camel_mime_message_class)
/* virtual method overload */
camel_data_wrapper_class->write_to_stream = _write_to_stream;
camel_mime_part_class->parse_header_pair = _parse_header_pair;
-
+
gtk_object_class->finalize = _finalize;
}
@@ -140,7 +140,7 @@ static void
camel_mime_message_init (gpointer object, gpointer klass)
{
CamelMimeMessage *camel_mime_message = CAMEL_MIME_MESSAGE (object);
-
+
camel_mime_message->recipients = g_hash_table_new (g_strcase_hash, g_strcase_equal);
camel_mime_message->flags = g_hash_table_new (g_strcase_hash, g_strcase_equal);
}
@@ -174,21 +174,22 @@ static void
_finalize (GtkObject *object)
{
CamelMimeMessage *message = CAMEL_MIME_MESSAGE (object);
-
+
CAMEL_LOG_FULL_DEBUG ("Entering CamelMimeMessage::finalize\n");
if (message->received_date) g_free (message->received_date);
if (message->sent_date) g_free (message->sent_date);
if (message->subject) g_free (message->subject);
if (message->reply_to) g_free (message->reply_to);
if (message->from) g_free (message->from);
-
+
#warning free recipients.
if (message->folder) gtk_object_unref (GTK_OBJECT (message->folder));
if (message->session) gtk_object_unref (GTK_OBJECT (message->session));
if (message->flags)
- g_hash_table_foreach (message->flags, g_hash_table_generic_free, NULL);
+ g_hash_table_foreach (message->flags, g_hash_table_generic_free, NULL);
+
GTK_OBJECT_CLASS (parent_class)->finalize (object);
CAMEL_LOG_FULL_DEBUG ("Leaving CamelMimeMessage::finalize\n");
}
@@ -202,7 +203,7 @@ camel_mime_message_new_with_session (CamelSession *session)
mime_message = gtk_type_new (CAMEL_MIME_MESSAGE_TYPE);
mime_message->session = session;
if (session) gtk_object_ref (GTK_OBJECT (session));
-
+
return mime_message;
}
@@ -387,10 +388,10 @@ _add_recipient (CamelMimeMessage *mime_message, gchar *recipient_type, gchar *re
/* be careful, recipient_type and recipient may be freed within this func */
GList *recipients_list;
GList *existent_list;
-
+
/* see if there is already a list for this recipient type */
existent_list = (GList *)g_hash_table_lookup (mime_message->recipients, recipient_type);
-
+
/* if the recipient is already in this list, do nothing */
if ( existent_list && g_list_find_custom (existent_list, (gpointer)recipient, string_equal_for_glist) ) {
g_free (recipient_type);
@@ -401,7 +402,7 @@ _add_recipient (CamelMimeMessage *mime_message, gchar *recipient_type, gchar *re
if the existent_list is NULL, then a new GList is
automagically created */
recipients_list = g_list_append (existent_list, (gpointer)recipient);
-
+
if (!existent_list) /* if there was no recipient of this type create the section */
g_hash_table_insert (mime_message->recipients, recipient_type, recipients_list);
else
@@ -458,11 +459,11 @@ _remove_recipient (CamelMimeMessage *mime_message, const gchar *recipient_type,
if (old_element) {
/* if recipient exists, remove it */
new_recipients_list = g_list_remove_link (recipients_list, old_element);
-
+
/* if glist head has changed, fix up hash table */
if (new_recipients_list != recipients_list)
g_hash_table_insert (mime_message->recipients, old_recipient_type, new_recipients_list);
-
+
g_free( (gchar *)(old_element->data));
g_list_free_1 (old_element);
}
@@ -496,18 +497,18 @@ camel_mime_message_get_recipients (CamelMimeMessage *mime_message, const gchar *
static void
_set_flag (CamelMimeMessage *mime_message, const gchar *flag, gboolean value)
{
- gchar old_flags;
- gboolean *ptr_value;
+ gchar *old_flags;
+ gboolean ptr_value;
+
if (! g_hash_table_lookup_extended (mime_message->flags,
flag,
(gpointer)&(old_flags),
(gpointer)&(ptr_value)) ) {
- ptr_value = g_new (gboolean, 1);
- g_hash_table_insert (mime_message->flags, g_strdup (flag), ptr_value);
- }
- *ptr_value = value;
-
+ g_hash_table_insert (mime_message->flags, g_strdup (flag), GINT_TO_POINTER (value));
+ } else
+ g_hash_table_insert (mime_message->flags, old_flags, GINT_TO_POINTER (value));
+
}
void
@@ -523,9 +524,7 @@ camel_mime_message_set_flag (CamelMimeMessage *mime_message, const gchar *flag,
static gboolean
_get_flag (CamelMimeMessage *mime_message, const gchar *flag)
{
- gboolean *value;
- value = (gboolean *)g_hash_table_lookup (mime_message->flags, flag);
- return ( (value) && (*value));
+ return GPOINTER_TO_INT (g_hash_table_lookup (mime_message->flags, flag));
}
gboolean
@@ -543,7 +542,7 @@ _add_flag_to_list (gpointer key, gpointer value, gpointer user_data)
{
GList **flag_list = (GList **)user_data;
gchar *flag_name = (gchar *)key;
-
+
if ((flag_name) && (flag_name[0] != '\0'))
*flag_list = g_list_append (*flag_list, flag_name);
}
@@ -605,7 +604,7 @@ _write_one_recipient_to_stream (gpointer key, gpointer value, gpointer user_data
// gchar *current;
CamelStream *stream = (CamelStream *)user_data;
if (recipient_type)
- write_header_with_glist_to_stream (stream, recipient_type, recipients, ", ");
+ write_header_with_glist_to_stream (stream, recipient_type, recipients, ", ");
}
static void
@@ -642,10 +641,10 @@ _set_recipient_list_from_string (CamelMimeMessage *message, gchar *recipient_typ
GList *recipients_list;
CAMEL_LOG_FULL_DEBUG ("CamelMimeMessage::_set_recipient_list_from_string parsing ##%s##\n", recipients_string);
recipients_list = string_split (
- recipients_string, ',', "\t ",
- STRING_TRIM_STRIP_TRAILING | STRING_TRIM_STRIP_LEADING);
+ recipients_string, ',', "\t ",
+ STRING_TRIM_STRIP_TRAILING | STRING_TRIM_STRIP_LEADING);
g_hash_table_insert (message->recipients, recipient_type, recipients_list);
-
+
}
static gboolean
@@ -658,71 +657,72 @@ _parse_header_pair (CamelMimePart *mime_part, gchar *header_name, gchar *header_
header_type = (CamelHeaderType) g_hash_table_lookup (header_name_table, header_name);
switch (header_type) {
-
+
case HEADER_FROM:
CAMEL_LOG_FULL_DEBUG (
- "CamelMimeMessage::parse_header_pair found HEADER_FROM : %s\n",
- header_value );
-
+ "CamelMimeMessage::parse_header_pair found HEADER_FROM : %s\n",
+ header_value );
+
camel_mime_message_set_from (message, header_value);
header_handled = TRUE;
break;
-
+
case HEADER_REPLY_TO:
CAMEL_LOG_FULL_DEBUG (
- "CamelMimeMessage::parse_header_pair found HEADER_REPLY_YO : %s\n",
- header_value );
-
+ "CamelMimeMessage::parse_header_pair found HEADER_REPLY_YO : %s\n",
+ header_value );
+
camel_mime_message_set_reply_to (message, header_value);
header_handled = TRUE;
break;
-
+
case HEADER_SUBJECT:
CAMEL_LOG_FULL_DEBUG (
- "CamelMimeMessage::parse_header_pair found HEADER_SUBJECT : %s\n",
- header_value );
-
+ "CamelMimeMessage::parse_header_pair found HEADER_SUBJECT : %s\n",
+ header_value );
+
camel_mime_message_set_subject (message, header_value);
header_handled = TRUE;
break;
-
+
case HEADER_TO:
CAMEL_LOG_FULL_DEBUG (
- "CamelMimeMessage::parse_header_pair found HEADER_TO : %s\n",
- header_value );
-
+ "CamelMimeMessage::parse_header_pair found HEADER_TO : %s\n",
+ header_value );
+
_set_recipient_list_from_string (message, "To", header_value);
g_free (header_value);
header_handled = TRUE;
break;
-
+
case HEADER_CC:
CAMEL_LOG_FULL_DEBUG (
- "CamelMimeMessage::parse_header_pair found HEADER_CC : %s\n",
- header_value );
+ "CamelMimeMessage::parse_header_pair found HEADER_CC : %s\n",
+ header_value );
_set_recipient_list_from_string (message, "Cc", header_value);
g_free (header_value);
header_handled = TRUE;
break;
-
+
case HEADER_BCC:
CAMEL_LOG_FULL_DEBUG (
- "CamelMimeMessage::parse_header_pair found HEADER_BCC : %s\n",
- header_value );
+ "CamelMimeMessage::parse_header_pair found HEADER_BCC : %s\n",
+ header_value );
_set_recipient_list_from_string (message, "Bcc", header_value);
g_free (header_value);
header_handled = TRUE;
break;
-
-
+
+
}
if (header_handled) {
g_free (header_name);
return TRUE;
} else
return parent_class->parse_header_pair (mime_part, header_name, header_value);
-
+
}
+
diff --git a/camel/camel-mime-message.h b/camel/camel-mime-message.h
index 522173c765..48e35d8103 100644
--- a/camel/camel-mime-message.h
+++ b/camel/camel-mime-message.h
@@ -75,8 +75,8 @@ struct _CamelMimeMessage
guint message_number; /* set by folder object when retrieving message */
CamelFolder *folder;
CamelSession *session;
-
-} ;
+
+};
diff --git a/camel/providers/MH/camel-mh-folder.c b/camel/providers/MH/camel-mh-folder.c
index a59566958a..4b91d5bc2d 100644
--- a/camel/providers/MH/camel-mh-folder.c
+++ b/camel/providers/MH/camel-mh-folder.c
@@ -52,6 +52,7 @@ static GList *_list_subfolders (CamelFolder *folder);
static CamelMimeMessage *_get_message (CamelFolder *folder, gint number);
static gint _get_message_count (CamelFolder *folder);
static gint _append_message (CamelFolder *folder, CamelMimeMessage *message);
+static GList *_expunge (CamelFolder *folder);
static void
@@ -72,6 +73,7 @@ camel_mh_folder_class_init (CamelMhFolderClass *camel_mh_folder_class)
camel_folder_class->get_message = _get_message;
camel_folder_class->get_message_count = _get_message_count;
camel_folder_class->append_message = _append_message;
+ camel_folder_class->expunge = _expunge;
}
@@ -156,7 +158,8 @@ _set_name (CamelFolder *folder, const gchar *name)
mh_folder->directory_path = g_strdup_printf ("%s%c%s", root_dir_path, separator, folder->full_name);
- CAMEL_LOG_FULL_DEBUG ("CamelMhFolder::set_name mh_folder->directory_path is %s\n", mh_folder->directory_path);
+ CAMEL_LOG_FULL_DEBUG ("CamelMhFolder::set_name mh_folder->directory_path is %s\n",
+ mh_folder->directory_path);
CAMEL_LOG_FULL_DEBUG ("Leaving CamelMhFolder::set_name\n");
}
@@ -286,7 +289,8 @@ _delete_messages (CamelFolder *folder)
unlink_error = unlink(entry_name);
if (unlink_error == -1) {
- CAMEL_LOG_WARNING ("CamelMhFolder::delete_messages Error when deleting file %s\n", entry_name);
+ CAMEL_LOG_WARNING ("CamelMhFolder::delete_messages Error when deleting file %s\n",
+ entry_name);
CAMEL_LOG_FULL_DEBUG ( " Full error text is : %s\n", strerror(errno));
}
}
@@ -303,7 +307,7 @@ _delete_messages (CamelFolder *folder)
static GList *
-_list_subfolders(CamelFolder *folder)
+_list_subfolders (CamelFolder *folder)
{
GList *subfolder_name_list = NULL;
@@ -393,6 +397,13 @@ _message_name_compare (gconstpointer a, gconstpointer b)
return (atoi (m1) - atoi (m2));
}
+static void
+_filename_free (gpointer data)
+{
+ g_free ((gchar *)data);
+}
+
+
/* slow routine, may be optimixed, or we should use
caches if users complain */
static CamelMimeMessage *
@@ -424,7 +435,8 @@ _get_message (CamelFolder *folder, gint number)
while (dir_entry != NULL) {
/* tests if the entry correspond to a message file */
if (_is_a_message_file (dir_entry->d_name, directory_path))
- message_list = g_list_insert_sorted (message_list, g_strdup (dir_entry->d_name), _message_name_compare);
+ message_list = g_list_insert_sorted (message_list, g_strdup (dir_entry->d_name),
+ _message_name_compare);
/* read next entry */
dir_entry = readdir (dir_handle);
}
@@ -435,18 +447,22 @@ _get_message (CamelFolder *folder, gint number)
message_name = g_list_nth_data (message_list, number);
if (message_name != NULL) {
- CAMEL_LOG_FULL_DEBUG ("CanelMhFolder::get_message message number = %d, name = %s\n", number, message_name);
+ 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_fs_new_with_name (message_file_name, CAMEL_STREAM_FS_READ);
- g_free (message_file_name);
+
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), "fullpath",
+ g_strdup (message_file_name), _filename_free);
#warning Set flags and all this stuff here
}
+ g_free (message_file_name);
} else
CAMEL_LOG_FULL_DEBUG ("CanelMhFolder::get_message message number = %d, not found\n", number);
string_list_free (message_list);
@@ -486,6 +502,7 @@ _get_message_count (CamelFolder *folder)
}
closedir (dir_handle);
+ CAMEL_LOG_FULL_DEBUG ("CamelMhFolder::get_message_count found %d messages\n", message_count);
return message_count;
}
@@ -534,14 +551,16 @@ _append_message (CamelFolder *folder, CamelMimeMessage *message)
new_message_number = last_max_message_number + 1;
new_message_filename = g_strdup_printf ("%s/%d", directory_path, new_message_number);
- CAMEL_LOG_FULL_DEBUG ("CamelMhFolder::append_message new message path is %s\n", new_message_filename);
+ CAMEL_LOG_FULL_DEBUG ("CamelMhFolder::append_message new message path is %s\n",
+ new_message_filename);
output_stream = camel_stream_fs_new_with_name (new_message_filename, CAMEL_STREAM_FS_WRITE);
if (output_stream != NULL) {
camel_data_wrapper_write_to_stream (CAMEL_DATA_WRAPPER (message), output_stream);
camel_stream_close (output_stream);
} else {
- CAMEL_LOG_WARNING ("CamelMhFolder::append_message could not open %s for writing\n", new_message_filename);
+ CAMEL_LOG_WARNING ("CamelMhFolder::append_message could not open %s for writing\n",
+ new_message_filename);
CAMEL_LOG_FULL_DEBUG (" Full error text is : %s\n", strerror(errno));
error = TRUE;
}
@@ -551,3 +570,88 @@ _append_message (CamelFolder *folder, CamelMimeMessage *message)
if (error) return -1;
else return new_message_number;
}
+
+
+
+gint
+camel_mime_message_number_cmp (gconstpointer a, gconstpointer b)
+{
+ CamelMimeMessage *m_a = CAMEL_MIME_MESSAGE (a);
+ CamelMimeMessage *m_b = CAMEL_MIME_MESSAGE (b);
+
+ return (m_a->message_number - (m_b->message_number));
+}
+
+
+static GList *
+_expunge (CamelFolder *folder)
+{
+ /* For the moment, we look in the folder active message
+ * list. I did not make my mind for the moment, should
+ * the gtk_object->destroy signal be used to expunge
+ * freed messages objects marked DELETED ?
+ */
+ GList *expunged_list = NULL;
+ CamelMimeMessage *message;
+ GList *message_node;
+ GList *next_message_node;
+ gchar *fullpath;
+ gint unlink_error;
+ guint nb_expunged = 0;
+
+ CAMEL_LOG_FULL_DEBUG ("Entering CamelFolder::expunge\n");
+
+ /* sort message list by ascending message number */
+ if (folder->message_list)
+ folder->message_list = g_list_sort (folder->message_list, camel_mime_message_number_cmp);
+
+ message_node = folder->message_list;
+
+ /* look in folder message list which messages
+ * need to be expunged */
+ while ( message_node) {
+ message = CAMEL_MIME_MESSAGE (message_node->data);
+
+ /* we may free message_node so get the next node now */
+ next_message_node = message_node->next;
+
+ if (message) {
+ CAMEL_LOG_FULL_DEBUG ("CamelMhFolder::expunge, examining message %d\n", message->message_number);
+ if (camel_mime_message_get_flag (message, "DELETED")) {
+ /* expunge the message */
+ fullpath = gtk_object_get_data (GTK_OBJECT (message), "fullpath");
+ CAMEL_LOG_FULL_DEBUG ("CamelMhFolder::expunge, message fullpath is %s\n",
+ fullpath);
+ unlink_error = unlink(fullpath);
+ if (unlink_error != -1) {
+ expunged_list = g_list_append (expunged_list, message);
+ message->expunged = TRUE;
+ /* remove the message from active message list */
+ g_list_remove_link (folder->message_list, message_node);
+ g_list_free_1 (message_node);
+ nb_expunged++;
+ } else {
+ CAMEL_LOG_WARNING ("CamelMhFolder:: could not unlink %s (message %d)\n",
+ fullpath, message->message_number);
+ CAMEL_LOG_FULL_DEBUG (" Full error text is : %s\n", strerror(errno));
+ }
+
+ } else {
+ /* readjust message number */
+ CAMEL_LOG_FULL_DEBUG ("CamelMhFolder:: Readjusting message number %d",
+ message->message_number);
+ message->message_number -= nb_expunged;
+ CAMEL_LOG_FULL_DEBUG (" to %d\n", message->message_number);
+ }
+ }
+ else {
+ CAMEL_LOG_WARNING ("CamelMhFolder::expunge warning message_node contains no message\n");
+
+ }
+ message_node = next_message_node;
+ CAMEL_LOG_FULL_DEBUG ("CamelFolder::expunge, examined message node %p\n", message_node);
+ }
+
+ CAMEL_LOG_FULL_DEBUG ("Leaving CamelFolder::expunge\n");
+ return expunged_list;
+}