X-Git-Url: https://vcs.fsf.org/?a=blobdiff_plain;f=src%2Fsrc%2Fmoan.c;h=6c04f7a570560a5f8d465e55ba935eed916de279;hb=82c6910a112610ac5c121ff5321365c5dc7e8eb2;hp=89a9b847d0bb0b7eab2cf3446f22f00d81bcfec1;hpb=059ec3d9952740285fb1ebf47961b8aca2eb1b4a;p=exim.git diff --git a/src/src/moan.c b/src/src/moan.c index 89a9b847d..6c04f7a57 100644 --- a/src/src/moan.c +++ b/src/src/moan.c @@ -1,10 +1,8 @@ -/* $Cambridge: exim/src/src/moan.c,v 1.1 2004/10/07 10:39:01 ph10 Exp $ */ - /************************************************* * Exim - an Internet mail transport agent * *************************************************/ -/* Copyright (c) University of Cambridge 1995 - 2004 */ +/* Copyright (c) University of Cambridge 1995 - 2009 */ /* See the file NOTICE for conditions of use and distribution. */ /* Functions for sending messages to sender or to mailmaster. */ @@ -14,6 +12,34 @@ +/************************************************* +* 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 * *************************************************/ @@ -61,9 +87,8 @@ else DEBUG(D_any) debug_printf("Child process %d for sending message\n", pid); 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 \n", - qualify_domain_sender); +fprintf(f, "Auto-Submitted: auto-replied\n"); +moan_write_from(f); fprintf(f, "To: %s\n", recipient); switch(ident) @@ -185,62 +210,74 @@ switch(ident) break; } -/* Now copy the message - headers then the rest of the input if -available, up to the configured 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 > thismessage_size_limit) - size_limit = thismessage_size_limit; - -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; } + } } } } @@ -248,7 +285,7 @@ if (message_file != NULL) /* 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) { @@ -398,8 +435,8 @@ Returns: nothing */ void -moan_tell_someone(uschar *who, address_item *addr, uschar *subject, - char *format, ...) +moan_tell_someone(uschar *who, address_item *addr, + const uschar *subject, const char *format, ...) { FILE *f; va_list ap; @@ -414,9 +451,8 @@ if (pid < 0) } f = fdopen(fd, "wb"); -fprintf(f, "Auto_submitted: auto-generated\n"); -fprintf(f, "From: Mail Delivery System \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); @@ -437,7 +473,7 @@ if (addr != NULL) } } -fclose(f); +(void)fclose(f); child_close(pid, 0); /* Waits for child to close; no timeout */ } @@ -467,7 +503,7 @@ Returns: does not return; exits from the program */ void -moan_smtp_batch(uschar *cmd_buffer, char *format, ...) +moan_smtp_batch(uschar *cmd_buffer, const char *format, ...) { va_list ap; int yield = (receive_messagecount > 0)? 1 : 2; @@ -546,7 +582,7 @@ if (errors_copy == NULL) return NULL; 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; @@ -572,10 +608,7 @@ while ((item = string_nextinlist(&listptr, &sep, buffer, sizeof(buffer))) 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; @@ -658,9 +691,8 @@ if (pid < 0) } f = fdopen(fd, "wb"); -fprintf(f, "Auto_submitted: auto-generated\n"); -fprintf(f, "From: Mail Delivery System \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"); @@ -692,7 +724,7 @@ if (some) 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;