tidying: coverity fixes
[exim.git] / src / src / receive.c
index aaf9215e97354d96335b255c1f5a37d974b772cf..b03ab71ed2353eede33dbc5c474e53362658d47e 100644 (file)
@@ -84,12 +84,10 @@ receive_check_set_sender(uschar *newsender)
 {
 uschar *qnewsender;
 if (trusted_caller) return TRUE;
-if (newsender == NULL || untrusted_set_sender == NULL) return FALSE;
-qnewsender = (Ustrchr(newsender, '@') != NULL)?
-  newsender : string_sprintf("%s@%s", newsender, qualify_domain_sender);
-return
-  match_address_list(qnewsender, TRUE, TRUE, CUSS &untrusted_set_sender, NULL, -1,
-    0, NULL) == OK;
+if (!newsender || !untrusted_set_sender) return FALSE;
+qnewsender = Ustrchr(newsender, '@')
+  ? newsender : string_sprintf("%s@%s", newsender, qualify_domain_sender);
+return match_address_list_basic(qnewsender, CUSS &untrusted_set_sender, 0) == OK;
 }
 
 
@@ -1018,6 +1016,46 @@ for(;;)
 /*NOTREACHED*/
 }
 
+static int
+read_message_bdat_smtp_wire(FILE *fout)
+{
+int ch;
+
+/* Remember that this message uses wireformat. */
+
+DEBUG(D_receive) debug_printf("CHUNKING: writing spoolfile in wire format\n");
+spool_file_wireformat = TRUE;
+
+/* Unfortunately cannot use sendfile() even if not TLS
+as that requires (on linux) mmap-like operations on the input fd.
+
+XXX but worthwhile doing a block interface to the bdat_getc buffer
+in the future */
+
+for (;;) switch (ch = bdat_getc(GETC_BUFFER_UNLIMITED))
+  {
+  case EOF: return END_EOF;
+  case EOD: return END_DOT;
+  case ERR: return END_PROTOCOL;
+
+  default:
+    message_size++;
+/*XXX not done:
+linelength
+max_received_linelength
+body_linecount
+body_zerocount
+*/
+    if (fout)
+      {
+      if (fputc(ch, fout) == EOF) return END_WERROR;
+      if (message_size > thismessage_size_limit) return END_SIZE;
+      }
+    break;
+  }
+/*NOTREACHED*/
+}
+
 
 
 
@@ -1308,36 +1346,30 @@ unsigned long mbox_size;
 header_line *my_headerlist;
 uschar *user_msg, *log_msg;
 int mime_part_count_buffer = -1;
+uschar * mbox_filename;
 int rc = OK;
 
 memset(CS rfc822_file_path,0,2048);
 
 /* check if it is a MIME message */
-my_headerlist = header_list;
-while (my_headerlist != NULL)
-  {
-  /* skip deleted headers */
-  if (my_headerlist->type == '*')
-    {
-    my_headerlist = my_headerlist->next;
-    continue;
-    }
-  if (strncmpic(my_headerlist->text, US"Content-Type:", 13) == 0)
+
+for (my_headerlist = header_list; my_headerlist; my_headerlist = my_headerlist->next)
+  if (  my_headerlist->type != '*'                     /* skip deleted headers */
+     && 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;
 
 DO_MIME_ACL:
+
 /* make sure the eml mbox file is spooled up */
-mbox_file = spool_mbox(&mbox_size, NULL);
-if (mbox_file == NULL) {
-  /* error while spooling */
+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);
@@ -1349,7 +1381,7 @@ if (mbox_file == NULL) {
   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;
 
@@ -1373,14 +1405,13 @@ if (Ustrlen(rfc822_file_path) > 0)
 /* check if we must check any message/rfc822 attachments */
 if (rc == OK)
   {
-  uschar temp_path[1024];
+  uschar * scandir;
   struct dirent * entry;
   DIR * tempdir;
 
-  (void) string_format(temp_path, sizeof(temp_path), "%s/scan/%s",
-    spool_directory, message_id);
+  scandir = string_copyn(mbox_filename, Ustrrchr(mbox_filename, '/') - mbox_filename);
 
-  tempdir = opendir(CS temp_path);
+  tempdir = opendir(CS scandir);
   for (;;)
     {
     if (!(entry = readdir(tempdir)))
@@ -1388,7 +1419,7 @@ if (rc == OK)
     if (strncmpic(US entry->d_name, US"__rfc822_", 9) == 0)
       {
       (void) string_format(rfc822_file_path, sizeof(rfc822_file_path),
-       "%s/scan/%s/%s", spool_directory, message_id, entry->d_name);
+       "%s/%s", scandir, entry->d_name);
       DEBUG(D_receive) debug_printf("RFC822 attachment detected: running MIME ACL for '%s'\n",
        rfc822_file_path);
       break;
@@ -3087,9 +3118,11 @@ if (!ferror(data_file) && !(receive_feof)() && message_ended != END_DOT)
   {
   if (smtp_input)
     {
-    message_ended = chunking_state > CHUNKING_OFFERED
-      ? read_message_bdat_smtp(data_file)
-      : read_message_data_smtp(data_file);
+    message_ended = chunking_state <= CHUNKING_OFFERED
+      ? read_message_data_smtp(data_file)
+      : spool_wireformat
+      ? read_message_bdat_smtp_wire(data_file)
+      : read_message_bdat_smtp(data_file);
     receive_linecount++;                /* The terminating "." line */
     }
   else message_ended = read_message_data(data_file);
@@ -3643,6 +3676,7 @@ dcc_ok = 0;
 version supplied with Exim always accepts, but this is a hook for sysadmins to
 supply their own checking code. The local_scan() function is run even when all
 the recipients have been discarded. */
+/*XXS could we avoid this for the standard case, given that few people will use it? */
 
 lseek(data_fd, (long int)SPOOL_DATA_START_OFFSET, SEEK_SET);
 
@@ -4267,6 +4301,7 @@ if (smtp_input)
 
       else if (chunking_state > CHUNKING_OFFERED)
        {
+/*XXX rethink for spool_wireformat */
         smtp_printf("250- %u byte chunk, total %d\r\n250 OK id=%s\r\n",
            chunking_datasize, message_size+message_linecount, message_id);
        chunking_state = CHUNKING_OFFERED;