DSN: add References: header. Bug 2452
[exim.git] / src / src / moan.c
1 /*************************************************
2 *     Exim - an Internet mail transport agent    *
3 *************************************************/
4
5 /* Copyright (c) University of Cambridge 1995 - 2018 */
6 /* See the file NOTICE for conditions of use and distribution. */
7
8 /* Functions for sending messages to sender or to mailmaster. */
9
10
11 #include "exim.h"
12
13
14
15 /*************************************************
16 *            Write From: line for DSN            *
17 *************************************************/
18
19 /* This function is called to write the From: line in automatically generated
20 messages - bounces, warnings, etc. It expands a configuration item in order to
21 get the text. If the expansion fails, a panic is logged and the default value
22 for the option is used.
23
24 Argument:   the FILE to write to
25 Returns:    nothing
26 */
27
28 void
29 moan_write_from(FILE *f)
30 {
31 uschar * s = expand_string(dsn_from);
32 if (!s)
33   {
34   log_write(0, LOG_MAIN|LOG_PANIC,
35     "Failed to expand dsn_from (using default): %s", expand_string_message);
36   s = expand_string(US DEFAULT_DSN_FROM);
37   }
38 fprintf(f, "From: %s\n", s);
39 }
40
41
42
43 /*************************************************
44 *            Write References: line for DSN      *
45 *************************************************/
46
47 /* Generate a References: header if there is in the header_list
48 at least one of Message-ID:, References:, or In-Reply-To: (see RFC 2822).
49
50 Arguments:  f           the FILE to write to
51             message_id  optional already-found message-id, or NULL
52
53 Returns:    nothing
54 */
55
56 void
57 moan_write_references(FILE * fp, uschar * message_id)
58 {
59 header_line * h;
60
61 if (!message_id)
62   for (h = header_list; h; h = h->next)
63     if (h->type == htype_id)
64       {
65       message_id = Ustrchr(h->text, ':') + 1;
66       while (isspace(*message_id)) message_id++;
67       }
68
69 for (h = header_list; h; h = h->next)
70   if (h->type != htype_old && strncmpic(US"References:", h->text, 11) == 0)
71     break;
72
73 if (!h)
74   for (h = header_list; h; h = h->next)
75     if (h->type != htype_old && strncmpic(US"In-Reply-To:", h->text, 12) == 0)
76       break;
77
78 /* We limit the total length of references.  Although there is no fixed
79 limit, some systems do not like headers growing beyond recognition.
80 Keep the first message ID for the thread root and the last few for
81 the position inside the thread, up to a maximum of 12 altogether. */
82
83 if (h || message_id)
84   {
85   fprintf(fp, "References:");
86   if (h)
87     {
88     uschar * s, * id, * error;
89     uschar * referenced_ids[12];
90     int reference_count = 0;
91
92     s = Ustrchr(h->text, ':') + 1;
93     f.parse_allow_group = FALSE;
94     while (*s && (s = parse_message_id(s, &id, &error)))
95       if (reference_count == nelem(referenced_ids))
96         {
97         memmove(referenced_ids + 1, referenced_ids + 2,
98            sizeof(referenced_ids) - 2*sizeof(uschar *));
99         referenced_ids[reference_count - 1] = id;
100         }
101       else
102         referenced_ids[reference_count++] = id;
103
104     for (int i = 0; i < reference_count; ++i)
105       fprintf(fp, " %s", referenced_ids[i]);
106     }
107
108   /* The message id will have a newline on the end of it. */
109
110   if (message_id) fprintf(fp, " %s", message_id);
111   else fprintf(fp, "\n");
112   }
113 }
114
115
116
117 /*************************************************
118 *              Send error message                *
119 *************************************************/
120
121 /* This function sends an error message by opening a pipe to a new process
122 running Exim, and writing a message to it using the "-t" option. This is not
123 used for delivery failures, which have their own code for handing failed
124 addresses.
125
126 Arguments:
127   recipient      addressee for the message
128   ident          identifies the type of error
129   eblock         chain of error_blocks containing data about the error
130   headers        the message's headers
131   message_file   FILE containing the body of the message
132   firstline      contains first line of file, if it was read to check for
133                    "From ", but it turned out not to be
134
135 Returns:         TRUE if message successfully sent
136 */
137
138 BOOL
139 moan_send_message(uschar *recipient, int ident, error_block *eblock,
140   header_line *headers, FILE *message_file, uschar *firstline)
141 {
142 int written = 0;
143 int fd;
144 int status;
145 int count = 0;
146 int size_limit = bounce_return_size_limit;
147 FILE * fp;
148 int pid;
149
150 #ifdef SUPPORT_DMARC
151 uschar * s, * s2;
152
153 /* For DMARC if there is a specific sender set, expand the variable for the
154 header From: and grab the address from that for the envelope FROM. */
155
156 if (  ident == ERRMESS_DMARC_FORENSIC
157    && dmarc_forensic_sender
158    && (s = expand_string(dmarc_forensic_sender))
159    && *s
160    && (s2 = expand_string(string_sprintf("${address:%s}", s)))
161    && *s2
162    )
163   pid = child_open_exim2(&fd, s2, bounce_sender_authentication);
164 else
165   {
166   s = NULL;
167   pid = child_open_exim(&fd);
168   }
169
170 #else
171 pid = child_open_exim(&fd);
172 #endif
173
174 if (pid < 0)
175   {
176   DEBUG(D_any) debug_printf("Failed to create child to send message: %s\n",
177     strerror(errno));
178   return FALSE;
179   }
180 else DEBUG(D_any) debug_printf("Child process %d for sending message\n", pid);
181
182 /* Creation of child succeeded */
183
184 fp = fdopen(fd, "wb");
185 if (errors_reply_to) fprintf(fp, "Reply-To: %s\n", errors_reply_to);
186 fprintf(fp, "Auto-Submitted: auto-replied\n");
187
188 #ifdef SUPPORT_DMARC
189 if (s)
190   fprintf(fp, "From: %s\n", s);
191 else
192 #endif
193   moan_write_from(fp);
194
195 fprintf(fp, "To: %s\n", recipient);
196 moan_write_references(fp, NULL);
197
198 switch(ident)
199   {
200   case ERRMESS_BADARGADDRESS:
201     fprintf(fp,
202       "Subject: Mail failure - malformed recipient address\n\n");
203     fprintf(fp,
204       "A message that you sent contained a recipient address that was incorrectly\n"
205       "constructed:\n\n");
206     fprintf(fp, "  %s  %s\n", eblock->text1, eblock->text2);
207     count = Ustrlen(eblock->text1);
208     if (count > 0 && eblock->text1[count-1] == '.')
209       fprintf(fp,
210         "\nRecipient addresses must not end with a '.' character.\n");
211     fprintf(fp,
212       "\nThe message has not been delivered to any recipients.\n");
213     break;
214
215   case ERRMESS_BADNOADDRESS:
216   case ERRMESS_BADADDRESS:
217     fprintf(fp,
218       "Subject: Mail failure - malformed recipient address\n\n");
219     fprintf(fp,
220       "A message that you sent contained one or more recipient addresses that were\n"
221       "incorrectly constructed:\n\n");
222
223     while (eblock)
224       {
225       fprintf(fp, "  %s: %s\n", eblock->text1, eblock->text2);
226       count++;
227       eblock = eblock->next;
228       }
229
230     fprintf(fp, (count == 1)? "\nThis address has been ignored. " :
231       "\nThese addresses have been ignored. ");
232
233     fprintf(fp, (ident == ERRMESS_BADADDRESS)?
234       "The other addresses in the message were\n"
235       "syntactically valid and have been passed on for an attempt at delivery.\n" :
236
237       "There were no other addresses in your\n"
238       "message, and so no attempt at delivery was possible.\n");
239     break;
240
241   case ERRMESS_IGADDRESS:
242     fprintf(fp, "Subject: Mail failure - no recipient addresses\n\n");
243     fprintf(fp,
244       "A message that you sent using the -t command line option contained no\n"
245       "addresses that were not also on the command line, and were therefore\n"
246       "suppressed. This left no recipient addresses, and so no delivery could\n"
247       "be attempted.\n");
248     break;
249
250   case ERRMESS_NOADDRESS:
251     fprintf(fp, "Subject: Mail failure - no recipient addresses\n\n");
252     fprintf(fp,
253       "A message that you sent contained no recipient addresses, and therefore no\n"
254       "delivery could be attempted.\n");
255     break;
256
257   case ERRMESS_IOERR:
258     fprintf(fp, "Subject: Mail failure - system failure\n\n");
259     fprintf(fp,
260       "A system failure was encountered while processing a message that you sent,\n"
261       "so it has not been possible to deliver it. The error was:\n\n%s\n",
262       eblock->text1);
263     break;
264
265   case ERRMESS_VLONGHEADER:
266     fprintf(fp, "Subject: Mail failure - overlong header section\n\n");
267     fprintf(fp,
268       "A message that you sent contained a header section that was excessively\n"
269       "long and could not be handled by the mail transmission software. The\n"
270       "message has not been delivered to any recipients.\n");
271     break;
272
273   case ERRMESS_VLONGHDRLINE:
274     fprintf(fp, "Subject: Mail failure - overlong header line\n\n");
275     fprintf(fp,
276       "A message that you sent contained a header line that was excessively\n"
277       "long and could not be handled by the mail transmission software. The\n"
278       "message has not been delivered to any recipients.\n");
279     break;
280
281   case ERRMESS_TOOBIG:
282     fprintf(fp, "Subject: Mail failure - message too big\n\n");
283     fprintf(fp,
284       "A message that you sent was longer than the maximum size allowed on this\n"
285       "system. It was not delivered to any recipients.\n");
286     break;
287
288   case ERRMESS_TOOMANYRECIP:
289     fprintf(fp, "Subject: Mail failure - too many recipients\n\n");
290     fprintf(fp,
291       "A message that you sent contained more recipients than allowed on this\n"
292       "system. It was not delivered to any recipients.\n");
293     break;
294
295   case ERRMESS_LOCAL_SCAN:
296   case ERRMESS_LOCAL_ACL:
297     fprintf(fp, "Subject: Mail failure - rejected by local scanning code\n\n");
298     fprintf(fp,
299       "A message that you sent was rejected by the local scanning code that\n"
300       "checks incoming messages on this system.");
301       if (eblock->text1)
302         fprintf(fp, " The following error was given:\n\n  %s", eblock->text1);
303   fprintf(fp, "\n");
304   break;
305
306 #ifdef SUPPORT_DMARC
307   case ERRMESS_DMARC_FORENSIC:
308     bounce_return_message = TRUE;
309     bounce_return_body    = FALSE;
310     fprintf(fp, "Subject: DMARC Forensic Report for %s from IP %s\n\n",
311           eblock ? eblock->text2 : US"Unknown",
312           sender_host_address);
313     fprintf(fp,
314       "A message claiming to be from you has failed the published DMARC\n"
315       "policy for your domain.\n\n");
316     while (eblock)
317       {
318       fprintf(fp, "  %s: %s\n", eblock->text1, eblock->text2);
319       count++;
320       eblock = eblock->next;
321       }
322   break;
323 #endif
324
325   default:
326     fprintf(fp, "Subject: Mail failure\n\n");
327     fprintf(fp,
328       "A message that you sent has caused the error routine to be entered with\n"
329       "an unknown error number (%d).\n", ident);
330     break;
331   }
332
333 /* Now, if configured, copy the message; first the headers and then the rest of
334 the input if available, up to the configured limit, if the option for including
335 message bodies in bounces is set. */
336
337 if (bounce_return_message)
338   {
339   if (bounce_return_body)
340     {
341     fprintf(fp, "\n"
342       "------ This is a copy of your message, including all the headers.");
343     if (size_limit == 0 || size_limit > thismessage_size_limit)
344       size_limit = thismessage_size_limit;
345     if (size_limit > 0 && size_limit < message_size)
346       {
347       int x = size_limit;
348       uschar *k = US"";
349       if ((x & 1023) == 0)
350         {
351         k = US"K";
352         x >>= 10;
353         }
354       fprintf(fp, "\n"
355         "------ No more than %d%s characters of the body are included.\n\n",
356           x, k);
357       }
358     else fprintf(fp, " ------\n\n");
359     }
360   else
361     {
362     fprintf(fp, "\n"
363       "------ This is a copy of the headers that were received before the "
364       "error\n       was detected.\n\n");
365     }
366
367   /* If the error occurred before the Received: header was created, its text
368   field will still be NULL; just omit such a header line. */
369
370   while (headers)
371     {
372     if (headers->text != NULL) fprintf(fp, "%s", CS headers->text);
373     headers = headers->next;
374     }
375
376   if (ident != ERRMESS_VLONGHEADER && ident != ERRMESS_VLONGHDRLINE)
377     fputc('\n', fp);
378
379   /* After early detection of an error, the message file may be STDIN,
380   in which case we might have to terminate on a line containing just "."
381   as well as on EOF. We may already have the first line in memory. */
382
383   if (bounce_return_body && message_file)
384     {
385     BOOL enddot = f.dot_ends && message_file == stdin;
386     uschar * buf = store_get(bounce_return_linesize_limit+2, TRUE);
387
388     if (firstline) fprintf(fp, "%s", CS firstline);
389
390     while (fgets(CS buf, bounce_return_linesize_limit+2, message_file))
391       {
392       int len;
393
394       if (enddot && *buf == '.' && buf[1] == '\n')
395         {
396         fputc('.', fp);
397         break;
398         }
399
400       len = Ustrlen(buf);
401       if (buf[len-1] != '\n')
402         {       /* eat rest of partial line */
403         int ch;
404         while ((ch = fgetc(message_file)) != EOF && ch != '\n') ;
405         }
406
407       if (size_limit > 0 && len > size_limit - written)
408         {
409         buf[size_limit - written] = '\0';
410         fputs(CS buf, fp);
411         break;
412         }
413
414       fputs(CS buf, fp);
415       }
416     }
417 #ifdef SUPPORT_DMARC
418   /* Overkill, but use exact test in case future code gets inserted */
419   else if (bounce_return_body && message_file == NULL)
420     {
421     /*XXX limit line length here? */
422     /* This doesn't print newlines, disable until can parse and fix
423      * output to be legible.  */
424     fprintf(fp, "%s", expand_string(US"$message_body"));
425     }
426 #endif
427   }
428 /* Close the file, which should send an EOF to the child process
429 that is receiving the message. Wait for it to finish, without a timeout. */
430
431 (void)fclose(fp);
432 status = child_close(pid, 0);  /* Waits for child to close */
433 if (status != 0)
434   {
435   uschar *msg = US"Child mail process returned status";
436   if (status == -257)
437     log_write(0, LOG_MAIN, "%s %d: errno=%d: %s", msg, status, errno,
438       strerror(errno));
439   else
440     log_write(0, LOG_MAIN, "%s %d", msg, status);
441   return FALSE;
442   }
443
444 return TRUE;
445 }
446
447
448
449 /*************************************************
450 *          Send message to sender                *
451 *************************************************/
452
453 /* This function is called when errors are detected during the receipt of a
454 message. Delivery failures are handled separately in deliver.c.
455
456 If there is a valid sender_address, and the failing message is not a local
457 error message, then this function calls moan_send_message to send a message to
458 that person. If the sender's address is null, then an error has occurred with a
459 message that was generated by a mailer daemon. All we can do is to write
460 information to log files. The same action is taken if local_error_message is
461 set - this can happen for non null-senders in certain configurations where exim
462 doesn't run setuid root.
463
464 Arguments:
465   ident         identifies the particular error
466   eblock        chain of error_blocks containing data about the error
467   headers       message's headers (chain)
468   message_file  a FILE where the body of the message can be read
469   check_sender  if TRUE, read the first line of the file for a possible
470                   "From " sender (if a trusted caller)
471
472 Returns:        FALSE if there is no sender_address to send to;
473                 else the return from moan_send_message()
474 */
475
476 BOOL
477 moan_to_sender(int ident, error_block *eblock, header_line *headers,
478   FILE *message_file, BOOL check_sender)
479 {
480 uschar *firstline = NULL;
481 uschar *msg = US"Error while reading message with no usable sender address";
482
483 if (message_reference)
484   msg = string_sprintf("%s (R=%s)", msg, message_reference);
485
486 /* Find the sender from a From line if permitted and possible */
487
488 if (check_sender && message_file && f.trusted_caller &&
489     Ufgets(big_buffer, BIG_BUFFER_SIZE, message_file) != NULL)
490   {
491   uschar *new_sender = NULL;
492   if (regex_match_and_setup(regex_From, big_buffer, 0, -1))
493     new_sender = expand_string(uucp_from_sender);
494   if (new_sender) sender_address = new_sender;
495     else firstline = big_buffer;
496   }
497
498 /* If viable sender address, send a message */
499
500 if (sender_address && sender_address[0] && !f.local_error_message)
501   return moan_send_message(sender_address, ident, eblock, headers,
502     message_file, firstline);
503
504 /* Otherwise, we can only log */
505
506 switch(ident)
507   {
508   case ERRMESS_BADARGADDRESS:
509   case ERRMESS_BADNOADDRESS:
510   case ERRMESS_BADADDRESS:
511   log_write(0, LOG_MAIN, "%s: at least one malformed recipient address: "
512     "%s - %s", msg, eblock->text1, eblock->text2);
513   break;
514
515   case ERRMESS_IGADDRESS:
516   case ERRMESS_NOADDRESS:
517   log_write(0, LOG_MAIN, "%s: no recipient addresses", msg);
518   break;
519
520   /* This error has already been logged. */
521   case ERRMESS_IOERR:
522   break;
523
524   case ERRMESS_VLONGHEADER:
525   log_write(0, LOG_MAIN, "%s: excessively long message header section read "
526     "(more than %d characters)", msg, header_maxsize);
527   break;
528
529   case ERRMESS_VLONGHDRLINE:
530   log_write(0, LOG_MAIN, "%s: excessively long message header line read "
531     "(more than %d characters)", msg, header_line_maxsize);
532   break;
533
534   case ERRMESS_TOOBIG:
535   log_write(0, LOG_MAIN, "%s: message too big (limit set to %d)", msg,
536     thismessage_size_limit);
537   break;
538
539   case ERRMESS_TOOMANYRECIP:
540   log_write(0, LOG_MAIN, "%s: too many recipients (max set to %d)", msg,
541     recipients_max);
542   break;
543
544   case ERRMESS_LOCAL_SCAN:
545   log_write(0, LOG_MAIN, "%s: rejected by local_scan: %s", msg, eblock->text1);
546   break;
547
548   case ERRMESS_LOCAL_ACL:
549   log_write(0, LOG_MAIN, "%s: rejected by non-SMTP ACL: %s", msg, eblock->text1);
550   break;
551
552   default:
553   log_write(0, LOG_MAIN|LOG_PANIC, "%s: unknown error number %d", msg,
554     ident);
555   break;
556   }
557
558 return FALSE;
559 }
560
561
562
563 /*************************************************
564 *            Send message to someone             *
565 *************************************************/
566
567 /* This is called when exim is configured to tell someone (often the
568 mailmaster) about some incident.
569
570 Arguments:
571   who           address to send mail to
572   addr          chain of deferred addresses whose details are to be included
573   subject       subject text for the message
574   format        a printf() format for the body of the message
575   ...           arguments for the format
576
577 Returns:        nothing
578 */
579
580 void
581 moan_tell_someone(uschar *who, address_item *addr,
582   const uschar *subject, const char *format, ...)
583 {
584 FILE *f;
585 va_list ap;
586 int fd;
587 int pid = child_open_exim(&fd);
588
589 if (pid < 0)
590   {
591   DEBUG(D_any) debug_printf("Failed to create child to send message: %s\n",
592     strerror(errno));
593   return;
594   }
595
596 f = fdopen(fd, "wb");
597 fprintf(f, "Auto-Submitted: auto-replied\n");
598 moan_write_from(f);
599 fprintf(f, "To: %s\n", who);
600 moan_write_references(f, NULL);
601 fprintf(f, "Subject: %s\n\n", subject);
602 va_start(ap, format);
603 vfprintf(f, format, ap);
604 va_end(ap);
605
606 if (addr)
607   {
608   fprintf(f, "\nThe following address(es) have yet to be delivered:\n");
609   for (; addr; addr = addr->next)
610     {
611     uschar * parent = addr->parent ? addr->parent->address : NULL;
612     fprintf(f, "  %s", addr->address);
613     if (parent) fprintf(f, " <%s>", parent);
614     if (addr->basic_errno > 0) fprintf(f, ": %s", strerror(addr->basic_errno));
615     if (addr->message) fprintf(f, ": %s", addr->message);
616     fprintf(f, "\n");
617     }
618   }
619
620 (void)fclose(f);
621 child_close(pid, 0);  /* Waits for child to close; no timeout */
622 }
623
624
625
626 /*************************************************
627 *            Handle SMTP batch error             *
628 *************************************************/
629
630 /* This is called when something goes wrong in batched (-bS) SMTP input.
631 Information is written to stdout and/or stderr, and Exim exits with a non-zero
632 completion code. BSMTP is almost always called by some other program, so it is
633 up to that program to interpret the return code and do something with the error
634 information, and also to preserve the batch input file for human analysis.
635
636 Formerly, Exim used to attempt to continue after some errors, but this strategy
637 has been abandoned as it can lead to loss of messages.
638
639 Arguments:
640   cmd_buffer   the command causing the error, or NULL
641   format       a printf() format
642   ...          arguments for the format
643
644 Returns:       does not return; exits from the program
645                exit code = 1 if some messages were accepted
646                exit code = 2 if no messages were accepted
647 */
648
649 void
650 moan_smtp_batch(uschar *cmd_buffer, const char *format, ...)
651 {
652 va_list ap;
653 int yield = (receive_messagecount > 0)? 1 : 2;
654
655 DEBUG(D_any) debug_printf("Handling error in batched SMTP input\n");
656
657 /* On stdout, write stuff that a program could parse fairly easily. */
658
659 va_start(ap, format);
660 vfprintf(stdout, format, ap);
661 va_end(ap);
662
663 fprintf(stdout, "\nTransaction started in line %d\n",
664   bsmtp_transaction_linecount);
665 fprintf(stdout,   "Error detected in line %d\n", receive_linecount);
666 if (cmd_buffer != NULL) fprintf(stdout, "%s\n", cmd_buffer);
667
668 /* On stderr, write stuff for human consumption */
669
670 fprintf(stderr,
671   "An error was detected while processing a file of BSMTP input.\n"
672   "The error message was:\n\n  ");
673
674 va_start(ap, format);
675 vfprintf(stderr, format, ap);
676 va_end(ap);
677
678 fprintf(stderr,
679   "\n\nThe SMTP transaction started in line %d.\n"
680       "The error was detected in line %d.\n",
681   bsmtp_transaction_linecount, receive_linecount);
682
683 if (cmd_buffer != NULL)
684   {
685   fprintf(stderr, "The SMTP command at fault was:\n\n   %s\n\n",
686     cmd_buffer);
687   }
688
689 fprintf(stderr, "%d previous message%s successfully processed.\n",
690   receive_messagecount, (receive_messagecount == 1)? " was" : "s were");
691
692 fprintf(stderr, "The rest of the batch was abandoned.\n");
693
694 exim_exit(yield, US"batch");
695 }
696
697
698
699
700 /*************************************************
701 *         Check for error copies                 *
702 *************************************************/
703
704 /* This function is passed the recipient of an error message, and must check
705 the error_copies string to see whether there is an additional recipient list to
706 which errors for this recipient must be bcc'd. The incoming recipient is always
707 fully qualified.
708
709 Argument:   recipient address
710 Returns:    additional recipient list or NULL
711 */
712
713 uschar *
714 moan_check_errorcopy(uschar *recipient)
715 {
716 uschar *item, *localpart, *domain;
717 const uschar *listptr = errors_copy;
718 uschar *yield = NULL;
719 uschar buffer[256];
720 int sep = 0;
721 int llen;
722
723 if (errors_copy == NULL) return NULL;
724
725 /* Set up pointer to the local part and domain, and compute the
726 length of the local part. */
727
728 localpart = recipient;
729 domain = Ustrrchr(recipient, '@');
730 if (domain == NULL) return NULL;  /* should not occur, but avoid crash */
731 llen = domain++ - recipient;
732
733 /* Scan through the configured items */
734
735 while ((item = string_nextinlist(&listptr, &sep, buffer, sizeof(buffer))))
736   {
737   const uschar *newaddress = item;
738   const uschar *pattern = string_dequote(&newaddress);
739
740   /* If no new address found, just skip this item. */
741
742   while (isspace(*newaddress)) newaddress++;
743   if (*newaddress == 0) continue;
744
745   /* We now have an item to match as an address in item, and the additional
746   address in newaddress. If the pattern matches, expand the new address string
747   and return it. During expansion, make local part and domain available for
748   insertion. This requires a copy to be made; we can't just temporarily
749   terminate it, as the whole address is required for $0. */
750
751   if (match_address_list(recipient, TRUE, TRUE, &pattern, NULL, 0, UCHAR_MAX+1,
752         NULL) == OK)
753     {
754     deliver_localpart = string_copyn(localpart, llen);
755     deliver_domain = domain;
756     yield = expand_string_copy(newaddress);
757     deliver_domain = deliver_localpart = NULL;
758     if (yield == NULL)
759       log_write(0, LOG_MAIN|LOG_PANIC, "Failed to expand %s when processing "
760         "errors_copy: %s", newaddress, expand_string_message);
761     break;
762     }
763   }
764
765 DEBUG(D_any) debug_printf("errors_copy check returned %s\n",
766   (yield == NULL)? US"NULL" : yield);
767
768 expand_nmax = -1;
769 return yield;
770 }
771
772
773
774 /************************************************
775 *        Handle skipped syntax errors           *
776 ************************************************/
777
778 /* This function is called by the redirect router when it has skipped over one
779 or more syntax errors in the list of addresses. If there is an address to mail
780 to, send a message, and always write the information to the log. In the case of
781 a filter file, a "syntax error" might actually be something else, such as the
782 inability to open a log file. Thus, the wording of the error message is
783 general.
784
785 Arguments:
786   rname             the router name
787   eblock            chain of error blocks
788   syntax_errors_to  address to send mail to, or NULL
789   some              TRUE if some addresses were generated; FALSE if none were
790   custom            custom message text
791
792 Returns:            FALSE if string expansion failed; TRUE otherwise
793 */
794
795 BOOL
796 moan_skipped_syntax_errors(uschar *rname, error_block *eblock,
797   uschar *syntax_errors_to, BOOL some, uschar *custom)
798 {
799 int pid, fd;
800 uschar *s, *t;
801 FILE *f;
802
803 for (error_block * e = eblock; e; e = e->next)
804   if (e->text2 != NULL)
805     log_write(0, LOG_MAIN, "%s router: skipped error: %s in \"%s\"",
806       rname, e->text1, e->text2);
807   else
808     log_write(0, LOG_MAIN, "%s router: skipped error: %s", rname,
809       e->text1);
810
811 if (!syntax_errors_to) return TRUE;
812
813 if (!(s = expand_string(syntax_errors_to)))
814   {
815   log_write(0, LOG_MAIN, "%s router failed to expand %s: %s", rname,
816     syntax_errors_to, expand_string_message);
817   return FALSE;
818   }
819
820 /* If we can't create a process to send the message, just forget about
821 it. */
822
823 pid = child_open_exim(&fd);
824
825 if (pid < 0)
826   {
827   DEBUG(D_any) debug_printf("Failed to create child to send message: %s\n",
828     strerror(errno));
829   return TRUE;
830   }
831
832 f = fdopen(fd, "wb");
833 fprintf(f, "Auto-Submitted: auto-replied\n");
834 moan_write_from(f);
835 fprintf(f, "To: %s\n", s);
836 fprintf(f, "Subject: error(s) in forwarding or filtering\n\n");
837 moan_write_references(f, NULL);
838
839 if (custom)
840   {
841   if (!(t = expand_string(custom)))
842     {
843     log_write(0, LOG_MAIN, "%s router failed to expand %s: %s", rname,
844       custom, expand_string_message);
845     return FALSE;
846     }
847   fprintf(f, "%s\n\n", t);
848   }
849
850 fprintf(f, "The %s router encountered the following error(s):\n\n",
851   rname);
852
853 for (error_block * e = eblock; e; e = e->next)
854   {
855   fprintf(f, "  %s", e->text1);
856   if (e->text2 != NULL)
857     fprintf(f, " in the address\n  \"%s\"", e->text2);
858   fprintf(f, "\n\n");
859   }
860
861 if (some)
862   fprintf(f, "Other addresses were processed normally.\n");
863 else
864   fprintf(f, "No valid addresses were generated.\n");
865
866 (void)fclose(f);
867 child_close(pid, 0);  /* Waits for child to close; no timeout */
868
869 return TRUE;
870 }
871
872 /* End of moan.c */