]> granicus.if.org Git - neomutt/commitdiff
Merge full envelope from message fetch into original sparse envelope, instead
authorBrendan Cully <brendan@kublai.com>
Sun, 24 Jul 2005 18:28:36 +0000 (18:28 +0000)
committerBrendan Cully <brendan@kublai.com>
Sun, 24 Jul 2005 18:28:36 +0000 (18:28 +0000)
of replacing it. This should be gentler on the various threading hashes and
may (knock on wood) fix the threading segfault. Threading behaviour is
observably better.

imap/message.c
muttlib.c
protos.h

index 990f156c986a4bbbeae321973c75226528f1a2e2..f3be17d4cd8c01076382649049d2b1731c8e5cbe 100644 (file)
@@ -326,6 +326,7 @@ int imap_fetch_message (MESSAGE *msg, CONTEXT *ctx, int msgno)
 {
   IMAP_DATA* idata;
   HEADER* h;
+  ENVELOPE* newenv;
   char buf[LONG_STRING];
   char path[_POSIX_PATH_MAX];
   char *pc;
@@ -463,23 +464,8 @@ int imap_fetch_message (MESSAGE *msg, CONTEXT *ctx, int msgno)
    * picked up in mutt_read_rfc822_header, we mark the message (and context
    * changed). Another possiblity: ignore Status on IMAP?*/
   read = h->read;
-  /* I hate do this here, since it's so low-level, but I'm not sure where
-   * I can abstract it. Problem: the id and subj hashes lose their keys when
-   * mutt_free_envelope gets called, but keep their spots in the hash. This
-   * confuses threading. Alternatively we could try to merge the new
-   * envelope into the old one. Also messy and lowlevel. */
-  if (ctx->id_hash && h->env->message_id)
-    hash_delete (ctx->id_hash, h->env->message_id, h, NULL);
-  if (ctx->subj_hash && h->env->real_subj)
-    hash_delete (ctx->subj_hash, h->env->real_subj, h, NULL);
-  if (ctx->thread_hash && h->env->message_id)
-    hash_delete (ctx->thread_hash, h->env->message_id, NULL, NULL);
-  mutt_free_envelope (&h->env);
-  h->env = mutt_read_rfc822_header (msg->fp, h, 0, 0);
-  if (ctx->id_hash && h->env->message_id)
-    hash_insert (ctx->id_hash, h->env->message_id, h, 0);
-  if (ctx->subj_hash && h->env->real_subj)
-    hash_insert (ctx->subj_hash, h->env->real_subj, h, 1);
+  newenv = mutt_read_rfc822_header (msg->fp, h, 0, 0);
+  mutt_merge_envelopes(h->env, &newenv);
 
   /* see above. We want the new status in h->read, so we unset it manually
    * and let mutt_set_flag set it correctly, updating context. */
index a86bdd6b5fed55f1700fd152194e1c15aba5781b..89669d6bed5f1e99d9a5238bffbe72411d1e5fd2 100644 (file)
--- a/muttlib.c
+++ b/muttlib.c
@@ -673,6 +673,49 @@ void mutt_free_envelope (ENVELOPE **p)
   FREE (p);
 }
 
+/* move all the headers from extra not present in base into base */
+void mutt_merge_envelopes(ENVELOPE* base, ENVELOPE** extra)
+{
+  /* copies each existing element if necessary, and sets the element
+  * to NULL in the source so that mutt_free_envelope doesn't leave us
+  * with dangling pointers. */
+#define MOVE_ELEM(h) if (!base->h) { base->h = (*extra)->h; (*extra)->h = NULL; }
+  MOVE_ELEM(return_path);
+  MOVE_ELEM(from);
+  MOVE_ELEM(to);
+  MOVE_ELEM(cc);
+  MOVE_ELEM(bcc);
+  MOVE_ELEM(sender);
+  MOVE_ELEM(reply_to);
+  MOVE_ELEM(mail_followup_to);
+  MOVE_ELEM(list_post);
+  MOVE_ELEM(subject);
+  MOVE_ELEM(real_subj);
+  MOVE_ELEM(message_id);
+  MOVE_ELEM(supersedes);
+  MOVE_ELEM(date);
+  MOVE_ELEM(x_label);
+  MOVE_ELEM(references);
+  MOVE_ELEM(in_reply_to);
+  /* real_subj is subordinate to subject */
+  if (!base->subject)
+  {
+    base->subject = (*extra)->subject;
+    base->real_subj = (*extra)->real_subj;
+    (*extra)->subject = NULL;
+    (*extra)->real_subj = NULL;
+  }
+  /* spam and user headers should never be hashed, and the new envelope may
+    * have better values. Use new versions regardless. */
+  mutt_buffer_free (&base->spam);
+  mutt_free_list (&base->userhdrs);
+  MOVE_ELEM(spam);
+  MOVE_ELEM(userhdrs);
+#undef MOVE_ELEM
+  
+  mutt_free_envelope(extra);
+}
+
 void _mutt_mktemp (char *s, const char *src, int line)
 {
   snprintf (s, _POSIX_PATH_MAX, "%s/mutt-%s-%d-%d-%d", NONULL (Tempdir), NONULL(Hostname), (int) getuid(), (int) getpid (), Counter++);
index 5dcb72737ecff2fe7bf7c485f7769e81703ddbca..9826e0b42dd3ced2a06d5e630f85fbedb66ed868 100644 (file)
--- a/protos.h
+++ b/protos.h
@@ -211,6 +211,7 @@ void mutt_make_forward_subject (ENVELOPE *env, CONTEXT *ctx, HEADER *cur);
 void mutt_make_help (char *, size_t, char *, int, int);
 void mutt_make_misc_reply_headers (ENVELOPE *env, CONTEXT *ctx, HEADER *cur, ENVELOPE *curenv);
 void mutt_make_post_indent (CONTEXT *ctx, HEADER *cur, FILE *out);
+void mutt_merge_envelopes(ENVELOPE* base, ENVELOPE** extra);
 void mutt_message_to_7bit (BODY *, FILE *);
 #define mutt_mktemp(a) _mutt_mktemp (a, __FILE__, __LINE__)
 void _mutt_mktemp (char *, const char *, int);