1 commit d6c829b9a350f61c98196768e3260beb3cbecbfe
2 Author: Jeremy Harris <jgh146exb@wizmail.org>
3 Date: Wed Oct 2 14:49:55 2019 +0100
5 DSN: add References: header. Bug 2452
7 diff --git a/src/src/deliver.c b/src/src/deliver.c
8 index 72751c2dc..7433b5fb2 100644
9 --- a/src/src/deliver.c
10 +++ b/src/src/deliver.c
11 @@ -7344,7 +7344,7 @@ if (addr_senddsn)
12 if (pid < 0) /* Creation of child failed */
14 log_write(0, LOG_MAIN|LOG_PANIC_DIE, "Process %d (parent %d) failed to "
15 - "create child process to send failure message: %s", getpid(),
16 + "create child process to send success-dsn message: %s", getpid(),
17 getppid(), strerror(errno));
19 DEBUG(D_deliver) debug_printf("DSN: child_open_exim failed\n");
20 @@ -7357,7 +7357,7 @@ if (addr_senddsn)
21 transport_ctx tctx = {{0}};
24 - debug_printf("sending error message to: %s\n", sender_address);
25 + debug_printf("sending success-dsn to: %s\n", sender_address);
27 /* build unique id for MIME boundary */
28 bound = string_sprintf(TIME_T_FMT "-eximdsn-%d", time(NULL), rand());
29 @@ -7369,8 +7369,11 @@ if (addr_senddsn)
31 fprintf(f, "Auto-Submitted: auto-generated\n"
33 - "Subject: Delivery Status Notification\n"
34 - "Content-Type: multipart/report; report-type=delivery-status; boundary=%s\n"
35 + "Subject: Delivery Status Notification\n",
37 + moan_write_references(f, NULL);
38 + fprintf(f, "Content-Type: multipart/report;"
39 + " report-type=delivery-status; boundary=%s\n"
40 "MIME-Version: 1.0\n\n"
43 @@ -7378,7 +7381,7 @@ if (addr_senddsn)
45 "This message was created automatically by mail delivery software.\n"
46 " ----- The following addresses had successful delivery notifications -----\n",
47 - sender_address, bound, bound);
50 for (address_item * a = addr_senddsn; a; a = a->next)
51 fprintf(f, "<%s> (relayed %s)\n\n",
52 @@ -7607,6 +7610,7 @@ while (addr_failed)
53 fprintf(fp, "Auto-Submitted: auto-replied\n");
55 fprintf(fp, "To: %s\n", bounce_recipient);
56 + moan_write_references(fp, NULL);
58 /* generate boundary string and output MIME-Headers */
59 bound = string_sprintf(TIME_T_FMT "-eximdsn-%d", time(NULL), rand());
60 @@ -8192,7 +8196,8 @@ else if (addr_defer != (address_item *)(+1))
64 - debug_printf("time on queue = %s id %s addr %s\n", readconf_printtime(queue_time), message_id, addr_defer->address);
65 + debug_printf("time on queue = %s id %s addr %s\n",
66 + readconf_printtime(queue_time), message_id, addr_defer->address);
67 debug_printf("warning counts: required %d done %d\n", count,
70 @@ -8230,6 +8235,7 @@ else if (addr_defer != (address_item *)(+1))
71 fprintf(f, "Auto-Submitted: auto-replied\n");
73 fprintf(f, "To: %s\n", recipients);
74 + moan_write_references(f, NULL);
76 /* generated boundary string and output MIME-Headers */
77 bound = string_sprintf(TIME_T_FMT "-eximdsn-%d", time(NULL), rand());
78 diff --git a/src/src/functions.h b/src/src/functions.h
79 index 31c005773..d99f15465 100644
80 --- a/src/src/functions.h
81 +++ b/src/src/functions.h
82 @@ -335,6 +335,7 @@ extern void moan_tell_someone(uschar *, address_item *,
83 const uschar *, const char *, ...) PRINTF_FUNCTION(4,5);
84 extern BOOL moan_to_sender(int, error_block *, header_line *, FILE *, BOOL);
85 extern void moan_write_from(FILE *);
86 +extern void moan_write_references(FILE *, uschar *);
87 extern FILE *modefopen(const uschar *, const char *, mode_t);
89 extern int open_cutthrough_connection( address_item * addr );
90 diff --git a/src/src/moan.c b/src/src/moan.c
91 index f6cda37f2..31d033c1a 100644
94 @@ -28,7 +28,7 @@ Returns: nothing
96 moan_write_from(FILE *f)
98 -uschar *s = expand_string(dsn_from);
99 +uschar * s = expand_string(dsn_from);
102 log_write(0, LOG_MAIN|LOG_PANIC,
103 @@ -40,6 +40,80 @@ fprintf(f, "From: %s\n", s);
107 +/*************************************************
108 +* Write References: line for DSN *
109 +*************************************************/
111 +/* Generate a References: header if there is in the header_list
112 +at least one of Message-ID:, References:, or In-Reply-To: (see RFC 2822).
114 +Arguments: f the FILE to write to
115 + message_id optional already-found message-id, or NULL
121 +moan_write_references(FILE * fp, uschar * message_id)
126 + for (h = header_list; h; h = h->next)
127 + if (h->type == htype_id)
129 + message_id = Ustrchr(h->text, ':') + 1;
130 + while (isspace(*message_id)) message_id++;
133 +for (h = header_list; h; h = h->next)
134 + if (h->type != htype_old && strncmpic(US"References:", h->text, 11) == 0)
138 + for (h = header_list; h; h = h->next)
139 + if (h->type != htype_old && strncmpic(US"In-Reply-To:", h->text, 12) == 0)
142 +/* We limit the total length of references. Although there is no fixed
143 +limit, some systems do not like headers growing beyond recognition.
144 +Keep the first message ID for the thread root and the last few for
145 +the position inside the thread, up to a maximum of 12 altogether. */
147 +if (h || message_id)
149 + fprintf(fp, "References:");
152 + uschar * s, * id, * error;
153 + uschar * referenced_ids[12];
154 + int reference_count = 0;
156 + s = Ustrchr(h->text, ':') + 1;
157 + f.parse_allow_group = FALSE;
158 + while (*s && (s = parse_message_id(s, &id, &error)))
159 + if (reference_count == nelem(referenced_ids))
161 + memmove(referenced_ids + 1, referenced_ids + 2,
162 + sizeof(referenced_ids) - 2*sizeof(uschar *));
163 + referenced_ids[reference_count - 1] = id;
166 + referenced_ids[reference_count++] = id;
168 + for (int i = 0; i < reference_count; ++i)
169 + fprintf(fp, " %s", referenced_ids[i]);
172 + /* The message id will have a newline on the end of it. */
174 + if (message_id) fprintf(fp, " %s", message_id);
175 + else fprintf(fp, "\n");
181 /*************************************************
182 * Send error message *
183 *************************************************/
184 @@ -119,6 +193,7 @@ else
187 fprintf(fp, "To: %s\n", recipient);
188 +moan_write_references(fp, NULL);
192 @@ -145,7 +220,7 @@ switch(ident)
193 "A message that you sent contained one or more recipient addresses that were\n"
194 "incorrectly constructed:\n\n");
196 - while (eblock != NULL)
199 fprintf(fp, " %s: %s\n", eblock->text1, eblock->text2);
201 @@ -522,6 +597,7 @@ f = fdopen(fd, "wb");
202 fprintf(f, "Auto-Submitted: auto-replied\n");
204 fprintf(f, "To: %s\n", who);
205 +moan_write_references(f, NULL);
206 fprintf(f, "Subject: %s\n\n", subject);
207 va_start(ap, format);
208 vfprintf(f, format, ap);
209 @@ -656,8 +732,7 @@ llen = domain++ - recipient;
211 /* Scan through the configured items */
213 -while ((item = string_nextinlist(&listptr, &sep, buffer, sizeof(buffer)))
215 +while ((item = string_nextinlist(&listptr, &sep, buffer, sizeof(buffer))))
217 const uschar *newaddress = item;
218 const uschar *pattern = string_dequote(&newaddress);
219 @@ -759,6 +834,7 @@ fprintf(f, "Auto-Submitted: auto-replied\n");
221 fprintf(f, "To: %s\n", s);
222 fprintf(f, "Subject: error(s) in forwarding or filtering\n\n");
223 +moan_write_references(f, NULL);
227 diff --git a/src/src/transports/autoreply.c b/src/src/transports/autoreply.c
228 index 734e65833..1aef02aaf 100644
229 --- a/src/src/transports/autoreply.c
230 +++ b/src/src/transports/autoreply.c
231 @@ -599,53 +599,7 @@ if (h)
232 fprintf(fp, "In-Reply-To: %s", message_id);
235 -/* Generate a References header if there is at least one of Message-ID:,
236 -References:, or In-Reply-To: (see RFC 2822). */
238 -for (h = header_list; h; h = h->next)
239 - if (h->type != htype_old && strncmpic(US"References:", h->text, 11) == 0)
243 - for (h = header_list; h; h = h->next)
244 - if (h->type != htype_old && strncmpic(US"In-Reply-To:", h->text, 12) == 0)
247 -/* We limit the total length of references. Although there is no fixed
248 -limit, some systems do not like headers growing beyond recognition.
249 -Keep the first message ID for the thread root and the last few for
250 -the position inside the thread, up to a maximum of 12 altogether. */
252 -if (h || message_id)
254 - fprintf(fp, "References:");
257 - uschar *s, *id, *error;
258 - uschar *referenced_ids[12];
259 - int reference_count = 0;
262 - s = Ustrchr(h->text, ':') + 1;
263 - f.parse_allow_group = FALSE;
264 - while (*s != 0 && (s = parse_message_id(s, &id, &error)) != NULL)
266 - if (reference_count == nelem(referenced_ids))
268 - memmove(referenced_ids + 1, referenced_ids + 2,
269 - sizeof(referenced_ids) - 2*sizeof(uschar *));
270 - referenced_ids[reference_count - 1] = id;
272 - else referenced_ids[reference_count++] = id;
274 - for (i = 0; i < reference_count; ++i) fprintf(fp, " %s", referenced_ids[i]);
277 - /* The message id will have a newline on the end of it. */
279 - if (message_id) fprintf(fp, " %s", message_id);
280 - else fprintf(fp, "\n");
282 + moan_write_references(fp, message_id);
284 /* Add an Auto-Submitted: header */