+/* make sure the eml mbox file is spooled up */
+if (!(mbox_file = spool_mbox(&mbox_size, NULL, &mbox_filename)))
+ { /* error while spooling */
+ log_write(0, LOG_MAIN|LOG_PANIC,
+ "acl_smtp_mime: error while creating mbox spool file, message temporarily rejected.");
+ Uunlink(spool_name);
+ unspool_mbox();
+#ifdef EXPERIMENTAL_DCC
+ dcc_ok = 0;
+#endif
+ 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 */
+ }
+
+mime_is_rfc822 = 0;
+
+MIME_ACL_CHECK:
+mime_part_count = -1;
+rc = mime_acl_check(acl, mbox_file, NULL, &user_msg, &log_msg);
+(void)fclose(mbox_file);
+
+if (rfc822_file_path)
+ {
+ mime_part_count = mime_part_count_buffer;
+
+ 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;
+ }
+ rfc822_file_path = NULL;
+ }
+
+/* check if we must check any message/rfc822 attachments */
+if (rc == OK)
+ {
+ uschar * scandir = string_copyn(mbox_filename,
+ Ustrrchr(mbox_filename, '/') - mbox_filename);
+ struct dirent * entry;
+ DIR * tempdir;
+
+ for (tempdir = exim_opendir(scandir); entry = readdir(tempdir); )
+ if (strncmpic(US entry->d_name, US"__rfc822_", 9) == 0)
+ {
+ rfc822_file_path = string_sprintf("%s/%s", scandir, entry->d_name);
+ DEBUG(D_receive)
+ debug_printf("RFC822 attachment detected: running MIME ACL for '%s'\n",
+ rfc822_file_path);
+ break;
+ }
+ closedir(tempdir);
+
+ if (rfc822_file_path)
+ {
+ if ((mbox_file = Ufopen(rfc822_file_path, "rb")))
+ {
+ /* set RFC822 expansion variable */
+ mime_is_rfc822 = 1;
+ mime_part_count_buffer = mime_part_count;
+ goto MIME_ACL_CHECK;
+ }
+ log_write(0, LOG_PANIC,
+ "acl_smtp_mime: can't open RFC822 spool file, skipping.");
+ unlink(CS rfc822_file_path);
+ }
+ }
+
+END_MIME_ACL:
+add_acl_headers(ACL_WHERE_MIME, US"MIME");
+if (rc == DISCARD)
+ {
+ recipients_count = 0;
+ *blackholed_by_ptr = US"MIME ACL";
+ cancel_cutthrough_connection(TRUE, US"mime acl discard");
+ }
+else if (rc != OK)
+ {
+ Uunlink(spool_name);
+ cancel_cutthrough_connection(TRUE, US"mime acl not ok");
+ unspool_mbox();
+#ifdef EXPERIMENTAL_DCC
+ dcc_ok = 0;
+#endif
+ if (smtp_input)
+ {
+ if (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 */
+ }
+
+return TRUE;
+}
+
+#endif /* WITH_CONTENT_SCAN */
+
+
+
+void
+received_header_gen(void)
+{
+uschar * received;
+uschar * timestamp = expand_string(US"${tod_full}");
+header_line * received_header= header_list;
+
+if (recipients_count == 1) received_for = recipients_list[0].address;
+received = expand_string(received_header_text);
+received_for = NULL;
+
+if (!received)
+ {
+ if(spool_name[0] != 0)
+ Uunlink(spool_name); /* Lose the data file */
+ log_write(0, LOG_MAIN|LOG_PANIC_DIE, "Expansion of \"%s\" "
+ "(received_header_text) failed: %s", string_printing(received_header_text),
+ expand_string_message);
+ }
+
+/* The first element on the header chain is reserved for the Received header,
+so all we have to do is fill in the text pointer, and set the type. However, if
+the result of the expansion is an empty string, we leave the header marked as
+"old" so as to refrain from adding a Received header. */
+
+if (!received[0])
+ {
+ received_header->text = string_sprintf("Received: ; %s\n", timestamp);
+ received_header->type = htype_old;
+ }
+else
+ {
+ received_header->text = string_sprintf("%s;\n\t%s\n", received, timestamp);
+ received_header->type = htype_received;
+ }
+
+received_header->slen = Ustrlen(received_header->text);
+
+DEBUG(D_receive) debug_printf(">>Generated Received: header line\n%c %s",
+ received_header->type, received_header->text);
+}
+
+
+
+/*************************************************
+* Receive message *
+*************************************************/
+
+/* Receive a message on the given input, and put it into a pair of spool files.
+Either a non-null list of recipients, or the extract flag will be true, or
+both. The flag sender_local is true for locally generated messages. The flag
+submission_mode is true if an ACL has obeyed "control = submission". The flag
+suppress_local_fixups is true if an ACL has obeyed "control =
+suppress_local_fixups" or -G was passed on the command-line.
+The flag smtp_input is true if the message is to be
+handled using SMTP conventions about termination and lines starting with dots.
+For non-SMTP messages, dot_ends is true for dot-terminated messages.
+
+If a message was successfully read, message_id[0] will be non-zero.
+
+The general actions of this function are:
+
+ . Read the headers of the message (if any) into a chain of store
+ blocks.
+
+ . If there is a "sender:" header and the message is locally originated,
+ throw it away, unless the caller is trusted, or unless
+ active_local_sender_retain is set - which can only happen if
+ active_local_from_check is false.
+
+ . If recipients are to be extracted from the message, build the
+ recipients list from the headers, removing any that were on the
+ original recipients list (unless extract_addresses_remove_arguments is
+ false), and at the same time, remove any bcc header that may be present.
+
+ . Get the spool file for the data, sort out its unique name, open