WHERE char *ImapPass INITVAL (NULL);
WHERE char *ImapUser INITVAL (NULL);
#endif
-WHERE char *InReplyTo;
WHERE char *Inbox;
WHERE char *Ispell;
WHERE char *Locale;
** message to which you are replying. You are strongly encouraged not to
** change this value, as it tends to agitate the more fanatical netizens.
*/
- { "in_reply_to", DT_STR, R_NONE, UL &InReplyTo, UL "%i; from %a on %{!%a, %b %d, %Y at %I:%M:%S%p %Z}" },
- /*
- ** .pp
- ** This specifies the format of the \fIIn-Reply-To\fP header field
- ** added when replying to a message. For a full listing of
- ** defined escape sequences, see the section on $$index_format.
- ** .pp
- ** \fBNote:\fP Don't use any sequences in this format string which
- ** may include 8-bit characters. Using such escape sequences may
- ** lead to bad headers.
- */
{ "indent_str", DT_SYN, R_NONE, UL "indent_string", 0 },
/*
*/
char *date;
char *x_label;
LIST *references; /* message references (in reverse order) */
+ LIST *in_reply_to; /* in-reply-to header content */
LIST *userhdrs; /* user defined headers */
} ENVELOPE;
}
int mutt_parse_rfc822_line (ENVELOPE *e, HEADER *hdr, char *line, char *p, short user_hdrs, short weed,
- short do_2047, LIST **lastp, char **in_reply_to)
+ short do_2047, LIST **lastp)
{
int matched = 0;
LIST *last = NULL;
case 'i':
if (!mutt_strcasecmp (line+1, "n-reply-to"))
{
- if (hdr && in_reply_to)
- {
- mutt_str_replace (in_reply_to, p);
- if (do_2047)
- rfc2047_decode (in_reply_to);
- }
+ mutt_free_list (&e->in_reply_to);
+ e->in_reply_to = mutt_parse_references (p);
+ matched = 1;
}
break;
LIST *last = NULL;
char *line = safe_malloc (LONG_STRING);
char *p;
- char *in_reply_to = 0;
long loc;
int matched;
size_t linelen = LONG_STRING;
if (!*p)
continue; /* skip empty header fields */
- matched = mutt_parse_rfc822_line (e, hdr, line, p, user_hdrs, weed, 1, &last, &in_reply_to);
+ matched = mutt_parse_rfc822_line (e, hdr, line, p, user_hdrs, weed, 1, &last);
}
hdr->content->hdr_offset = hdr->offset;
hdr->content->offset = ftell (f);
- /* if an in-reply-to was given, check to see if it is in the references
- * list already. if not, add it so we can do a better job of threading.
- */
- if (in_reply_to && (p = extract_message_id (in_reply_to)) != NULL)
- {
- if (!e->references ||
- (e->references && mutt_strcmp (e->references->data, p) != 0))
- {
- LIST *tmp = mutt_new_list ();
-
- tmp->data = p;
- tmp->next = e->references;
- e->references = tmp;
- }
- else
- safe_free ((void **) &p);
- }
-
/* do RFC2047 decoding */
rfc2047_decode_adrlist (e->from);
rfc2047_decode_adrlist (e->to);
}
}
- safe_free ((void *) &in_reply_to);
return (e);
}
int mutt_parse_push (BUFFER *, BUFFER *, unsigned long, BUFFER *);
int mutt_parse_rc_line (/* const */ char *, BUFFER *, BUFFER *);
int mutt_parse_rfc822_line (ENVELOPE *e, HEADER *hdr, char *line, char *p, short user_hdrs, short weed,
- short do_2047, LIST **lastp, char **in_reply_to);
+ short do_2047, LIST **lastp);
int mutt_parse_score (BUFFER *, BUFFER *, unsigned long, BUFFER *);
int mutt_parse_unscore (BUFFER *, BUFFER *, unsigned long, BUFFER *);
int mutt_parse_unhook (BUFFER *, BUFFER *, unsigned long, BUFFER *);
void mutt_make_misc_reply_headers (ENVELOPE *env, CONTEXT *ctx,
HEADER *cur, ENVELOPE *curenv)
{
- LIST *tmp;
- char buffer[STRING];
-
if (curenv->real_subj)
{
env->subject = safe_malloc (mutt_strlen (curenv->real_subj) + 5);
else
env->subject = safe_strdup ("Re: your mail");
- /* add the In-Reply-To field */
- if (InReplyTo)
+}
+
+static void
+mutt_make_reference_headers (ENVELOPE *curenv, ENVELOPE *env, CONTEXT *ctx)
+{
+ HEADER *h;
+ LIST **p, **q;
+ int i;
+
+ if (!curenv)
{
- strfcpy (buffer, "In-Reply-To: ", sizeof (buffer));
- mutt_make_string (buffer + 13, sizeof (buffer) - 13, InReplyTo, ctx, cur);
- tmp = env->userhdrs;
- while (tmp && tmp->next)
- tmp = tmp->next;
- if (tmp)
+ env->references = NULL;
+ env->in_reply_to = NULL;
+ p = &env->references;
+ q = &env->in_reply_to;
+
+ for(i = 0; i < ctx->vcount; i++)
{
- tmp->next = mutt_new_list ();
- tmp = tmp->next;
+ while(*p) p = &(*p)->next;
+ while (*q) q = &(*q)->next;
+
+ h = ctx->hdrs[ctx->v2r[i]];
+ if(h->tagged)
+ {
+ *p = mutt_make_references(h->env);
+ if (h->env->message_id)
+ {
+ *q = mutt_new_list ();
+ (*q)->data = safe_strdup (h->env->message_id);
+ }
+ }
}
- else
- tmp = env->userhdrs = mutt_new_list ();
- tmp->data = safe_strdup (buffer);
+ }
+ else
+ {
+ env->references = mutt_make_references (curenv);
+ env->in_reply_to = mutt_new_list ();
+ env->in_reply_to->data = safe_strdup (curenv->message_id);
}
}
mutt_fix_reply_recipients (env);
mutt_make_misc_reply_headers (env, ctx, cur, curenv);
-
- if(tag)
- {
- HEADER *h;
- LIST **p;
-
- env->references = NULL;
- p = &env->references;
-
- for(i = 0; i < ctx->vcount; i++)
- {
- while(*p) p = &(*p)->next;
- h = ctx->hdrs[ctx->v2r[i]];
- if(h->tagged)
- *p = mutt_make_references(h->env);
- }
- }
- else
- env->references = mutt_make_references(curenv);
-
+ mutt_make_reference_headers (tag ? NULL : curenv, env, ctx);
}
else if (flags & SENDFORWARD)
mutt_make_forward_subject (env, ctx, cur);
mutt_write_mime_header (attach, fp);
}
+ if (env->in_reply_to)
+ {
+ fputs ("In-Reply-To:", fp);
+ write_references (env->in_reply_to, fp);
+ fputc ('\n', fp);
+ }
+
if (mode == 0 && !privacy && option (OPTXMAILER))
{
/* Add a vanity header */
-/*
- * WORK IN PROGRESS ALERT: Daniel Eisenbud <daniel@math.berkeley.edu>
- * is currently working on this code. Contact him before working on it!
- */
-
/*
* Copyright (C) 1996-2000 Michael R. Elkins <me@cs.hmc.edu>
*
* to find the most recent message to which "cur" refers itself.
*/
-static HEADER *find_reference (HEADER *cur, CONTEXT *ctx)
+static HEADER *find_ref (LIST *refs, HEADER *cur, CONTEXT *ctx)
{
- LIST *refs = cur->env->references;
HEADER *ptr;
for (; refs; refs = refs->next)
/* ups, this message is in a reference loop. bad. */
if (cur->env->message_id && !strcmp (cur->env->message_id, refs->data))
continue;
-
+
if ((ptr = hash_find (ctx->id_hash, refs->data)))
{
if (is_descendant (ptr, cur))
return NULL;
}
+/*
+ * In-Reply-To contains the direct parents according to RFC 2822.
+ * References is second best, since it may contain indirect parents,
+ * too.
+ */
+
+static HEADER *find_reference (HEADER *cur, CONTEXT *ctx)
+{
+ HEADER *ptr;
+
+ if ((ptr = find_ref (cur->env->in_reply_to, cur, ctx)))
+ return ptr;
+ if ((ptr = find_ref (cur->env->references, cur, ctx)))
+ return ptr;
+
+ return NULL;
+}
+
/* Determines whether to display a message's subject. */
static int need_display_subject (CONTEXT *ctx, HEADER *tree)
{
return top;
}
+static int matches_in_reply_to (HEADER *t, const char *p)
+{
+ LIST *irt;
+
+ for (irt = t->env->in_reply_to; irt; irt = irt->next)
+ if (mutt_strcmp (irt->data, p) == 0)
+ return 1;
+
+ return 0;
+}
+
static void move_descendants (HEADER **tree, HEADER *cur, sort_t *usefunc)
{
HEADER *ptr, *tmp = *tree;
while (tmp)
{
- /* only need to look at the last reference */
- if (tmp->env->references &&
- mutt_strcmp (tmp->env->references->data, cur->env->message_id) == 0)
+ /* Look at the entire in-reply-to header, and at the last (!) reference. */
+ if (matches_in_reply_to (tmp, cur->env->message_id) ||
+ (tmp->env->references && mutt_strcmp (tmp->env->references->data, cur->env->message_id) == 0))
{
/* remove message from current location */
unlink_message (tree, tmp);
scratch[taglen] = '\0';
value = &scratch[taglen+1];
SKIPWS (value);
- mutt_parse_rfc822_line (e, NULL, scratch, value, 1, 0, 0, &last, NULL);
+ mutt_parse_rfc822_line (e, NULL, scratch, value, 1, 0, 0, &last);
}
}