From d762b979438fbc28cf1cc39b47d046afa69ff30b Mon Sep 17 00:00:00 2001 From: Jeffrey Stedfast Date: Tue, 14 May 2002 23:37:58 +0000 Subject: Fixes bug #24136. 2002-05-14 Jeffrey Stedfast Fixes bug #24136. * providers/imap/camel-imap-folder.c (content_info_get_part_spec): New function to take a CamelMessageContentInfo and generate a part-specification string. (get_content): Stop passing around part_spec strings and use content_info_get_part_spec instead. * camel-folder-summary.c (camel_content_info_dump): Made this into a public debugging function. * providers/imap/camel-imap-utils.c (imap_parse_body): Make sure to set the parent of any message/rfc822 subparts. svn path=/trunk/; revision=16793 --- camel/ChangeLog | 16 +++++ camel/camel-folder-summary.c | 36 +++++----- camel/camel-folder-summary.h | 11 +++- camel/providers/imap/camel-imap-folder.c | 110 ++++++++++++++++++++++++++----- camel/providers/imap/camel-imap-utils.c | 1 + 5 files changed, 137 insertions(+), 37 deletions(-) diff --git a/camel/ChangeLog b/camel/ChangeLog index e9a502ec48..b8253c1448 100644 --- a/camel/ChangeLog +++ b/camel/ChangeLog @@ -1,3 +1,19 @@ +2002-05-14 Jeffrey Stedfast + + Fixes bug #24136. + + * providers/imap/camel-imap-folder.c (content_info_get_part_spec): + New function to take a CamelMessageContentInfo and generate a + part-specification string. + (get_content): Stop passing around part_spec strings and use + content_info_get_part_spec instead. + + * camel-folder-summary.c (camel_content_info_dump): Made this into + a public debugging function. + + * providers/imap/camel-imap-utils.c (imap_parse_body): Make sure + to set the parent of any message/rfc822 subparts. + 2002-05-13 Jeffrey Stedfast * providers/imap/camel-imap-folder.c (imap_get_message): Previous diff --git a/camel/camel-folder-summary.c b/camel/camel-folder-summary.c index 6dd0cddc20..aa5156b9be 100644 --- a/camel/camel-folder-summary.c +++ b/camel/camel-folder-summary.c @@ -2702,34 +2702,35 @@ camel_message_info_set_string (CamelMessageInfo *mi, int type, char *str) } #endif -#if 0 -static void -content_info_dump(CamelMessageContentInfo *ci, int depth) + +void +camel_content_info_dump (CamelMessageContentInfo *ci, int depth) { char *p; - - p = alloca(depth*4+1); - memset(p, ' ', depth*4); - p[depth*4] = 0; - + + p = alloca (depth * 4 + 1); + memset (p, ' ', depth * 4); + p[depth * 4] = 0; + if (ci == NULL) { - printf("%s\n", p); + printf ("%s\n", p); return; } - - printf("%scontent-type: %s/%s\n", p, ci->type->type, ci->type->subtype); - printf("%scontent-transfer-encoding: %s\n", p, ci->encoding); - printf("%scontent-description: %s\n", p, ci->description); - printf("%ssize: %lu\n", p, (unsigned long)ci->size); + + printf ("%scontent-type: %s/%s\n", p, ci->type->type ? ci->type->type : "(null)", + ci->type->subtype ? ci->type->subtype : "(null)"); + printf ("%scontent-transfer-encoding: %s\n", p, ci->encoding ? ci->encoding : "(null)"); + printf ("%scontent-description: %s\n", p, ci->description ? ci->description : "(null)"); + printf ("%ssize: %lu\n", p, (unsigned long) ci->size); ci = ci->childs; while (ci) { - content_info_dump(ci, depth+1); + camel_content_info_dump (ci, depth + 1); ci = ci->next; } } void -message_info_dump(CamelMessageInfo *mi) +camel_message_info_dump (CamelMessageInfo *mi) { if (mi == NULL) { printf("No message?\n"); @@ -2743,6 +2744,5 @@ message_info_dump(CamelMessageInfo *mi) printf("From: %s\n", camel_message_info_from(mi)); printf("UID: %s\n", camel_message_info_uid(mi)); printf("Flags: %04x\n", mi->flags & 0xffff); - content_info_dump(mi->content, 0); + camel_content_info_dump(mi->content, 0); } -#endif diff --git a/camel/camel-folder-summary.h b/camel/camel-folder-summary.h index e94ffe2cfa..7545f2af22 100644 --- a/camel/camel-folder-summary.h +++ b/camel/camel-folder-summary.h @@ -44,10 +44,10 @@ typedef struct _CamelFolderSummaryClass CamelFolderSummaryClass; describe the content structure of the message (if it has any) */ struct _CamelMessageContentInfo { struct _CamelMessageContentInfo *next; - + struct _CamelMessageContentInfo *childs; struct _CamelMessageContentInfo *parent; - + struct _header_content_type *type; char *id; char *description; @@ -333,6 +333,13 @@ void camel_message_info_set_string(CamelMessageInfo *mi, int type, char *str); #define camel_message_info_set_mlist(x, s) (g_free(((CamelMessageInfo *)(x))->mlist),((CamelMessageInfo *)(x))->mlist = (s)) #endif + +/* debugging functions */ + +void camel_content_info_dump (CamelMessageContentInfo *ci, int depth); + +void camel_message_info_dump (CamelMessageInfo *mi); + #ifdef __cplusplus } #endif /* __cplusplus */ diff --git a/camel/providers/imap/camel-imap-folder.c b/camel/providers/imap/camel-imap-folder.c index 67db4b8ce7..f78d38eb35 100644 --- a/camel/providers/imap/camel-imap-folder.c +++ b/camel/providers/imap/camel-imap-folder.c @@ -65,6 +65,8 @@ #include "string-utils.h" +#define d(x) x + /* set to -1 for infinite size */ #define UID_SET_LIMIT (4096) @@ -1477,22 +1479,98 @@ static CamelMimeMessage *get_message (CamelImapFolder *imap_folder, CamelMessageContentInfo *ci, CamelException *ex); +struct _part_spec_stack { + struct _part_spec_stack *parent; + int part; +}; + +static void +part_spec_push (struct _part_spec_stack **stack, int part) +{ + struct _part_spec_stack *node; + + printf ("pushing %d\n", part); + + node = g_new (struct _part_spec_stack, 1); + node->parent = *stack; + node->part = part; + + *stack = node; +} + +static int +part_spec_pop (struct _part_spec_stack **stack) +{ + struct _part_spec_stack *node; + int part; + + g_return_val_if_fail (*stack != NULL, 0); + + node = *stack; + *stack = node->parent; + + part = node->part; + g_free (node); + + return part; +} + +static char * +content_info_get_part_spec (CamelMessageContentInfo *ci) +{ + struct _part_spec_stack *stack = NULL; + CamelMessageContentInfo *node; + char *part_spec, *buf; + size_t len = 1; + int part; + + node = ci; + while (node->parent) { + CamelMessageContentInfo *child; + + child = node->parent->childs; + for (part = 1; child; part++) { + if (child == node) + break; + + child = child->next; + } + + len += (part / 10) + 2; + part_spec_push (&stack, part); + + node = node->parent; + } + + buf = part_spec = g_malloc (len); + part_spec[0] = '\0'; + + while (stack) { + part = part_spec_pop (&stack); + buf += sprintf (buf, "%d%s", part, stack ? "." : ""); + } + + return part_spec; +} + /* Fetch the contents of the MIME part indicated by @ci, which is part * of message @uid in @folder. */ static CamelDataWrapper * get_content (CamelImapFolder *imap_folder, const char *uid, - const char *part_spec, CamelMimePart *part, - CamelMessageContentInfo *ci, CamelException *ex) + CamelMimePart *part, CamelMessageContentInfo *ci, + CamelException *ex) { CamelDataWrapper *content = NULL; CamelStream *stream; - char *child_spec; + char *part_spec; - /* There are three cases: multipart, message/rfc822, and "other" */ + part_spec = content_info_get_part_spec (ci); + /* There are three cases: multipart, message/rfc822, and "other" */ if (header_content_type_is (ci->type, "multipart", "*")) { CamelMultipart *body_mp; + char *child_spec; int speclen, num; body_mp = camel_multipart_new (); @@ -1502,10 +1580,11 @@ get_content (CamelImapFolder *imap_folder, const char *uid, camel_multipart_set_boundary (body_mp, NULL); speclen = strlen (part_spec); - child_spec = g_malloc (speclen + 15); + child_spec = g_malloc (speclen + 16); memcpy (child_spec, part_spec, speclen); if (speclen > 0) child_spec[speclen++] = '.'; + g_free (part_spec); ci = ci->childs; num = 1; @@ -1525,8 +1604,7 @@ get_content (CamelImapFolder *imap_folder, const char *uid, return NULL; } - *(strchr (child_spec + speclen, '.')) = '\0'; - content = get_content (imap_folder, uid, child_spec, part, ci, ex); + content = get_content (imap_folder, uid, part, ci, ex); } if (!stream || !content) { g_free (child_spec); @@ -1545,16 +1623,12 @@ get_content (CamelImapFolder *imap_folder, const char *uid, return (CamelDataWrapper *)body_mp; } else if (header_content_type_is (ci->type, "message", "rfc822")) { - return (CamelDataWrapper *) - get_message (imap_folder, uid, part_spec, ci->childs, ex); + content = (CamelDataWrapper *) get_message (imap_folder, uid, part_spec, ci->childs, ex); + g_free (part_spec); + return content; } else { - if (!ci->parent || header_content_type_is (ci->parent->type, "message", "rfc822")) - child_spec = g_strdup_printf ("%s%s1", part_spec, *part_spec ? "." : ""); - else - child_spec = g_strdup (part_spec); - - content = camel_imap_wrapper_new (imap_folder, ci->type, uid, child_spec, part); - g_free (child_spec); + content = camel_imap_wrapper_new (imap_folder, ci->type, uid, part_spec, part); + g_free (part_spec); return content; } } @@ -1586,7 +1660,7 @@ get_message (CamelImapFolder *imap_folder, const char *uid, return NULL; } - content = get_content (imap_folder, uid, part_spec, CAMEL_MIME_PART (msg), ci, ex); + content = get_content (imap_folder, uid, CAMEL_MIME_PART (msg), ci, ex); if (!content) { camel_object_unref (CAMEL_OBJECT (msg)); return NULL; @@ -1702,6 +1776,8 @@ imap_get_message (CamelFolder *folder, const char *uid, CamelException *ex) camel_imap_response_free (store, response); + d(camel_content_info_dump (mi->content, 0)); + if (!mi->content->type) { /* FETCH returned OK, but we didn't parse a BODY * response. Courier will return invalid BODY diff --git a/camel/providers/imap/camel-imap-utils.c b/camel/providers/imap/camel-imap-utils.c index 617b587397..304ef97448 100644 --- a/camel/providers/imap/camel-imap-utils.c +++ b/camel/providers/imap/camel-imap-utils.c @@ -629,6 +629,7 @@ imap_parse_body (char **body_p, CamelFolder *folder, skip_char (&body, ' '); if (body) strtoul (body, &body, 10); + child->parent = ci; } else if (header_content_type_is (type, "text", "*")) { if (body) strtoul (body, &body, 10); -- cgit v1.2.3