-/* $Cambridge: exim/src/src/receive.c,v 1.26 2006/02/14 15:11:43 ph10 Exp $ */
+/* $Cambridge: exim/src/src/receive.c,v 1.34 2007/02/16 22:23:35 magnus Exp $ */
/*************************************************
* Exim - an Internet mail transport agent *
*************************************************/
-/* Copyright (c) University of Cambridge 1995 - 2006 */
+/* Copyright (c) University of Cambridge 1995 - 2007 */
/* See the file NOTICE for conditions of use and distribution. */
/* Code for receiving a message and setting up spool files. */
header_line *h, *next;
header_line *last_received = NULL;
-if (acl_warn_headers == NULL) return;
+if (acl_added_headers == NULL) return;
DEBUG(D_receive|D_acl) debug_printf(">>Headers added by %s ACL:\n", acl_name);
-for (h = acl_warn_headers; h != NULL; h = next)
+for (h = acl_added_headers; h != NULL; h = next)
{
next = h->next;
DEBUG(D_receive|D_acl) debug_printf(" %s", header_last->text);
}
-acl_warn_headers = NULL;
+acl_added_headers = NULL;
DEBUG(D_receive|D_acl) debug_printf(">>\n");
}
/* check if it is a MIME message */
my_headerlist = header_list;
-while (my_headerlist != NULL) {
+while (my_headerlist != NULL)
+ {
/* skip deleted headers */
- if (my_headerlist->type == '*') {
+ if (my_headerlist->type == '*')
+ {
my_headerlist = my_headerlist->next;
continue;
- };
- if (strncmpic(my_headerlist->text, US"Content-Type:", 13) == 0) {
+ }
+ if (strncmpic(my_headerlist->text, US"Content-Type:", 13) == 0)
+ {
DEBUG(D_receive) debug_printf("Found Content-Type: header - executing acl_smtp_mime.\n");
goto DO_MIME_ACL;
- };
+ }
my_headerlist = my_headerlist->next;
-};
+ }
DEBUG(D_receive) debug_printf("No Content-Type: header - presumably not a MIME message.\n");
return TRUE;
"acl_smtp_mime: error while creating mbox spool file, message temporarily rejected.");
Uunlink(spool_name);
unspool_mbox();
- smtp_respond(451, TRUE, US"temporary local problem");
+ smtp_respond(US"451", 3, TRUE, US"temporary local problem");
message_id[0] = 0; /* Indicate no message accepted */
*smtp_reply_ptr = US""; /* Indicate reply already sent */
return FALSE; /* Indicate skip to end of receive function */
rc = mime_acl_check(acl, mbox_file, NULL, &user_msg, &log_msg);
(void)fclose(mbox_file);
-if (Ustrlen(rfc822_file_path) > 0) {
+if (Ustrlen(rfc822_file_path) > 0)
+ {
mime_part_count = mime_part_count_buffer;
- if (unlink(CS rfc822_file_path) == -1) {
+ if (unlink(CS rfc822_file_path) == -1)
+ {
log_write(0, LOG_PANIC,
"acl_smtp_mime: can't unlink RFC822 spool file, skipping.");
goto END_MIME_ACL;
- };
-};
+ }
+ }
/* check if we must check any message/rfc822 attachments */
-if (rc == OK) {
+if (rc == OK)
+ {
uschar temp_path[1024];
int n;
struct dirent *entry;
(void)string_format(temp_path, 1024, "%s/scan/%s", spool_directory,
message_id);
- tempdir = opendir(CS temp_path);
- n = 0;
- do {
- entry = readdir(tempdir);
- if (entry == NULL) break;
- if (strncmpic(US entry->d_name,US"__rfc822_",9) == 0) {
+ tempdir = opendir(CS temp_path);
+ n = 0;
+ do
+ {
+ entry = readdir(tempdir);
+ if (entry == NULL) break;
+ if (strncmpic(US entry->d_name,US"__rfc822_",9) == 0)
+ {
(void)string_format(rfc822_file_path, 2048,"%s/scan/%s/%s", spool_directory, message_id, entry->d_name);
- debug_printf("RFC822 attachment detected: running MIME ACL for '%s'\n", rfc822_file_path);
- break;
- };
- } while (1);
- closedir(tempdir);
+ debug_printf("RFC822 attachment detected: running MIME ACL for '%s'\n", rfc822_file_path);
+ break;
+ }
+ } while (1);
+ closedir(tempdir);
- if (entry != NULL) {
+ if (entry != NULL)
+ {
mbox_file = Ufopen(rfc822_file_path,"rb");
- if (mbox_file == NULL) {
+ if (mbox_file == NULL)
+ {
log_write(0, LOG_PANIC,
"acl_smtp_mime: can't open RFC822 spool file, skipping.");
unlink(CS rfc822_file_path);
goto END_MIME_ACL;
- };
+ }
/* set RFC822 expansion variable */
mime_is_rfc822 = 1;
mime_part_count_buffer = mime_part_count;
goto MIME_ACL_CHECK;
- };
-};
+ }
+ }
END_MIME_ACL:
add_acl_headers(US"MIME");
*smtp_reply_ptr = US""; /* Indicate reply already sent */
message_id[0] = 0; /* Indicate no message accepted */
return FALSE; /* Cause skip to end of receive function */
- };
+ }
return TRUE;
}
uschar *errmsg, *s;
struct stat statbuf;
-/* Final message to give to SMTP caller */
+/* Final message to give to SMTP caller, and messages from ACLs */
uschar *smtp_reply = NULL;
+uschar *user_msg, *log_msg;
/* Working header pointers */
recipients_count = recipients_list_max = 0;
}
- parse_allow_group = TRUE; /* Allow address group syntax */
-
/* Now scan the headers */
for (h = header_list->next; h != NULL; h = h->next)
uschar *s = Ustrchr(h->text, ':') + 1;
while (isspace(*s)) s++;
+ parse_allow_group = TRUE; /* Allow address group syntax */
+
while (*s != 0)
{
uschar *ss = parse_find_address_end(s, FALSE);
s = ss + (*ss? 1:0);
while (isspace(*s)) s++;
- }
+ } /* Next address */
+
+ parse_allow_group = FALSE; /* Reset group syntax flags */
+ parse_found_group = FALSE;
/* If this was the bcc: header, mark it "old", which means it
will be kept on the spool, but not transmitted as part of the
} /* For appropriate header line */
} /* For each header line */
- parse_allow_group = FALSE; /* Reset group syntax flags */
- parse_found_group = FALSE;
}
/* Now build the unique message id. This has changed several times over the
anything until the terminating dot line is sent. */
if (fflush(data_file) == EOF || ferror(data_file) ||
- fsync(fileno(data_file)) < 0 || (receive_ferror)())
+ EXIMfsync(fileno(data_file)) < 0 || (receive_ferror)())
{
uschar *msg_errno = US strerror(errno);
BOOL input_error = (receive_ferror)() != 0;
*/
deliver_datafile = data_fd;
+user_msg = NULL;
+
+enable_dollar_recipients = TRUE;
if (recipients_count == 0)
{
}
else
{
- enable_dollar_recipients = TRUE;
-
/* Handle interactive SMTP messages */
if (smtp_input && !smtp_batched_input)
if (acl_smtp_data != NULL && recipients_count > 0)
{
- uschar *user_msg, *log_msg;
rc = acl_check(ACL_WHERE_DATA, NULL, acl_smtp_data, &user_msg, &log_msg);
add_acl_headers(US"DATA");
if (rc == DISCARD)
#ifdef WITH_CONTENT_SCAN
unspool_mbox();
#endif
- log_write(0, LOG_MAIN|LOG_REJECT, "F=<%s> rejected by non-SMTP ACL: %s",
- sender_address, log_msg);
+ /* The ACL can specify where rejections are to be logged, possibly
+ nowhere. The default is main and reject logs. */
+
+ if (log_reject_target != 0)
+ log_write(0, log_reject_target, "F=<%s> rejected by non-SMTP ACL: %s",
+ sender_address, log_msg);
+
if (user_msg == NULL) user_msg = US"local configuration problem";
if (smtp_batched_input)
{
if (deliver_freeze) frozen_by = US"ACL"; /* for later logging */
if (queue_only_policy) queued_by = US"ACL";
-
- enable_dollar_recipients = FALSE;
}
#ifdef WITH_CONTENT_SCAN
alarm(0);
os_non_restarting_signal(SIGALRM, sigalrm_handler);
+enable_dollar_recipients = FALSE;
+
store_pool = POOL_MAIN; /* In case changed */
DEBUG(D_receive) debug_printf("local_scan() returned %d %s\n", rc,
local_scan_data);
{
uschar *istemp = US"";
uschar *s = NULL;
+ uschar *smtp_code;
int size = 0;
int sptr = 0;
- int code;
errmsg = local_scan_data;
/* Fall through */
case LOCAL_SCAN_REJECT:
- code = 550;
+ smtp_code = US"550";
if (errmsg == NULL) errmsg = US"Administrative prohibition";
break;
case LOCAL_SCAN_TEMPREJECT:
TEMPREJECT:
- code = 451;
+ smtp_code = US"451";
if (errmsg == NULL) errmsg = US"Temporary local problem";
istemp = US"temporarily ";
break;
{
if (!smtp_batched_input)
{
- smtp_respond(code, TRUE, errmsg);
+ smtp_respond(smtp_code, 3, TRUE, errmsg);
message_id[0] = 0; /* Indicate no message accepted */
smtp_reply = US""; /* Indicate reply already sent */
goto TIDYUP; /* Skip to end of function */
}
else
{
- moan_smtp_batch(NULL, "%d %s", code, errmsg);
+ moan_smtp_batch(NULL, "%s %s", smtp_code, errmsg);
/* Does not return */
}
}
if (smtp_reply == NULL)
{
if (fake_response != OK)
- smtp_respond(fake_response == DEFER ? 450 : 550,
- TRUE, fake_response_text);
+ smtp_respond((fake_response == DEFER)? US"450" : US"550", 3, TRUE,
+ fake_response_text);
+
+ /* An OK response is required; use "message" text if present. */
+
+ else if (user_msg != NULL)
+ {
+ uschar *code = US"250";
+ int len = 3;
+ smtp_message_code(&code, &len, &user_msg, NULL);
+ smtp_respond(code, len, TRUE, user_msg);
+ }
+
+ /* Default OK response */
+
else
smtp_printf("250 OK id=%s\r\n", message_id);
if (host_checking)
fprintf(stdout,
"\n**** SMTP testing: that is not a real message id!\n\n");
}
+
+ /* smtp_reply was previously set */
+
else if (smtp_reply[0] != 0)
{
if (fake_response != OK && (smtp_reply[0] == '2'))
- smtp_respond(fake_response == DEFER ? 450 : 550,
- TRUE, fake_response_text);
+ smtp_respond((fake_response == DEFER)? US"450" : US"550", 3, TRUE,
+ fake_response_text);
else
smtp_printf("%.1024s\r\n", smtp_reply);
}