-/* $Cambridge: exim/src/src/moan.c,v 1.1 2004/10/07 10:39:01 ph10 Exp $ */
+/* $Cambridge: exim/src/src/moan.c,v 1.10 2007/08/29 15:06:47 ph10 Exp $ */
/*************************************************
* Exim - an Internet mail transport agent *
*************************************************/
-/* Copyright (c) University of Cambridge 1995 - 2004 */
+/* Copyright (c) University of Cambridge 1995 - 2007 */
/* See the file NOTICE for conditions of use and distribution. */
/* Functions for sending messages to sender or to mailmaster. */
+/*************************************************
+* Write From: line for DSN *
+*************************************************/
+
+/* This function is called to write the From: line in automatically generated
+messages - bounces, warnings, etc. It expands a configuration item in order to
+get the text. If the expansion fails, a panic is logged and the default value
+for the option is used.
+
+Argument: the FILE to write to
+Returns: nothing
+*/
+
+void
+moan_write_from(FILE *f)
+{
+uschar *s = expand_string(dsn_from);
+if (s == NULL)
+ {
+ log_write(0, LOG_MAIN|LOG_PANIC,
+ "Failed to expand dsn_from (using default): %s", expand_string_message);
+ s = expand_string(US DEFAULT_DSN_FROM);
+ }
+fprintf(f, "From: %s\n", s);
+}
+
+
+
/*************************************************
* Send error message *
*************************************************/
f = fdopen(fd, "wb");
if (errors_reply_to != NULL) fprintf(f, "Reply-To: %s\n", errors_reply_to);
-fprintf(f, "Auto_submitted: auto-generated\n");
-fprintf(f, "From: Mail Delivery System <Mailer-Daemon@%s>\n",
- qualify_domain_sender);
+fprintf(f, "Auto-Submitted: auto-replied\n");
+moan_write_from(f);
fprintf(f, "To: %s\n", recipient);
switch(ident)
break;
}
-/* Now copy the message - headers then the rest of the input if
-available, up to the configured limit. */
-
-if (size_limit == 0 || size_limit > thismessage_size_limit)
- size_limit = thismessage_size_limit;
+/* Now, if configured, copy the message; first the headers and then the rest of
+the input if available, up to the configured limit, if the option for including
+message bodies in bounces is set. */
-if (size_limit > 0 && size_limit < message_size)
+if (bounce_return_message)
{
- int x = size_limit;
- uschar *k = US"";
- if ((x & 1023) == 0)
+ if (bounce_return_body)
{
- k = US"K";
- x >>= 10;
+ fprintf(f, "\n"
+ "------ This is a copy of your message, including all the headers.");
+ if (size_limit == 0 || size_limit > thismessage_size_limit)
+ size_limit = thismessage_size_limit;
+ if (size_limit > 0 && size_limit < message_size)
+ {
+ int x = size_limit;
+ uschar *k = US"";
+ if ((x & 1023) == 0)
+ {
+ k = US"K";
+ x >>= 10;
+ }
+ fprintf(f, "\n"
+ "------ No more than %d%s characters of the body are included.\n\n",
+ x, k);
+ }
+ else fprintf(f, " ------\n\n");
+ }
+ else
+ {
+ fprintf(f, "\n"
+ "------ This is a copy of the headers that were received before the "
+ "error\n was detected.\n\n");
}
- fprintf(f, "\n"
- "------ This is a copy of your message, including all the headers.\n"
- "------ No more than %d%s characters of the body are included.\n\n", x, k);
- }
-else fprintf(f, "\n"
- "------ This is a copy of your message, including all the headers. ------"
- "\n\n");
-/* If the error occurred before the Received: header was created, its text
-field will still be NULL; just omit such a header line. */
+ /* If the error occurred before the Received: header was created, its text
+ field will still be NULL; just omit such a header line. */
-while (headers != NULL)
- {
- if (headers->text != NULL) fprintf(f, "%s", CS headers->text);
- headers = headers->next;
- }
+ while (headers != NULL)
+ {
+ if (headers->text != NULL) fprintf(f, "%s", CS headers->text);
+ headers = headers->next;
+ }
-if (ident != ERRMESS_VLONGHEADER && ident != ERRMESS_VLONGHDRLINE)
- fputc('\n', f);
+ if (ident != ERRMESS_VLONGHEADER && ident != ERRMESS_VLONGHDRLINE)
+ fputc('\n', f);
-/* After early detection of an error, the message file may be STDIN,
-in which case we might have to terminate on a line containing just "."
-as well as on EOF. We may already have the first line in memory. */
+ /* After early detection of an error, the message file may be STDIN,
+ in which case we might have to terminate on a line containing just "."
+ as well as on EOF. We may already have the first line in memory. */
-if (message_file != NULL)
- {
- int ch;
- int state = 1;
- BOOL enddot = dot_ends && message_file == stdin;
- if (firstline != NULL) fprintf(f, "%s", CS firstline);
- while ((ch = fgetc(message_file)) != EOF)
+ if (bounce_return_body && message_file != NULL)
{
- fputc(ch, f);
- if (size_limit > 0 && ++written > size_limit) break;
- if (enddot)
+ int ch;
+ int state = 1;
+ BOOL enddot = dot_ends && message_file == stdin;
+ if (firstline != NULL) fprintf(f, "%s", CS firstline);
+ while ((ch = fgetc(message_file)) != EOF)
{
- if (state == 0) { if (ch == '\n') state = 1; }
- else if (state == 1)
- { if (ch == '.') state = 2; else if (ch != '\n') state = 0; }
- else
- { if (ch == '\n') break; else state = 0; }
+ fputc(ch, f);
+ if (size_limit > 0 && ++written > size_limit) break;
+ if (enddot)
+ {
+ if (state == 0) { if (ch == '\n') state = 1; }
+ else if (state == 1)
+ { if (ch == '.') state = 2; else if (ch != '\n') state = 0; }
+ else
+ { if (ch == '\n') break; else state = 0; }
+ }
}
}
}
/* Close the file, which should send an EOF to the child process
that is receiving the message. Wait for it to finish, without a timeout. */
-fclose(f);
+(void)fclose(f);
status = child_close(pid, 0); /* Waits for child to close */
if (status != 0)
{
}
f = fdopen(fd, "wb");
-fprintf(f, "Auto_submitted: auto-generated\n");
-fprintf(f, "From: Mail Delivery System <Mailer-Daemon@%s>\n",
- qualify_domain_sender);
+fprintf(f, "Auto-Submitted: auto-replied\n");
+moan_write_from(f);
fprintf(f, "To: %s\n", who);
fprintf(f, "Subject: %s\n\n", subject);
va_start(ap, format);
}
}
-fclose(f);
+(void)fclose(f);
child_close(pid, 0); /* Waits for child to close; no timeout */
}
length of the local part. */
localpart = recipient;
-domain = Ustrchr(recipient, '@');
+domain = Ustrrchr(recipient, '@');
if (domain == NULL) return NULL; /* should not occur, but avoid crash */
llen = domain++ - recipient;
if (match_address_list(recipient, TRUE, TRUE, &pattern, NULL, 0, UCHAR_MAX+1,
NULL) == OK)
{
- uschar temp[256];
- Ustrncpy(temp, localpart, llen);
- temp[llen] = 0;
- deliver_localpart = temp;
+ deliver_localpart = string_copyn(localpart, llen);
deliver_domain = domain;
yield = expand_string_copy(newaddress);
deliver_domain = deliver_localpart = NULL;
}
f = fdopen(fd, "wb");
-fprintf(f, "Auto_submitted: auto-generated\n");
-fprintf(f, "From: Mail Delivery System <Mailer-Daemon@%s>\n",
- qualify_domain_sender);
+fprintf(f, "Auto-Submitted: auto-replied\n");
+moan_write_from(f);
fprintf(f, "To: %s\n", s);
fprintf(f, "Subject: error(s) in forwarding or filtering\n\n");
else
fprintf(f, "No valid addresses were generated.\n");
-fclose(f);
+(void)fclose(f);
child_close(pid, 0); /* Waits for child to close; no timeout */
return TRUE;