X-Git-Url: https://vcs.fsf.org/?p=exim.git;a=blobdiff_plain;f=src%2Fsrc%2Fspool_mbox.c;h=16b0a332cc73bdd4c1c95bfb477199cfbce34f21;hp=357eba9da2fcd22bcfaf7922157197c443de05e4;hb=refs%2Ftags%2Fexim-4_90_RC1;hpb=80fea873648ca2ab2e592999a336c59cf054ab55 diff --git a/src/src/spool_mbox.c b/src/src/spool_mbox.c index 357eba9da..16b0a332c 100644 --- a/src/src/spool_mbox.c +++ b/src/src/spool_mbox.c @@ -4,7 +4,7 @@ /* Copyright (c) Tom Kistner 2003 - 2015 * License: GPL - * Copyright (c) The Exim Maintainers 2016 + * Copyright (c) The Exim Maintainers 2017 */ /* Code for setting up a MBOX style spool file inside a /scan/ @@ -13,23 +13,23 @@ sub directory of exim's spool directory. */ #include "exim.h" #ifdef WITH_CONTENT_SCAN -/* externals, we must reset them on unspooling */ -#ifdef WITH_OLD_DEMIME -extern int demime_ok; -extern struct file_extension *file_extensions; -#endif - extern int malware_ok; extern int spam_ok; int spool_mbox_ok = 0; uschar spooled_message_id[MESSAGE_ID_LENGTH+1]; -/* returns a pointer to the FILE, and puts the size in bytes into mbox_file_size - * normally, source_file_override is NULL */ +/* +Create an MBOX-style message file from the spooled files. + +Returns a pointer to the FILE, and puts the size in bytes into mbox_file_size. +If mbox_fname is non-null, fill in a pointer to the name. +Normally, source_file_override is NULL +*/ FILE * -spool_mbox(unsigned long *mbox_file_size, const uschar *source_file_override) +spool_mbox(unsigned long *mbox_file_size, const uschar *source_file_override, + uschar ** mbox_fname) { uschar message_subdir[2]; uschar buffer[16384]; @@ -41,10 +41,13 @@ FILE *yield = NULL; header_line *my_headerlist; struct stat statbuf; int i, j; -void *reset_point = store_get(0); +void *reset_point; + +mbox_path = string_sprintf("%s/scan/%s/%s.eml", + spool_directory, message_id, message_id); +if (mbox_fname) *mbox_fname = mbox_path; -mbox_path = string_sprintf("%s/scan/%s/%s.eml", spool_directory, message_id, - message_id); +reset_point = store_get(0); /* Skip creation if already spooled out as mbox file */ if (!spool_mbox_ok) @@ -59,8 +62,8 @@ if (!spool_mbox_ok) } /* open [message_id].eml file for writing */ - mbox_file = modefopen(mbox_path, "wb", SPOOL_MODE); - if (mbox_file == NULL) + + if (!(mbox_file = modefopen(mbox_path, "wb", SPOOL_MODE))) { log_write(0, LOG_MAIN|LOG_PANIC, "%s", string_open_failed(errno, "scan file %s", mbox_path)); @@ -77,33 +80,25 @@ if (!spool_mbox_ok) "${if def:sender_address{X-Envelope-From: <${sender_address}>\n}}" "${if def:recipients{X-Envelope-To: ${recipients}\n}}"); - if (temp_string != NULL) - { - i = fwrite(temp_string, Ustrlen(temp_string), 1, mbox_file); - if (i != 1) + if (temp_string) + if (fwrite(temp_string, Ustrlen(temp_string), 1, mbox_file) != 1) { log_write(0, LOG_MAIN|LOG_PANIC, "Error/short write while writing \ mailbox headers to %s", mbox_path); goto OUT; } - } - /* write all header lines to mbox file */ - my_headerlist = header_list; - for (my_headerlist = header_list; my_headerlist != NULL; - my_headerlist = my_headerlist->next) - { - /* skip deleted headers */ - if (my_headerlist->type == '*') continue; + /* write all non-deleted header lines to mbox file */ - i = fwrite(my_headerlist->text, my_headerlist->slen, 1, mbox_file); - if (i != 1) - { - log_write(0, LOG_MAIN|LOG_PANIC, "Error/short write while writing \ - message headers to %s", mbox_path); - goto OUT; - } - } + for (my_headerlist = header_list; my_headerlist; + my_headerlist = my_headerlist->next) + if (my_headerlist->type != '*') + if (fwrite(my_headerlist->text, my_headerlist->slen, 1, mbox_file) != 1) + { + log_write(0, LOG_MAIN|LOG_PANIC, "Error/short write while writing \ + message headers to %s", mbox_path); + goto OUT; + } /* End headers */ if (fwrite("\n", 1, 1, mbox_file) != 1) @@ -114,22 +109,20 @@ if (!spool_mbox_ok) } /* copy body file */ - if (source_file_override == NULL) + if (!source_file_override) { message_subdir[1] = '\0'; for (i = 0; i < 2; i++) { - message_subdir[0] = (split_spool_directory == (i == 0))? message_id[5] : 0; - temp_string = string_sprintf("%s/input/%s/%s-D", spool_directory, - message_subdir, message_id); - data_file = Ufopen(temp_string, "rb"); - if (data_file != NULL) break; + message_subdir[0] = split_spool_directory == (i == 0) ? message_id[5] : 0; + temp_string = spool_fname(US"input", message_subdir, message_id, US"-D"); + if ((data_file = Ufopen(temp_string, "rb"))) break; } } else data_file = Ufopen(source_file_override, "rb"); - if (data_file == NULL) + if (!data_file) { log_write(0, LOG_MAIN|LOG_PANIC, "Could not open datafile for message %s", message_id); @@ -150,18 +143,32 @@ if (!spool_mbox_ok) do { - j = fread(buffer, 1, sizeof(buffer), data_file); + uschar * s; + + if (!spool_file_wireformat || source_file_override) + j = fread(buffer, 1, sizeof(buffer), data_file); + else /* needs CRLF -> NL */ + if ((s = US fgets(CS buffer, sizeof(buffer), data_file))) + { + uschar * p = s + Ustrlen(s) - 1; + + if (*p == '\n' && p[-1] == '\r') + *--p = '\n'; + else if (*p == '\r') + ungetc(*p--, data_file); + + j = p - buffer; + } + else + j = 0; if (j > 0) - { - i = fwrite(buffer, j, 1, mbox_file); - if (i != 1) + if (fwrite(buffer, j, 1, mbox_file) != 1) { log_write(0, LOG_MAIN|LOG_PANIC, "Error/short write while writing \ message body to %s", mbox_path); goto OUT; } - } } while (j > 0); (void)fclose(mbox_file); @@ -173,15 +180,14 @@ if (!spool_mbox_ok) } /* get the size of the mbox message and open [message_id].eml file for reading*/ -if (Ustat(mbox_path, &statbuf) != 0 || - (yield = Ufopen(mbox_path,"rb")) == NULL) - { + +if ( !(yield = Ufopen(mbox_path,"rb")) + || fstat(fileno(yield), &statbuf) != 0 + ) log_write(0, LOG_MAIN|LOG_PANIC, "%s", string_open_failed(errno, "scan file %s", mbox_path)); - goto OUT; - } - -*mbox_file_size = statbuf.st_size; +else + *mbox_file_size = statbuf.st_size; OUT: if (data_file) (void)fclose(data_file); @@ -193,20 +199,11 @@ return yield; -/* remove mbox spool file, demimed files and temp directory */ +/* remove mbox spool file and temp directory */ void unspool_mbox(void) { - -/* reset all exiscan state variables */ -#ifdef WITH_OLD_DEMIME -demime_ok = 0; -demime_errorlevel = 0; -demime_reason = NULL; -file_extensions = NULL; -#endif - spam_ok = 0; malware_ok = 0; @@ -214,14 +211,12 @@ if (spool_mbox_ok && !no_mbox_unspool) { uschar *mbox_path; uschar *file_path; - int n; struct dirent *entry; DIR *tempdir; mbox_path = string_sprintf("%s/scan/%s", spool_directory, spooled_message_id); - tempdir = opendir(CS mbox_path); - if (!tempdir) + if (!(tempdir = opendir(CS mbox_path))) { debug_printf("Unable to opendir(%s): %s\n", mbox_path, strerror(errno)); /* Just in case we still can: */ @@ -229,14 +224,15 @@ if (spool_mbox_ok && !no_mbox_unspool) return; } /* loop thru dir & delete entries */ - while((entry = readdir(tempdir)) != NULL) + while((entry = readdir(tempdir))) { uschar *name = US entry->d_name; + int dummy; if (Ustrcmp(name, US".") == 0 || Ustrcmp(name, US"..") == 0) continue; file_path = string_sprintf("%s/%s", mbox_path, name); debug_printf("unspool_mbox(): unlinking '%s'\n", file_path); - n = unlink(CS file_path); + dummy = unlink(CS file_path); dummy = dummy; /* compiler quietening */ } closedir(tempdir);