diff options
Diffstat (limited to 'camel')
-rw-r--r-- | camel/camel-folder.c | 27 | ||||
-rw-r--r-- | camel/camel-mime-message.c | 108 | ||||
-rw-r--r-- | camel/camel-mime-message.h | 4 | ||||
-rw-r--r-- | camel/providers/MH/camel-mh-folder.c | 120 |
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; +} |