X-Git-Url: https://git.exim.org/exim.git/blobdiff_plain/8c5d388a6e12d1a8bd4aa565920238f8a921414a..18481de384caecff421f23f715be916403f5d0ee:/src/src/receive.c diff --git a/src/src/receive.c b/src/src/receive.c index 585cb9025..f6bdf4742 100644 --- a/src/src/receive.c +++ b/src/src/receive.c @@ -2,7 +2,7 @@ * Exim - an Internet mail transport agent * *************************************************/ -/* Copyright (c) University of Cambridge 1995 - 2015 */ +/* Copyright (c) University of Cambridge 1995 - 2016 */ /* See the file NOTICE for conditions of use and distribution. */ /* Code for receiving a message and setting up spool files. */ @@ -23,7 +23,7 @@ extern int dcc_ok; static FILE *data_file = NULL; static int data_fd = -1; -static uschar spool_name[256]; +static uschar *spool_name = US""; @@ -525,7 +525,7 @@ static void smtp_user_msg(uschar *code, uschar *user_msg) { int len = 3; -smtp_message_code(&code, &len, &user_msg, NULL); +smtp_message_code(&code, &len, &user_msg, NULL, TRUE); smtp_respond(code, len, TRUE, user_msg); } #endif @@ -770,6 +770,9 @@ Arguments: Returns: One of the END_xxx values indicating why it stopped reading */ +/*XXX CHUNKING: maybe a variant routing specialised for BDAT, assuming +string RFC compliance ie. CRLF always? We still have to strip the CR +but we are not dealing with variant lunacy or looking for the end-dot */ static int read_message_data_smtp(FILE *fout) @@ -835,7 +838,15 @@ while ((ch = (receive_getc)()) != EOF) ch_state = 4; continue; } - ch_state = 1; /* The dot itself is removed */ + /* The dot was removed at state 3. For a doubled dot, here, reinstate + it to cutthrough. The current ch, dot or not, is passed both to cutthrough + and to file below. */ + if (ch == '.') + { + uschar c= ch; + (void) cutthrough_puts(&c, 1); + } + ch_state = 1; break; case 4: /* After [CR] LF . CR */ @@ -953,10 +964,12 @@ if (error_handling == ERRORS_SENDER) error_block eblock; eblock.next = NULL; eblock.text1 = text1; + eblock.text2 = US""; if (!moan_to_sender(errcode, &eblock, hptr, f, FALSE)) error_rc = EXIT_FAILURE; } -else fprintf(stderr, "exim: %s%s\n", text2, text1); /* Sic */ +else + fprintf(stderr, "exim: %s%s\n", text2, text1); /* Sic */ (void)fclose(f); exim_exit(error_rc); } @@ -1113,16 +1126,17 @@ Returns: the extended string */ static uschar * -add_host_info_for_log(uschar *s, int *sizeptr, int *ptrptr) +add_host_info_for_log(uschar * s, int * sizeptr, int * ptrptr) { -if (sender_fullhost != NULL) +if (sender_fullhost) { + if (LOGGING(dnssec) && sender_host_dnssec) /*XXX sender_helo_dnssec? */ + s = string_cat(s, sizeptr, ptrptr, US" DS"); s = string_append(s, sizeptr, ptrptr, 2, US" H=", sender_fullhost); if (LOGGING(incoming_interface) && interface_address != NULL) { - uschar *ss = string_sprintf(" I=[%s]:%d", interface_address, - interface_port); - s = string_cat(s, sizeptr, ptrptr, ss, Ustrlen(ss)); + s = string_cat(s, sizeptr, ptrptr, + string_sprintf(" I=[%s]:%d", interface_address, interface_port)); } } if (sender_ident != NULL) @@ -1279,10 +1293,12 @@ else if (rc != OK) #ifdef EXPERIMENTAL_DCC dcc_ok = 0; #endif - if (smtp_input && smtp_handle_acl_fail(ACL_WHERE_MIME, rc, user_msg, log_msg) != 0) { - *smtp_yield_ptr = FALSE; /* No more messsages after dropped connection */ + if ( smtp_input + && smtp_handle_acl_fail(ACL_WHERE_MIME, rc, user_msg, log_msg) != 0) + { + *smtp_yield_ptr = FALSE; /* No more messages after dropped connection */ *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 */ } @@ -1306,7 +1322,7 @@ if (recipients_count == 1) received_for = recipients_list[0].address; received = expand_string(received_header_text); received_for = NULL; -if (received == NULL) +if (!received) { if(spool_name[0] != 0) Uunlink(spool_name); /* Lose the data file */ @@ -1530,7 +1546,7 @@ yet, initialize the size and warning count, and deal with no size limit. */ message_id[0] = 0; data_file = NULL; data_fd = -1; -spool_name[0] = 0; +spool_name = US""; message_size = 0; warning_count = 0; received_count = 1; /* For the one we will add */ @@ -1600,6 +1616,7 @@ next->text. */ for (;;) { +/*XXX CHUNKING: account for BDAT size & last, and do more chunks as needed */ int ch = (receive_getc)(); /* If we hit EOF on a SMTP connection, it's an error, since incoming @@ -2459,7 +2476,7 @@ it will fit. */ to be the least significant base-62 digit of the time of arrival. Otherwise ensure that it is an empty string. */ -message_subdir[0] = split_spool_directory? message_id[5] : 0; +message_subdir[0] = split_spool_directory ? message_id[5] : 0; /* Now that we have the message-id, if there is no message-id: header, generate one, but only for local (without suppress_local_fixups) or submission mode @@ -2818,6 +2835,7 @@ if (filter_test != FTEST_NONE) return message_ended == END_DOT; } +/*XXX CHUNKING: need to cancel cutthrough under BDAT, for now */ /* Cutthrough delivery: We have to create the Received header now rather than at the end of reception, so the timestamp behaviour is a change to the normal case. @@ -2848,20 +2866,18 @@ if (cutthrough.fd >= 0) /* Open a new spool file for the data portion of the message. We need to access it both via a file descriptor and a stream. Try to make the -directory if it isn't there. Note re use of sprintf: spool_directory -is checked on input to be < 200 characters long. */ +directory if it isn't there. */ + +spool_name = spool_fname(US"input", message_subdir, message_id, US"-D"); +DEBUG(D_receive) debug_printf("Data file name: %s\n", spool_name); -sprintf(CS spool_name, "%s/input/%s/%s-D", spool_directory, message_subdir, - message_id); -data_fd = Uopen(spool_name, O_RDWR|O_CREAT|O_EXCL, SPOOL_MODE); -if (data_fd < 0) +if ((data_fd = Uopen(spool_name, O_RDWR|O_CREAT|O_EXCL, SPOOL_MODE)) < 0) { if (errno == ENOENT) { - uschar temp[16]; - sprintf(CS temp, "input/%s", message_subdir); - if (message_subdir[0] == 0) temp[5] = 0; - (void)directory_make(spool_directory, temp, INPUT_DIRECTORY_MODE, TRUE); + (void) directory_make(spool_directory, + spool_sname(US"input", message_subdir), + INPUT_DIRECTORY_MODE, TRUE); data_fd = Uopen(spool_name, O_RDWR|O_CREAT|O_EXCL, SPOOL_MODE); } if (data_fd < 0) @@ -2917,6 +2933,7 @@ if (!ferror(data_file) && !(receive_feof)() && message_ended != END_DOT) { if (smtp_input) { +/*XXX CHUNKING: main data read, for message body */ message_ended = read_message_data_smtp(data_file); receive_linecount++; /* The terminating "." line */ } @@ -3263,7 +3280,7 @@ else { Uunlink(spool_name); if (smtp_handle_acl_fail(ACL_WHERE_DKIM, rc, user_msg, log_msg) != 0) - smtp_yield = FALSE; /* No more messsages after dropped connection */ + smtp_yield = FALSE; /* No more messages after dropped connection */ smtp_reply = US""; /* Indicate reply already sent */ message_id[0] = 0; /* Indicate no message accepted */ goto TIDYUP; /* Skip to end of function */ @@ -3381,7 +3398,7 @@ else dcc_ok = 0; #endif if (smtp_handle_acl_fail(ACL_WHERE_DATA, rc, user_msg, log_msg) != 0) - smtp_yield = FALSE; /* No more messsages after dropped connection */ + smtp_yield = FALSE; /* No more messages after dropped connection */ smtp_reply = US""; /* Indicate reply already sent */ message_id[0] = 0; /* Indicate no message accepted */ goto TIDYUP; /* Skip to end of function */ @@ -3637,11 +3654,11 @@ signal(SIGINT, SIG_IGN); deliver_firsttime = TRUE; #ifdef EXPERIMENTAL_BRIGHTMAIL -if (bmi_run == 1) { - /* rewind data file */ +if (bmi_run == 1) + { /* rewind data file */ lseek(data_fd, (long int)SPOOL_DATA_START_OFFSET, SEEK_SET); bmi_verdicts = bmi_process_message(header_list, data_fd); -}; + } #endif /* Update the timstamp in our Received: header to account for any time taken by @@ -3679,7 +3696,6 @@ if (host_checking || blackholed_by != NULL) /* Write the -H file */ else - { if ((msg_size = spool_write_header(message_id, SW_RECEIVING, &errmsg)) < 0) { log_write(0, LOG_MAIN, "Message abandoned: %s", errmsg); @@ -3699,7 +3715,6 @@ else /* Does not return */ } } - } /* The message has now been successfully received. */ @@ -3793,6 +3808,9 @@ if (LOGGING(8bitmime)) s = string_append(s, &size, &sptr, 2, US" M8S=", big_buffer); } +if (*queue_name) + s = string_append(s, &size, &sptr, 2, US" Q=", queue_name); + /* If an addr-spec in a message-id contains a quoted string, it can contain any characters except " \ and CR and so in particular it can contain NL! Therefore, make sure we use a printing-characters only version for the log. @@ -3847,16 +3865,15 @@ if (message_logs && blackholed_by == NULL) { int fd; - sprintf(CS spool_name, "%s/msglog/%s/%s", spool_directory, message_subdir, - message_id); - fd = Uopen(spool_name, O_WRONLY|O_APPEND|O_CREAT, SPOOL_MODE); - - if (fd < 0 && errno == ENOENT) + spool_name = spool_fname(US"msglog", message_subdir, message_id, US""); + + if ( (fd = Uopen(spool_name, O_WRONLY|O_APPEND|O_CREAT, SPOOL_MODE)) < 0 + && errno == ENOENT + ) { - uschar temp[16]; - sprintf(CS temp, "msglog/%s", message_subdir); - if (message_subdir[0] == 0) temp[6] = 0; - (void)directory_make(spool_directory, temp, MSGLOG_DIRECTORY_MODE, TRUE); + (void)directory_make(spool_directory, + spool_sname(US"msglog", message_subdir), + MSGLOG_DIRECTORY_MODE, TRUE); fd = Uopen(spool_name, O_WRONLY|O_APPEND|O_CREAT, SPOOL_MODE); } @@ -3934,24 +3951,16 @@ if (smtp_input && sender_host_address != NULL && !sender_host_notsocket && /* Re-use the log line workspace */ sptr = 0; - s = string_cat(s, &size, &sptr, msg, Ustrlen(msg)); + s = string_cat(s, &size, &sptr, msg); s = add_host_info_for_log(s, &size, &sptr); s[sptr] = 0; log_write(0, LOG_MAIN, "%s", s); /* Delete the files for this aborted message. */ - sprintf(CS spool_name, "%s/input/%s/%s-D", spool_directory, - message_subdir, message_id); - Uunlink(spool_name); - - sprintf(CS spool_name, "%s/input/%s/%s-H", spool_directory, - message_subdir, message_id); - Uunlink(spool_name); - - sprintf(CS spool_name, "%s/msglog/%s/%s", spool_directory, - message_subdir, message_id); - Uunlink(spool_name); + Uunlink(spool_fname(US"input", message_subdir, message_id, US"-D")); + Uunlink(spool_fname(US"input", message_subdir, message_id, US"-H")); + Uunlink(spool_fname(US"msglog", message_subdir, message_id, US"")); goto TIDYUP; } @@ -3975,7 +3984,7 @@ for this message. */ */ if(cutthrough.fd >= 0) { - uschar * msg= cutthrough_finaldot(); /* Ask the target system to accept the messsage */ + uschar * msg= cutthrough_finaldot(); /* Ask the target system to accept the message */ /* Logging was done in finaldot() */ switch(msg[0]) { @@ -4078,7 +4087,7 @@ if (smtp_input) { uschar *code = US"250"; int len = 3; - smtp_message_code(&code, &len, &user_msg, NULL); + smtp_message_code(&code, &len, &user_msg, NULL, TRUE); smtp_respond(code, len, TRUE, user_msg); } @@ -4105,16 +4114,11 @@ if (smtp_input) switch (cutthrough_done) { case ACCEPTED: log_write(0, LOG_MAIN, "Completed");/* Delivery was done */ - case PERM_REJ: { /* Delete spool files */ - sprintf(CS spool_name, "%s/input/%s/%s-D", spool_directory, - message_subdir, message_id); - Uunlink(spool_name); - sprintf(CS spool_name, "%s/input/%s/%s-H", spool_directory, - message_subdir, message_id); - Uunlink(spool_name); - sprintf(CS spool_name, "%s/msglog/%s/%s", spool_directory, - message_subdir, message_id); - Uunlink(spool_name); + case PERM_REJ: + { /* Delete spool files */ + Uunlink(spool_fname(US"input", message_subdir, message_id, US"-D")); + Uunlink(spool_fname(US"input", message_subdir, message_id, US"-H")); + Uunlink(spool_fname(US"msglog", message_subdir, message_id, US"")); } case TMP_REJ: message_id[0] = 0; /* Prevent a delivery from starting */ default:break;