Logging: connection_reject log selector should apply also to the connect acl
[exim.git] / src / src / spool_in.c
index 6341387a206f45f6a91181548e26e1da3d0b2cb2..3592fa7b64bed9e4cb6ae695d792cea87a1e4887 100644 (file)
@@ -25,6 +25,8 @@ fact it won't be written to. Just in case there's a major disaster (e.g.
 overwriting some other file descriptor with the value of this one), open it
 with append.
 
+As called by deliver_message() (at least) we are operating as root.
+
 Argument: the id of the message
 Returns:  fd if file successfully opened and locked, else -1
 
@@ -37,7 +39,6 @@ spool_open_datafile(uschar *id)
 int i;
 struct stat statbuf;
 flock_t lock_data;
-uschar spoolname[256];
 int fd;
 
 /* If split_spool_directory is set, first look for the file in the appropriate
@@ -49,23 +50,31 @@ splitting state. */
 
 for (i = 0; i < 2; i++)
   {
+  uschar * fname;
   int save_errno;
-  message_subdir[0] = split_spool_directory == (i == 0) ? id[5] : 0;
-  snprintf(CS spoolname, sizeof(spoolname), "%s/input/%s/%s/%s-D",
-           spool_directory, queue_name, message_subdir, id);
-  DEBUG(D_deliver) debug_printf("Trying spool file %s\n", spoolname);
 
-  if ((fd = Uopen(spoolname, O_RDWR | O_APPEND, 0)) >= 0)
+  message_subdir[0] = split_spool_directory == i ? '\0' : id[5];
+  fname = spool_fname(US"input", message_subdir, id, US"-D");
+  DEBUG(D_deliver) debug_printf("Trying spool file %s\n", fname);
+
+  if ((fd = Uopen(fname,
+#ifdef O_CLOEXEC
+                     O_CLOEXEC |
+#endif
+                     O_RDWR | O_APPEND, 0)) >= 0)
     break;
   save_errno = errno;
   if (errno == ENOENT)
     {
     if (i == 0) continue;
     if (!queue_running)
-      log_write(0, LOG_MAIN, "Spool file %s-D not found", id);
+      log_write(0, LOG_MAIN, "Spool%s%s file %s-D not found",
+       *queue_name ? US" Q=" : US"",
+       *queue_name ? queue_name : US"",
+       id);
     }
-  else log_write(0, LOG_MAIN, "Spool error for %s: %s", spoolname,
-    strerror(errno));
+  else
+    log_write(0, LOG_MAIN, "Spool error for %s: %s", fname, strerror(errno));
   errno = save_errno;
   return -1;
   }
@@ -78,8 +87,9 @@ an open file descriptor (at least, I think that's the Cygwin story). On real
 Unix systems it doesn't make any difference as long as Exim is consistent in
 what it locks. */
 
-(void)fcntl(fd, F_SETFD, fcntl(fd, F_GETFD) |
-  FD_CLOEXEC);
+#ifndef O_CLOEXEC
+(void)fcntl(fd, F_SETFD, fcntl(fd, F_GETFD) | FD_CLOEXEC);
+#endif
 
 lock_data.l_type = F_WRLCK;
 lock_data.l_whence = SEEK_SET;
@@ -212,6 +222,8 @@ have been the cause of that incident, but in any case, this code must be robust
 against such an event, and if such a file is encountered, it must be treated as
 malformed.
 
+As called from deliver_message() (at least) we are running as root.
+
 Arguments:
   name          name of the header file, including the -H
   read_headers  TRUE if in-store header structures are to be built
@@ -322,10 +334,11 @@ for (n = 0; n < 2; n++)
   {
   if (!subdir_set)
     message_subdir[0] = split_spool_directory == (n == 0) ? name[5] : 0;
-  sprintf(CS big_buffer, "%s/input/%s/%s/%s",
-         spool_directory, queue_name, message_subdir, name);
-  if ((f = Ufopen(big_buffer, "rb"))) break;
-  if (n != 0 || subdir_set || errno != ENOENT) return spool_read_notopen;
+
+  if ((f = Ufopen(spool_fname(US"input", message_subdir, name, US""), "rb")))
+    break;
+  if (n != 0 || subdir_set || errno != ENOENT)
+    return spool_read_notopen;
   }
 
 errno = 0;
@@ -472,21 +485,21 @@ for (;;)
 
     else if (Ustrncmp(p, "cl ", 3) == 0)
       {
-      int index, count;
-      uschar name[20];   /* Need plenty of space for %d format */
-      tree_node *node;
-      if (  sscanf(CS big_buffer + 5, "%d %d", &index, &count) != 2
+      unsigned index, count;
+      uschar name[20];   /* Need plenty of space for %u format */
+      tree_node * node;
+      if (  sscanf(CS big_buffer + 5, "%u %u", &index, &count) != 2
         || index >= 20
          )
         goto SPOOL_FORMAT_ERROR;
       if (index < 10)
-        (void) string_format(name, sizeof(name), "%c%d", 'c', index);
+        (void) string_format(name, sizeof(name), "%c%u", 'c', index);
       else
-        (void) string_format(name, sizeof(name), "%c%d", 'm', index - 10);
+        (void) string_format(name, sizeof(name), "%c%u", 'm', index - 10);
       node = acl_var_create(name);
       node->data.ptr = store_get(count + 1);
       if (fread(node->data.ptr, 1, count+1, f) < count) goto SPOOL_READ_ERROR;
-      ((uschar*)node->data.ptr)[count] = 0;
+      (US node->data.ptr)[count] = '\0';
       }
     break;