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