summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorJeremy Harris <jgh146exb@wizmail.org>2019-10-02 14:49:55 +0100
committerJeremy Harris <jgh146exb@wizmail.org>2019-10-02 14:50:40 +0100
commitd6c829b9a350f61c98196768e3260beb3cbecbfe (patch)
tree4cf6f1a50ad350b68948a2b8de37ff1f2c8fc711 /src
parent218a6f15f24e2925c66c4855b4d255e1a11c7911 (diff)
DSN: add References: header. Bug 2452
Diffstat (limited to 'src')
-rw-r--r--src/src/deliver.c18
-rw-r--r--src/src/functions.h1
-rw-r--r--src/src/moan.c84
-rw-r--r--src/src/transports/autoreply.c47
4 files changed, 94 insertions, 56 deletions
diff --git a/src/src/deliver.c b/src/src/deliver.c
index 72751c2dc..7433b5fb2 100644
--- a/src/src/deliver.c
+++ b/src/src/deliver.c
@@ -7344,7 +7344,7 @@ if (addr_senddsn)
if (pid < 0) /* Creation of child failed */
{
log_write(0, LOG_MAIN|LOG_PANIC_DIE, "Process %d (parent %d) failed to "
- "create child process to send failure message: %s", getpid(),
+ "create child process to send success-dsn message: %s", getpid(),
getppid(), strerror(errno));
DEBUG(D_deliver) debug_printf("DSN: child_open_exim failed\n");
@@ -7357,7 +7357,7 @@ if (addr_senddsn)
transport_ctx tctx = {{0}};
DEBUG(D_deliver)
- debug_printf("sending error message to: %s\n", sender_address);
+ debug_printf("sending success-dsn to: %s\n", sender_address);
/* build unique id for MIME boundary */
bound = string_sprintf(TIME_T_FMT "-eximdsn-%d", time(NULL), rand());
@@ -7369,8 +7369,11 @@ if (addr_senddsn)
moan_write_from(f);
fprintf(f, "Auto-Submitted: auto-generated\n"
"To: %s\n"
- "Subject: Delivery Status Notification\n"
- "Content-Type: multipart/report; report-type=delivery-status; boundary=%s\n"
+ "Subject: Delivery Status Notification\n",
+ sender_address);
+ moan_write_references(f, NULL);
+ fprintf(f, "Content-Type: multipart/report;"
+ " report-type=delivery-status; boundary=%s\n"
"MIME-Version: 1.0\n\n"
"--%s\n"
@@ -7378,7 +7381,7 @@ if (addr_senddsn)
"This message was created automatically by mail delivery software.\n"
" ----- The following addresses had successful delivery notifications -----\n",
- sender_address, bound, bound);
+ bound, bound);
for (address_item * a = addr_senddsn; a; a = a->next)
fprintf(f, "<%s> (relayed %s)\n\n",
@@ -7607,6 +7610,7 @@ while (addr_failed)
fprintf(fp, "Auto-Submitted: auto-replied\n");
moan_write_from(fp);
fprintf(fp, "To: %s\n", bounce_recipient);
+ moan_write_references(fp, NULL);
/* generate boundary string and output MIME-Headers */
bound = string_sprintf(TIME_T_FMT "-eximdsn-%d", time(NULL), rand());
@@ -8192,7 +8196,8 @@ else if (addr_defer != (address_item *)(+1))
DEBUG(D_deliver)
{
- debug_printf("time on queue = %s id %s addr %s\n", readconf_printtime(queue_time), message_id, addr_defer->address);
+ debug_printf("time on queue = %s id %s addr %s\n",
+ readconf_printtime(queue_time), message_id, addr_defer->address);
debug_printf("warning counts: required %d done %d\n", count,
warning_count);
}
@@ -8230,6 +8235,7 @@ else if (addr_defer != (address_item *)(+1))
fprintf(f, "Auto-Submitted: auto-replied\n");
moan_write_from(f);
fprintf(f, "To: %s\n", recipients);
+ moan_write_references(f, NULL);
/* generated boundary string and output MIME-Headers */
bound = string_sprintf(TIME_T_FMT "-eximdsn-%d", time(NULL), rand());
diff --git a/src/src/functions.h b/src/src/functions.h
index 31c005773..d99f15465 100644
--- a/src/src/functions.h
+++ b/src/src/functions.h
@@ -335,6 +335,7 @@ extern void moan_tell_someone(uschar *, address_item *,
const uschar *, const char *, ...) PRINTF_FUNCTION(4,5);
extern BOOL moan_to_sender(int, error_block *, header_line *, FILE *, BOOL);
extern void moan_write_from(FILE *);
+extern void moan_write_references(FILE *, uschar *);
extern FILE *modefopen(const uschar *, const char *, mode_t);
extern int open_cutthrough_connection( address_item * addr );
diff --git a/src/src/moan.c b/src/src/moan.c
index f6cda37f2..31d033c1a 100644
--- a/src/src/moan.c
+++ b/src/src/moan.c
@@ -28,7 +28,7 @@ Returns: nothing
void
moan_write_from(FILE *f)
{
-uschar *s = expand_string(dsn_from);
+uschar * s = expand_string(dsn_from);
if (!s)
{
log_write(0, LOG_MAIN|LOG_PANIC,
@@ -41,6 +41,80 @@ fprintf(f, "From: %s\n", s);
/*************************************************
+* Write References: line for DSN *
+*************************************************/
+
+/* Generate a References: header if there is in the header_list
+at least one of Message-ID:, References:, or In-Reply-To: (see RFC 2822).
+
+Arguments: f the FILE to write to
+ message_id optional already-found message-id, or NULL
+
+Returns: nothing
+*/
+
+void
+moan_write_references(FILE * fp, uschar * message_id)
+{
+header_line * h;
+
+if (!message_id)
+ for (h = header_list; h; h = h->next)
+ if (h->type == htype_id)
+ {
+ message_id = Ustrchr(h->text, ':') + 1;
+ while (isspace(*message_id)) message_id++;
+ }
+
+for (h = header_list; h; h = h->next)
+ if (h->type != htype_old && strncmpic(US"References:", h->text, 11) == 0)
+ break;
+
+if (!h)
+ for (h = header_list; h; h = h->next)
+ if (h->type != htype_old && strncmpic(US"In-Reply-To:", h->text, 12) == 0)
+ break;
+
+/* We limit the total length of references. Although there is no fixed
+limit, some systems do not like headers growing beyond recognition.
+Keep the first message ID for the thread root and the last few for
+the position inside the thread, up to a maximum of 12 altogether. */
+
+if (h || message_id)
+ {
+ fprintf(fp, "References:");
+ if (h)
+ {
+ uschar * s, * id, * error;
+ uschar * referenced_ids[12];
+ int reference_count = 0;
+
+ s = Ustrchr(h->text, ':') + 1;
+ f.parse_allow_group = FALSE;
+ while (*s && (s = parse_message_id(s, &id, &error)))
+ if (reference_count == nelem(referenced_ids))
+ {
+ memmove(referenced_ids + 1, referenced_ids + 2,
+ sizeof(referenced_ids) - 2*sizeof(uschar *));
+ referenced_ids[reference_count - 1] = id;
+ }
+ else
+ referenced_ids[reference_count++] = id;
+
+ for (int i = 0; i < reference_count; ++i)
+ fprintf(fp, " %s", referenced_ids[i]);
+ }
+
+ /* The message id will have a newline on the end of it. */
+
+ if (message_id) fprintf(fp, " %s", message_id);
+ else fprintf(fp, "\n");
+ }
+}
+
+
+
+/*************************************************
* Send error message *
*************************************************/
@@ -119,6 +193,7 @@ else
moan_write_from(fp);
fprintf(fp, "To: %s\n", recipient);
+moan_write_references(fp, NULL);
switch(ident)
{
@@ -145,7 +220,7 @@ switch(ident)
"A message that you sent contained one or more recipient addresses that were\n"
"incorrectly constructed:\n\n");
- while (eblock != NULL)
+ while (eblock)
{
fprintf(fp, " %s: %s\n", eblock->text1, eblock->text2);
count++;
@@ -522,6 +597,7 @@ f = fdopen(fd, "wb");
fprintf(f, "Auto-Submitted: auto-replied\n");
moan_write_from(f);
fprintf(f, "To: %s\n", who);
+moan_write_references(f, NULL);
fprintf(f, "Subject: %s\n\n", subject);
va_start(ap, format);
vfprintf(f, format, ap);
@@ -656,8 +732,7 @@ llen = domain++ - recipient;
/* Scan through the configured items */
-while ((item = string_nextinlist(&listptr, &sep, buffer, sizeof(buffer)))
- != NULL)
+while ((item = string_nextinlist(&listptr, &sep, buffer, sizeof(buffer))))
{
const uschar *newaddress = item;
const uschar *pattern = string_dequote(&newaddress);
@@ -759,6 +834,7 @@ fprintf(f, "Auto-Submitted: auto-replied\n");
moan_write_from(f);
fprintf(f, "To: %s\n", s);
fprintf(f, "Subject: error(s) in forwarding or filtering\n\n");
+moan_write_references(f, NULL);
if (custom)
{
diff --git a/src/src/transports/autoreply.c b/src/src/transports/autoreply.c
index 734e65833..1aef02aaf 100644
--- a/src/src/transports/autoreply.c
+++ b/src/src/transports/autoreply.c
@@ -598,52 +598,7 @@ if (h)
fprintf(fp, "In-Reply-To: %s", message_id);
}
-/* Generate a References header if there is at least one of Message-ID:,
-References:, or In-Reply-To: (see RFC 2822). */
-
-for (h = header_list; h; h = h->next)
- if (h->type != htype_old && strncmpic(US"References:", h->text, 11) == 0)
- break;
-
-if (!h)
- for (h = header_list; h; h = h->next)
- if (h->type != htype_old && strncmpic(US"In-Reply-To:", h->text, 12) == 0)
- break;
-
-/* We limit the total length of references. Although there is no fixed
-limit, some systems do not like headers growing beyond recognition.
-Keep the first message ID for the thread root and the last few for
-the position inside the thread, up to a maximum of 12 altogether. */
-
-if (h || message_id)
- {
- fprintf(fp, "References:");
- if (h)
- {
- uschar *s, *id, *error;
- uschar *referenced_ids[12];
- int reference_count = 0;
-
- s = Ustrchr(h->text, ':') + 1;
- f.parse_allow_group = FALSE;
- while (*s != 0 && (s = parse_message_id(s, &id, &error)) != NULL)
- {
- if (reference_count == nelem(referenced_ids))
- {
- memmove(referenced_ids + 1, referenced_ids + 2,
- sizeof(referenced_ids) - 2*sizeof(uschar *));
- referenced_ids[reference_count - 1] = id;
- }
- else referenced_ids[reference_count++] = id;
- }
- for (int i = 0; i < reference_count; ++i) fprintf(fp, " %s", referenced_ids[i]);
- }
-
- /* The message id will have a newline on the end of it. */
-
- if (message_id) fprintf(fp, " %s", message_id);
- else fprintf(fp, "\n");
- }
+moan_write_references(fp, message_id);
/* Add an Auto-Submitted: header */