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