From 941a7e5a30f2a35eea69974a45fc516a4b3d5397 Mon Sep 17 00:00:00 2001 From: Jeffrey Stedfast Date: Thu, 6 Jul 2000 20:52:41 +0000 Subject: Parse for more header information to allow message threading in IMAP. 2000-07-06 Jeffrey Stedfast * providers/imap/camel-imap-folder.c (imap_get_summary): Parse for more header information to allow message threading in IMAP. (imap_get_message_info): Same. * camel-folder-summary.c: Renamed summary_format_* to camel_summary_format_* and moved them into public scope. svn path=/trunk/; revision=3925 --- camel/ChangeLog | 7 ++ camel/camel-folder-summary.c | 16 +-- camel/camel-folder-summary.h | 4 + camel/providers/imap/camel-imap-folder.c | 186 ++++++++++++++++++++++++++----- 4 files changed, 178 insertions(+), 35 deletions(-) diff --git a/camel/ChangeLog b/camel/ChangeLog index a723b43f58..b9dfd30f4c 100644 --- a/camel/ChangeLog +++ b/camel/ChangeLog @@ -1,5 +1,12 @@ 2000-07-06 Jeffrey Stedfast + * providers/imap/camel-imap-folder.c (imap_get_summary): Parse for + more header information to allow message threading in IMAP. + (imap_get_message_info): Same. + + * camel-folder-summary.c: Renamed summary_format_* to + camel_summary_format_* and moved them into public scope. + * providers/smtp/camel-smtp-transport.c (smtp_connect): Oops. Don't pass port # as a string in the error code (if it fails to connect). diff --git a/camel/camel-folder-summary.c b/camel/camel-folder-summary.c index 18605fb551..1558616653 100644 --- a/camel/camel-folder-summary.c +++ b/camel/camel-folder-summary.c @@ -906,8 +906,8 @@ static CamelMessageContentInfo * content_info_new_from_parser(CamelFolderSummary return ci; } -static char * -summary_format_address(struct _header_raw *h, const char *name) +char * +camel_summary_format_address(struct _header_raw *h, const char *name) { struct _header_address *addr; const char *text; @@ -924,8 +924,8 @@ summary_format_address(struct _header_raw *h, const char *name) return ret; } -static char * -summary_format_string(struct _header_raw *h, const char *name) +char * +camel_summary_format_string(struct _header_raw *h, const char *name) { const char *text; @@ -947,10 +947,10 @@ message_info_new(CamelFolderSummary *s, struct _header_raw *h) mi = g_malloc0(s->message_info_size); - mi->subject = summary_format_string(h, "subject"); - mi->from = summary_format_address(h, "from"); - mi->to = summary_format_address(h, "to"); - mi->cc = summary_format_address(h, "cc"); + mi->subject = camel_summary_format_string(h, "subject"); + mi->from = camel_summary_format_address(h, "from"); + mi->to = camel_summary_format_address(h, "to"); + mi->cc = camel_summary_format_address(h, "cc"); mi->user_flags = NULL; mi->date_sent = header_decode_date(header_raw_find(&h, "date", NULL), NULL); received = header_raw_find(&h, "received", NULL); diff --git a/camel/camel-folder-summary.h b/camel/camel-folder-summary.h index 50563f9ca7..d7f20962c4 100644 --- a/camel/camel-folder-summary.h +++ b/camel/camel-folder-summary.h @@ -194,6 +194,10 @@ CamelMessageInfo *camel_folder_summary_uid(CamelFolderSummary *, const char *uid /* shift content ... */ void camel_folder_summary_offset_content(CamelMessageContentInfo *content, off_t offset); +/* summary formatting utils */ +char *camel_summary_format_address (struct _header_raw *h, const char *name); +char *camel_summary_format_string (struct _header_raw *h, const char *name); + /* summary file loading/saving helper functions */ int camel_folder_summary_encode_fixed_int32(FILE *, gint32); int camel_folder_summary_decode_fixed_int32(FILE *, gint32 *); diff --git a/camel/providers/imap/camel-imap-folder.c b/camel/providers/imap/camel-imap-folder.c index 0b997225b9..baa38315c7 100644 --- a/camel/providers/imap/camel-imap-folder.c +++ b/camel/providers/imap/camel-imap-folder.c @@ -197,9 +197,12 @@ imap_finalize (GtkObject *object) for (i = 0; i < max; i++) { info = g_ptr_array_index (imap_folder->summary, i); g_free (info->subject); - g_free (info->to); g_free (info->from); + g_free (info->to); + g_free (info->cc); g_free (info->uid); + g_free (info->message_id); + header_references_list_clear (&info->references); g_free (info); info = NULL; } @@ -492,6 +495,8 @@ imap_append_message (CamelFolder *folder, CamelMimeMessage *message, CamelExcept return; } + /* FIXME: we should close/free the mem stream */ + g_free (result); g_free (folder_path); } @@ -928,7 +933,7 @@ get_header_field (gchar *header, gchar *field) /* it may be wrapped on multiple lines, so lets strip out \n's */ for (p = part; *p; ) { if (*p == '\r' || *p == '\n') - memmove(p, p + 1, strlen (p) - 1); + memmove (p, p + 1, strlen (p) - 1); else p++; } @@ -936,14 +941,20 @@ get_header_field (gchar *header, gchar *field) return part; } +static char *header_fields[] = { "subject", "from", "to", "cc", "date", + "received", "message-id", "references", + "in-reply-to", "" }; + GPtrArray * imap_get_summary (CamelFolder *folder, CamelException *ex) { CamelImapFolder *imap_folder = CAMEL_IMAP_FOLDER (folder); GPtrArray *array = NULL; CamelMessageInfo *info; - gint num, i = 0, status = 0; - char *result, *datestr, *p, *q; + gint num, i, j, status = 0; + char *result, *p, *q; + const char *received; + struct _header_raw *h, *tail = NULL; if (imap_folder->summary) return imap_folder->summary; @@ -967,17 +978,67 @@ imap_get_summary (CamelFolder *folder, CamelException *ex) g_free (result); break; } - + + /* construct the header list */ + h = NULL; + for (j = 0; *header_fields[j]; j++) { + struct _header_raw *raw; + char *field, *value; + + field = g_strdup_printf ("\n%s:", header_fields[j]); + value = get_header_field (result, field); + g_free (field); + if (!value) + continue; + + raw = g_malloc0 (sizeof (struct _header_raw)); + raw->next = NULL; + raw->name = g_strdup (header_fields[j]); + raw->value = value; + raw->offset = -1; + + if (!h) { + h = raw; + tail = h; + } else { + tail->next = raw; + tail = raw; + } + } + + /* construct the CamelMessageInfo */ info = g_malloc0 (sizeof (CamelMessageInfo)); - info->subject = get_header_field (result, "\nSubject:"); - info->to = get_header_field (result, "\nTo:"); - info->from = get_header_field (result, "\nFrom:"); + info->subject = camel_summary_format_string (h, "subject"); + info->from = camel_summary_format_address (h, "from"); + info->to = camel_summary_format_address (h, "to"); + info->cc = camel_summary_format_address (h, "cc"); + info->user_flags = NULL; + info->date_sent = header_decode_date (header_raw_find (&h, "date", NULL), NULL); + received = header_raw_find (&h, "received", NULL); + if (received) + received = strrchr (received, ';'); + if (received) + info->date_received = header_decode_date (received + 1, NULL); + else + info->date_received = 0; + info->message_id = header_msgid_decode (header_raw_find (&h, "message-id", NULL)); + /* if we have a references, use that, otherwise, see if we have an in-reply-to + header, with parsable content, otherwise *shrug* */ + info->references = header_references_decode (header_raw_find (&h, "references", NULL)); + if (info->references == NULL) + info->references = header_references_decode (header_raw_find (&h, "in-reply-to", NULL)); - datestr = get_header_field (result, "\nDate:"); - info->date_sent = header_decode_date (datestr, NULL); - g_free (datestr); g_free (result); + while (h->next) { + struct _header_raw *next = h->next; + + g_free (h->name); + g_free (h->value); + g_free (h); + h = next; + } + /* now to get the UID */ status = camel_imap_command_extended (CAMEL_IMAP_STORE (folder->parent_store), folder, &result, "FETCH %d UID", i); @@ -993,8 +1054,11 @@ imap_get_summary (CamelFolder *folder, CamelException *ex) g_free (result); g_free (info->subject); - g_free (info->to); g_free (info->from); + g_free (info->to); + g_free (info->cc); + g_free (info->message_id); + header_references_list_clear (&info->references); g_free (info); info = NULL; @@ -1006,8 +1070,11 @@ imap_get_summary (CamelFolder *folder, CamelException *ex) fprintf (stderr, "Warning: UID for message %d not found\n", i); g_free (info->subject); - g_free (info->to); g_free (info->from); + g_free (info->to); + g_free (info->cc); + g_free (info->message_id); + header_references_list_clear (&info->references); g_free (info); info = NULL; @@ -1020,8 +1087,11 @@ imap_get_summary (CamelFolder *folder, CamelException *ex) fprintf (stderr, "Warning: UID for message %d not found\n", i); g_free (info->subject); - g_free (info->to); g_free (info->from); + g_free (info->to); + g_free (info->cc); + g_free (info->message_id); + header_references_list_clear (&info->references); g_free (info); info = NULL; @@ -1049,8 +1119,12 @@ imap_get_summary (CamelFolder *folder, CamelException *ex) g_free (result); g_free (info->subject); - g_free (info->to); g_free (info->from); + g_free (info->to); + g_free (info->cc); + g_free (info->message_id); + g_free (info->uid); + header_references_list_clear (&info->references); g_free (info); info = NULL; @@ -1062,8 +1136,12 @@ imap_get_summary (CamelFolder *folder, CamelException *ex) fprintf (stderr, "Warning: FLAGS for message %d not found\n", i); g_free (info->subject); - g_free (info->to); g_free (info->from); + g_free (info->to); + g_free (info->cc); + g_free (info->message_id); + g_free (info->uid); + header_references_list_clear (&info->references); g_free (info); info = NULL; @@ -1076,8 +1154,12 @@ imap_get_summary (CamelFolder *folder, CamelException *ex) fprintf (stderr, "Warning: FLAGS for message %d not found\n", i); g_free (info->subject); - g_free (info->to); g_free (info->from); + g_free (info->to); + g_free (info->cc); + g_free (info->message_id); + g_free (info->uid); + header_references_list_clear (&info->references); g_free (info); info = NULL; @@ -1120,8 +1202,10 @@ imap_get_message_info (CamelFolder *folder, const char *uid) { CamelImapFolder *imap_folder = CAMEL_IMAP_FOLDER (folder); CamelMessageInfo *info = NULL; - char *result, *datestr, *p; - int status; + struct _header_raw *h, *tail = NULL; + const char *received; + char *result, *p; + int j, status; /* lets first check to see if we have the message info cached */ if (imap_folder->summary) { @@ -1130,7 +1214,7 @@ imap_get_message_info (CamelFolder *folder, const char *uid) max = imap_folder->summary->len; for (i = 0; i < max; i++) { info = g_ptr_array_index (imap_folder->summary, i); - if (!strcmp(info->uid, uid)) + if (!strcmp (info->uid, uid)) return info; } } @@ -1145,18 +1229,66 @@ imap_get_message_info (CamelFolder *folder, const char *uid) return NULL; } - info = g_malloc0 (sizeof (CamelMessageInfo)); - info->subject = get_header_field (result, "\nSubject:"); - info->to = get_header_field (result, "\nTo:"); - info->from = get_header_field (result, "\nFrom:"); + h = NULL; + for (j = 0; *header_fields[j]; j++) { + struct _header_raw *raw; + char *field, *value; + + field = g_strdup_printf ("\n%s:", header_fields[j]); + value = get_header_field (result, field); + g_free (field); + if (!value) + continue; + + raw = g_malloc0 (sizeof (struct _header_raw)); + raw->next = NULL; + raw->name = g_strdup (header_fields[j]); + raw->value = value; + raw->offset = -1; + + if (!h) { + h = raw; + tail = h; + } else { + tail->next = raw; + tail = raw; + } + } - datestr = get_header_field (result, "\nDate:"); - info->date_sent = header_decode_date (datestr, NULL); - g_free (datestr); + /* construct the CamelMessageInfo */ + info = g_malloc0 (sizeof (CamelMessageInfo)); + info->subject = camel_summary_format_string (h, "subject"); + info->from = camel_summary_format_address (h, "from"); + info->to = camel_summary_format_address (h, "to"); + info->cc = camel_summary_format_address (h, "cc"); + info->user_flags = NULL; + info->date_sent = header_decode_date (header_raw_find (&h, "date", NULL), NULL); + received = header_raw_find (&h, "received", NULL); + if (received) + received = strrchr (received, ';'); + if (received) + info->date_received = header_decode_date (received + 1, NULL); + else + info->date_received = 0; + info->message_id = header_msgid_decode (header_raw_find (&h, "message-id", NULL)); + /* if we have a references, use that, otherwise, see if we have an in-reply-to + header, with parsable content, otherwise *shrug* */ + info->references = header_references_decode (header_raw_find (&h, "references", NULL)); + if (info->references == NULL) + info->references = header_references_decode (header_raw_find (&h, "in-reply-to", NULL)); info->uid = g_strdup (uid); g_free (result); + while (h->next) { + struct _header_raw *next = h->next; + + g_free (h->name); + g_free (h->value); + g_free (h); + h = next; + } + /* now to get the flags */ status = camel_imap_command_extended (CAMEL_IMAP_STORE (folder->parent_store), folder, &result, "UID FETCH %s FLAGS", uid); -- cgit v1.2.3