X-Git-Url: https://git.exim.org/exim.git/blobdiff_plain/e6d2a9894df8c3b65920e903ab21076a0a37e20e..5aba2a452669cc19defd5732e2512984ecd1603e:/src/src/receive.c diff --git a/src/src/receive.c b/src/src/receive.c index dc228d921..c783cedfd 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. */ @@ -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 @@ -835,7 +835,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 +961,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); } @@ -1122,7 +1132,7 @@ if (sender_fullhost != 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, ss); } } if (sender_ident != NULL) @@ -1279,10 +1289,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 +1318,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 */ @@ -2303,7 +2315,7 @@ if (extract_recip) for (p = s; p < ss; p++) if (*p != '\n') *pp++ = *p; *pp = 0; -#ifdef EXPERIMENTAL_INTERNATIONAL +#ifdef SUPPORT_I18N { BOOL b = allow_utf8_domains; allow_utf8_domains = TRUE; @@ -2311,7 +2323,7 @@ if (extract_recip) recipient = parse_extract_address(recipient, &errmess, &start, &end, &domain, FALSE); -#ifdef EXPERIMENTAL_INTERNATIONAL +#ifdef SUPPORT_I18N if (string_is_utf8(recipient)) message_smtputf8 = TRUE; else @@ -2459,7 +2471,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 @@ -2851,16 +2863,17 @@ 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. */ -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) +snprintf(CS spool_name, sizeof(spool_name), "%s/input/%s/%s/%s-D", + spool_directory, queue_name, message_subdir, message_id); +DEBUG(D_receive) debug_printf("Data file name: %s\n", spool_name); + +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; + uschar * temp = string_sprintf("input%s%s%s%s", + *queue_name ? "/" : "", queue_name, + *message_subdir ? "/" : "", message_subdir); (void)directory_make(spool_directory, temp, INPUT_DIRECTORY_MODE, TRUE); data_fd = Uopen(spool_name, O_RDWR|O_CREAT|O_EXCL, SPOOL_MODE); } @@ -3263,7 +3276,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 +3394,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 +3650,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 +3692,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 +3711,6 @@ else /* Does not return */ } } - } /* The message has now been successfully received. */ @@ -3793,6 +3804,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,15 +3861,16 @@ 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) + snprintf(CS spool_name, sizeof(spool_name), "%s/msglog/%s/%s/%s", + spool_directory, queue_name, message_subdir, message_id); + + 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; + uschar * temp = string_sprintf("msglog%s%s%s%s", + *queue_name ? "/" : "", queue_name, + *message_subdir ? "/" : "", message_subdir); (void)directory_make(spool_directory, temp, MSGLOG_DIRECTORY_MODE, TRUE); fd = Uopen(spool_name, O_WRONLY|O_APPEND|O_CREAT, SPOOL_MODE); } @@ -3934,23 +3949,23 @@ 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); + snprintf(CS spool_name, sizeof(spool_name), "%s/input/%s/%s/%s-D", + spool_directory, queue_name, message_subdir, message_id); Uunlink(spool_name); - sprintf(CS spool_name, "%s/input/%s/%s-H", spool_directory, - message_subdir, message_id); + snprintf(CS spool_name, sizeof(spool_name), "%s/input/%s/%s/%s-H", + spool_directory, queue_name, message_subdir, message_id); Uunlink(spool_name); - sprintf(CS spool_name, "%s/msglog/%s/%s", spool_directory, - message_subdir, message_id); + snprintf(CS spool_name, sizeof(spool_name), "%s/msglog/%s/%s/%s", + spool_directory, queue_name, message_subdir, message_id); Uunlink(spool_name); goto TIDYUP; @@ -3975,7 +3990,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 +4093,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); } @@ -4106,14 +4121,14 @@ if (smtp_input) { 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); + snprintf(CS spool_name, sizeof(spool_name), "%s/input/%s/%s/%s-D", + spool_directory, queue_name, message_subdir, message_id); Uunlink(spool_name); - sprintf(CS spool_name, "%s/input/%s/%s-H", spool_directory, - message_subdir, message_id); + snprintf(CS spool_name, sizeof(spool_name), "%s/input/%s/%s/%s-H", + spool_directory, queue_name, message_subdir, message_id); Uunlink(spool_name); - sprintf(CS spool_name, "%s/msglog/%s/%s", spool_directory, - message_subdir, message_id); + snprintf(CS spool_name, sizeof(spool_name), "%s/msglog/%s/%s/%s", + spool_directory, queue_name, message_subdir, message_id); Uunlink(spool_name); } case TMP_REJ: message_id[0] = 0; /* Prevent a delivery from starting */