* Exim - an Internet mail transport agent *
*************************************************/
-/* Copyright (c) University of Cambridge 1995 - 2016 */
+/* Copyright (c) University of Cambridge 1995 - 2018 */
/* See the file NOTICE for conditions of use and distribution. */
/* Functions for reading spool files. When compiling for a utility (eximon),
-/*************************************************
-* Read spool header file *
-*************************************************/
-
-/* This function reads a spool header file and places the data into the
-appropriate global variables. The header portion is always read, but header
-structures are built only if read_headers is set true. It isn't, for example,
-while generating -bp output.
-
-It may be possible for blocks of nulls (binary zeroes) to get written on the
-end of a file if there is a system crash during writing. It was observed on an
-earlier version of Exim that omitted to fsync() the files - this is thought to
-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
- subdir_set TRUE is message_subdir is already set
-
-Returns: spool_read_OK success
- spool_read_notopen open failed
- spool_read_enverror error in the envelope portion
- spool_read_hdrdrror error in the header portion
-*/
-
-int
-spool_read_header(uschar *name, BOOL read_headers, BOOL subdir_set)
-{
-FILE *f = NULL;
-int n;
-int rcount = 0;
-long int uid, gid;
-BOOL inheader = FALSE;
-uschar *p;
-
/* Reset all the global variables to their default values. However, there is
one exception. DO NOT change the default value of dont_deliver, because it may
be forced by an external setting. */
+void
+spool_clear_header_globals(void)
+{
acl_var_c = acl_var_m = NULL;
authenticated_id = NULL;
authenticated_sender = NULL;
sender_local = FALSE;
sender_set_untrusted = FALSE;
smtp_active_hostname = primary_hostname;
+#ifndef COMPILE_UTILITY
+spool_file_wireformat = FALSE;
+#endif
tree_nonrecipients = NULL;
#ifdef EXPERIMENTAL_BRIGHTMAIL
#ifdef SUPPORT_TLS
tls_in.certificate_verified = FALSE;
-# ifdef EXPERIMENTAL_DANE
+# ifdef SUPPORT_DANE
tls_in.dane_verified = FALSE;
# endif
tls_in.cipher = NULL;
dsn_ret = 0;
dsn_envid = NULL;
+}
+
+
+/*************************************************
+* Read spool header file *
+*************************************************/
+
+/* This function reads a spool header file and places the data into the
+appropriate global variables. The header portion is always read, but header
+structures are built only if read_headers is set true. It isn't, for example,
+while generating -bp output.
+
+It may be possible for blocks of nulls (binary zeroes) to get written on the
+end of a file if there is a system crash during writing. It was observed on an
+earlier version of Exim that omitted to fsync() the files - this is thought to
+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
+ subdir_set TRUE is message_subdir is already set
+
+Returns: spool_read_OK success
+ spool_read_notopen open failed
+ spool_read_enverror error in the envelope portion
+ spool_read_hdrerror error in the header portion
+*/
+
+int
+spool_read_header(uschar *name, BOOL read_headers, BOOL subdir_set)
+{
+FILE *f = NULL;
+int n;
+int rcount = 0;
+long int uid, gid;
+BOOL inheader = FALSE;
+uschar *p;
+
+/* Reset all the global variables to their default values. However, there is
+one exception. DO NOT change the default value of dont_deliver, because it may
+be forced by an external setting. */
+
+spool_clear_header_globals();
/* Generate the full name and open the file. If message_subdir is already
set, just look in the given directory. Otherwise, look in both the split
/* time */
if (Ufgets(big_buffer, big_buffer_size, f) == NULL) goto SPOOL_READ_ERROR;
-if (sscanf(CS big_buffer, "%d %d", &received_time, &warning_count) != 2)
+if (sscanf(CS big_buffer, TIME_T_FMT " %d", &received_time.tv_sec, &warning_count) != 2)
goto SPOOL_FORMAT_ERROR;
+received_time.tv_usec = 0;
-message_age = time(NULL) - received_time;
+message_age = time(NULL) - received_time.tv_sec;
#ifndef COMPILE_UTILITY
DEBUG(D_deliver) debug_printf("user=%s uid=%ld gid=%ld sender=%s\n",
tree_node *node;
endptr = Ustrchr(big_buffer + 6, ' ');
if (endptr == NULL) goto SPOOL_FORMAT_ERROR;
- name = string_sprintf("%c%.*s", big_buffer[4], endptr - big_buffer - 6,
- big_buffer + 6);
+ name = string_sprintf("%c%.*s", big_buffer[4],
+ (int)(endptr - big_buffer - 6), big_buffer + 6);
if (sscanf(CS endptr, " %d", &count) != 1) goto SPOOL_FORMAT_ERROR;
node = acl_var_create(name);
node->data.ptr = store_get(count + 1);
break;
case 'l':
- if (Ustrcmp(p, "ocal") == 0) sender_local = TRUE;
+ if (Ustrcmp(p, "ocal") == 0)
+ sender_local = TRUE;
else if (Ustrcmp(big_buffer, "-localerror") == 0)
local_error_message = TRUE;
else if (Ustrncmp(p, "ocal_scan ", 10) == 0)
case 'r':
if (Ustrncmp(p, "eceived_protocol", 16) == 0)
received_protocol = string_copy(big_buffer + 19);
+ else if (Ustrncmp(p, "eceived_time_usec", 17) == 0)
+ {
+ unsigned usec;
+ if (sscanf(CS big_buffer + 21, "%u", &usec) == 1)
+ received_time.tv_usec = usec;
+ }
break;
case 's':
else if (Ustrncmp(p, "pam_score_int ", 14) == 0)
spam_score_int = string_copy(big_buffer + 16);
#endif
+#ifndef COMPILE_UTILITY
+ else if (Ustrncmp(p, "pool_file_wireformat", 20) == 0)
+ spool_file_wireformat = TRUE;
+#endif
#if defined(SUPPORT_I18N) && !defined(COMPILE_UTILITY)
else if (Ustrncmp(p, "mtputf8", 7) == 0)
message_smtputf8 = TRUE;