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