]>
Commit | Line | Data |
---|---|---|
590b0a38 AM |
1 | commit d6c829b9a350f61c98196768e3260beb3cbecbfe |
2 | Author: Jeremy Harris <jgh146exb@wizmail.org> | |
3 | Date: Wed Oct 2 14:49:55 2019 +0100 | |
4 | ||
5 | DSN: add References: header. Bug 2452 | |
6 | ||
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 */ | |
13 | { | |
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)); | |
18 | ||
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}}; | |
22 | ||
23 | DEBUG(D_deliver) | |
24 | - debug_printf("sending error message to: %s\n", sender_address); | |
25 | + debug_printf("sending success-dsn to: %s\n", sender_address); | |
26 | ||
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) | |
30 | moan_write_from(f); | |
31 | fprintf(f, "Auto-Submitted: auto-generated\n" | |
32 | "To: %s\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", | |
36 | + sender_address); | |
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" | |
41 | ||
42 | "--%s\n" | |
43 | @@ -7378,7 +7381,7 @@ if (addr_senddsn) | |
44 | ||
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); | |
48 | + bound, bound); | |
49 | ||
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"); | |
54 | moan_write_from(fp); | |
55 | fprintf(fp, "To: %s\n", bounce_recipient); | |
56 | + moan_write_references(fp, NULL); | |
57 | ||
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)) | |
61 | ||
62 | DEBUG(D_deliver) | |
63 | { | |
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, | |
68 | warning_count); | |
69 | } | |
70 | @@ -8230,6 +8235,7 @@ else if (addr_defer != (address_item *)(+1)) | |
71 | fprintf(f, "Auto-Submitted: auto-replied\n"); | |
72 | moan_write_from(f); | |
73 | fprintf(f, "To: %s\n", recipients); | |
74 | + moan_write_references(f, NULL); | |
75 | ||
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); | |
88 | ||
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 | |
92 | --- a/src/src/moan.c | |
93 | +++ b/src/src/moan.c | |
94 | @@ -28,7 +28,7 @@ Returns: nothing | |
95 | void | |
96 | moan_write_from(FILE *f) | |
97 | { | |
98 | -uschar *s = expand_string(dsn_from); | |
99 | +uschar * s = expand_string(dsn_from); | |
100 | if (!s) | |
101 | { | |
102 | log_write(0, LOG_MAIN|LOG_PANIC, | |
103 | @@ -40,6 +40,80 @@ fprintf(f, "From: %s\n", s); | |
104 | ||
105 | ||
106 | ||
107 | +/************************************************* | |
108 | +* Write References: line for DSN * | |
109 | +*************************************************/ | |
110 | + | |
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). | |
113 | + | |
114 | +Arguments: f the FILE to write to | |
115 | + message_id optional already-found message-id, or NULL | |
116 | + | |
117 | +Returns: nothing | |
118 | +*/ | |
119 | + | |
120 | +void | |
121 | +moan_write_references(FILE * fp, uschar * message_id) | |
122 | +{ | |
123 | +header_line * h; | |
124 | + | |
125 | +if (!message_id) | |
126 | + for (h = header_list; h; h = h->next) | |
127 | + if (h->type == htype_id) | |
128 | + { | |
129 | + message_id = Ustrchr(h->text, ':') + 1; | |
130 | + while (isspace(*message_id)) message_id++; | |
131 | + } | |
132 | + | |
133 | +for (h = header_list; h; h = h->next) | |
134 | + if (h->type != htype_old && strncmpic(US"References:", h->text, 11) == 0) | |
135 | + break; | |
136 | + | |
137 | +if (!h) | |
138 | + for (h = header_list; h; h = h->next) | |
139 | + if (h->type != htype_old && strncmpic(US"In-Reply-To:", h->text, 12) == 0) | |
140 | + break; | |
141 | + | |
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. */ | |
146 | + | |
147 | +if (h || message_id) | |
148 | + { | |
149 | + fprintf(fp, "References:"); | |
150 | + if (h) | |
151 | + { | |
152 | + uschar * s, * id, * error; | |
153 | + uschar * referenced_ids[12]; | |
154 | + int reference_count = 0; | |
155 | + | |
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)) | |
160 | + { | |
161 | + memmove(referenced_ids + 1, referenced_ids + 2, | |
162 | + sizeof(referenced_ids) - 2*sizeof(uschar *)); | |
163 | + referenced_ids[reference_count - 1] = id; | |
164 | + } | |
165 | + else | |
166 | + referenced_ids[reference_count++] = id; | |
167 | + | |
168 | + for (int i = 0; i < reference_count; ++i) | |
169 | + fprintf(fp, " %s", referenced_ids[i]); | |
170 | + } | |
171 | + | |
172 | + /* The message id will have a newline on the end of it. */ | |
173 | + | |
174 | + if (message_id) fprintf(fp, " %s", message_id); | |
175 | + else fprintf(fp, "\n"); | |
176 | + } | |
177 | +} | |
178 | + | |
179 | + | |
180 | + | |
181 | /************************************************* | |
182 | * Send error message * | |
183 | *************************************************/ | |
184 | @@ -119,6 +193,7 @@ else | |
185 | moan_write_from(fp); | |
186 | ||
187 | fprintf(fp, "To: %s\n", recipient); | |
188 | +moan_write_references(fp, NULL); | |
189 | ||
190 | switch(ident) | |
191 | { | |
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"); | |
195 | ||
196 | - while (eblock != NULL) | |
197 | + while (eblock) | |
198 | { | |
199 | fprintf(fp, " %s: %s\n", eblock->text1, eblock->text2); | |
200 | count++; | |
201 | @@ -522,6 +597,7 @@ f = fdopen(fd, "wb"); | |
202 | fprintf(f, "Auto-Submitted: auto-replied\n"); | |
203 | moan_write_from(f); | |
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; | |
210 | ||
211 | /* Scan through the configured items */ | |
212 | ||
213 | -while ((item = string_nextinlist(&listptr, &sep, buffer, sizeof(buffer))) | |
214 | - != NULL) | |
215 | +while ((item = string_nextinlist(&listptr, &sep, buffer, sizeof(buffer)))) | |
216 | { | |
217 | const uschar *newaddress = item; | |
218 | const uschar *pattern = string_dequote(&newaddress); | |
219 | @@ -759,6 +834,7 @@ fprintf(f, "Auto-Submitted: auto-replied\n"); | |
220 | moan_write_from(f); | |
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); | |
224 | ||
225 | if (custom) | |
226 | { | |
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); | |
233 | } | |
234 | ||
235 | -/* Generate a References header if there is at least one of Message-ID:, | |
236 | -References:, or In-Reply-To: (see RFC 2822). */ | |
237 | - | |
238 | -for (h = header_list; h; h = h->next) | |
239 | - if (h->type != htype_old && strncmpic(US"References:", h->text, 11) == 0) | |
240 | - break; | |
241 | - | |
242 | -if (!h) | |
243 | - for (h = header_list; h; h = h->next) | |
244 | - if (h->type != htype_old && strncmpic(US"In-Reply-To:", h->text, 12) == 0) | |
245 | - break; | |
246 | - | |
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. */ | |
251 | - | |
252 | -if (h || message_id) | |
253 | - { | |
254 | - fprintf(fp, "References:"); | |
255 | - if (h) | |
256 | - { | |
257 | - uschar *s, *id, *error; | |
258 | - uschar *referenced_ids[12]; | |
259 | - int reference_count = 0; | |
260 | - int i; | |
261 | - | |
262 | - s = Ustrchr(h->text, ':') + 1; | |
263 | - f.parse_allow_group = FALSE; | |
264 | - while (*s != 0 && (s = parse_message_id(s, &id, &error)) != NULL) | |
265 | - { | |
266 | - if (reference_count == nelem(referenced_ids)) | |
267 | - { | |
268 | - memmove(referenced_ids + 1, referenced_ids + 2, | |
269 | - sizeof(referenced_ids) - 2*sizeof(uschar *)); | |
270 | - referenced_ids[reference_count - 1] = id; | |
271 | - } | |
272 | - else referenced_ids[reference_count++] = id; | |
273 | - } | |
274 | - for (i = 0; i < reference_count; ++i) fprintf(fp, " %s", referenced_ids[i]); | |
275 | - } | |
276 | - | |
277 | - /* The message id will have a newline on the end of it. */ | |
278 | - | |
279 | - if (message_id) fprintf(fp, " %s", message_id); | |
280 | - else fprintf(fp, "\n"); | |
281 | - } | |
282 | + moan_write_references(fp, message_id); | |
283 | ||
284 | /* Add an Auto-Submitted: header */ | |
285 |