Commit 5bc9461d 5bc9461d147e3d24bbf5f6e793579c021ae198e4 by Sergey Poznyakoff

Add In-Reply-To and References headers to the outgoing message.

1 parent a22fa46f
......@@ -17,6 +17,150 @@
#include "mail.h"
#define DATEBUFSIZE 128
static char *
concat (const char *s1, const char *s2)
{
int len = (s1 ? strlen (s1) : 0) + (s2 ? strlen (s2) : 0) + 2;
char *s = malloc (len);
if (s)
{
char *p = s;
if (s1)
{
strcpy (p, s1);
p += strlen (s1);
*p++ = ' ';
}
if (s2)
strcpy (p, s2);
}
return s;
}
void
make_in_reply_to (compose_env_t *env, message_t msg)
{
char *value, *s1 = NULL, *s2 = NULL;
header_t hdr;
if (message_get_header (msg, &hdr))
return;
if (header_aget_value (hdr, MU_HEADER_DATE, &value))
{
envelope_t envelope = NULL;
value = malloc (DATEBUFSIZE);
if (value)
{
message_get_envelope (msg, &envelope);
envelope_date (envelope, value, DATEBUFSIZE, NULL);
}
}
if (value)
asprintf (&s1, "Your message of %s", value);
if (header_aget_value (hdr, MU_HEADER_MESSAGE_ID, &value) == 0)
{
asprintf (&s2, "\n\t%s", value);
free (value);
}
if (s1 || s2)
{
value = concat (s1, s2);
free (s1);
free (s2);
compose_header_set (env, MU_HEADER_IN_REPLY_TO, value,
COMPOSE_REPLACE);
free (value);
}
}
int
strip_message_id (char *msgid, char **val)
{
address_t addr;
char *p = strchr (msgid, '<');
if (!p)
p = msgid;
if (address_create (&addr, p) == 0)
{
size_t count = 0;
char *p;
address_get_count (addr, &count);
if (count != 1)
{
address_destroy (&addr);
return 1;
}
if (address_aget_email (addr, 1, &p))
return -1;
address_destroy (&addr);
*val = malloc (strlen (p) + 3);
if (!*val)
{
free (p);
return -1;
}
sprintf (*val, "<%s>", p);
free (p);
return 0;
}
return 1;
}
int
get_msgid_header (header_t hdr, const char *name, char **val)
{
char *p;
int status = header_aget_value (hdr, name, &p);
if (status)
return status;
status = strip_message_id (p, val);
free (p);
return status;
}
/* rfc2822:
The "References:" field will contain the contents of the parent's
"References:" field (if any) followed by the contents of the parent's
"Message-ID:" field (if any). If the parent message does not contain
a "References:" field but does have an "In-Reply-To:" field
containing a single message identifier, then the "References:" field
will contain the contents of the parent's "In-Reply-To:" field
followed by the contents of the parent's "Message-ID:" field (if
any). If the parent has none of the "References:", "In-Reply-To:",
or "Message-ID:" fields, then the new message will have no
References:" field. */
void
make_references (compose_env_t *env, message_t msg)
{
char *ref = NULL, *msgid = NULL;
header_t hdr;
if (message_get_header (msg, &hdr))
return;
get_msgid_header (hdr, MU_HEADER_MESSAGE_ID, &msgid);
if (get_msgid_header (hdr, MU_HEADER_REFERENCES, &ref))
get_msgid_header (hdr, MU_HEADER_IN_REPLY_TO, &ref);
if (ref || msgid)
{
char *s = concat (ref, msgid);
free (ref);
free (msgid);
compose_header_set (env, MU_HEADER_REFERENCES, s, COMPOSE_REPLACE);
}
}
/*
* r[eply] [msglist] -- GNU extension
* r[espond] [msglist] -- GNU extension
......@@ -39,7 +183,7 @@ mail_reply (int argc, char **argv)
compose_init (&env);
if (util_get_message (mbox, cursor, &msg, 1))
if (util_get_message (mbox, cursor, &msg, MSG_NODELETED))
return 1;
message_get_header (msg, &hdr);
......@@ -99,6 +243,8 @@ mail_reply (int argc, char **argv)
fprintf (ofile, "Subject: %s\n\n",
compose_header_get (&env, MU_HEADER_SUBJECT, ""));
make_in_reply_to (&env, msg);
make_references (&env, msg);
status = mail_send0 (&env, 0);
compose_destroy (&env);
return status;
......