{
IMAP_DATA* idata;
HEADER* h;
+ ENVELOPE* newenv;
char buf[LONG_STRING];
char path[_POSIX_PATH_MAX];
char *pc;
* 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. */
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++);
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);