Fix logging of max-size log line
[exim.git] / src / src / macros.h
index c62f16e7d27251ced9ff8628a8f1bf6004af7e3d..243c1e5a0dd4f5a863d21d4e3547a65d95346bc5 100644 (file)
@@ -2,8 +2,10 @@
 *     Exim - an Internet mail transport agent    *
 *************************************************/
 
 *     Exim - an Internet mail transport agent    *
 *************************************************/
 
-/* Copyright (c) University of Cambridge 1995 - 2016 */
+/* Copyright (c) The Exim Maintainers 2020 - 2022 */
+/* Copyright (c) University of Cambridge 1995 - 2018 */
 /* See the file NOTICE for conditions of use and distribution. */
 /* See the file NOTICE for conditions of use and distribution. */
+/* SPDX-License-Identifier: GPL-2.0-or-later */
 
 
 /* These two macros make it possible to obtain the result of macro-expanding
 
 
 /* These two macros make it possible to obtain the result of macro-expanding
@@ -15,33 +17,36 @@ a string as a text string. This is sometimes useful for debugging output. */
 /* Number of elements of an array */
 #define nelem(arr) (sizeof(arr) / sizeof(*arr))
 
 /* Number of elements of an array */
 #define nelem(arr) (sizeof(arr) / sizeof(*arr))
 
+/* Maximum of two items */
+#ifndef MAX
+# define MAX(a,b) ((a) > (b) ? (a) : (b))
+#endif
+
 
 /* When running in the test harness, the load average is fudged. */
 
 #define OS_GETLOADAVG() \
 
 /* When running in the test harness, the load average is fudged. */
 
 #define OS_GETLOADAVG() \
-  (running_in_test_harness? (test_harness_load_avg += 10) : os_getloadavg())
+  (f.running_in_test_harness? (test_harness_load_avg += 10) : os_getloadavg())
 
 
 
 
-/* The address_item structure has a word full of 1-bit flags. These macros
+/* The address_item structure has a struct full of 1-bit flags. These macros
 manipulate them. */
 
 manipulate them. */
 
-#define setflag(addr,flag)    addr->flags |= (flag)
-#define clearflag(addr,flag)  addr->flags &= ~(flag)
+#define setflag(addr, flagname)    addr->flags.flagname = TRUE
+#define clearflag(addr, flagname)  addr->flags.flagname = FALSE
 
 
-#define testflag(addr,flag)       ((addr->flags & (flag)) != 0)
-#define testflagsall(addr,flag)   ((addr->flags & (flag)) == (flag))
+#define testflag(addr, flagname)   (addr->flags.flagname)
 
 
-#define copyflag(addrnew,addrold,flag) \
-  addrnew->flags = (addrnew->flags & ~(flag)) | (addrold->flags & (flag))
-
-#define orflag(addrnew,addrold,flag) \
-  addrnew->flags |= addrold->flags & (flag)
+#define copyflag(addrnew, addrold, flagname) \
+  addrnew->flags.flagname = addrold->flags.flagname
 
 
 /* For almost all calls to convert things to printing characters, we want to
 
 
 /* For almost all calls to convert things to printing characters, we want to
-allow tabs. A macro just makes life a bit easier. */
+allow tabs & spaces. A macro just makes life a bit easier. */
 
 
-#define string_printing(s) string_printing2((s), TRUE)
+#define string_printing(s) string_printing2((s), 0)
+#define SP_TAB         BIT(0)
+#define SP_SPACE       BIT(1)
 
 
 /* We need a special return code for "no recipients and failed to send an error
 
 
 /* We need a special return code for "no recipients and failed to send an error
@@ -75,16 +80,11 @@ as unsigned. */
   ((uschar)(c) > 127 && print_topbitchars))
 
 
   ((uschar)(c) > 127 && print_topbitchars))
 
 
-/* Convenience for testing strings */
-
-#define streqic(Foo, Bar) (strcmpic(Foo, Bar) == 0)
-
-
 /* When built with TLS support, the act of flushing SMTP output becomes
 a no-op once an SSL session is in progress. */
 
 /* When built with TLS support, the act of flushing SMTP output becomes
 a no-op once an SSL session is in progress. */
 
-#ifdef SUPPORT_TLS
-#define mac_smtp_fflush() if (tls_in.active < 0) fflush(smtp_out);
+#ifndef DISABLE_TLS
+#define mac_smtp_fflush() if (tls_in.active.sock < 0) fflush(smtp_out);
 #else
 #define mac_smtp_fflush() fflush(smtp_out);
 #endif
 #else
 #define mac_smtp_fflush() fflush(smtp_out);
 #endif
@@ -106,15 +106,9 @@ don't make the file descriptors two-way. */
 
 /* Debugging control */
 
 
 /* Debugging control */
 
-#define DEBUG(x)      if ((debug_selector & (x)) != 0)
-#define HDEBUG(x)     if (host_checking || (debug_selector & (x)) != 0)
-
-#define PTR_CHK(ptr) \
-do { \
-if ((void *)ptr > (void *)store_get(0)) \
-  debug_printf("BUG: ptr '%s' beyond arena at %s:%d\n", \
-               mac_expanded_string(ptr), __FUNCTION__, __LINE__); \
-} while(0)
+#define LOG_NAME_SIZE 256
+#define DEBUG(x)      if (debug_selector & (x))
+#define HDEBUG(x)     if (host_checking || debug_selector & (x))
 
 /* The default From: text for DSNs */
 
 
 /* The default From: text for DSNs */
 
@@ -124,7 +118,7 @@ if ((void *)ptr > (void *)store_get(0)) \
 verifying. This has to be explicit because it is referenced in more than one
 source module. */
 
 verifying. This has to be explicit because it is referenced in more than one
 source module. */
 
-#define ADDRESS_EXPANSIONS_COUNT 18
+#define ADDRESS_EXPANSIONS_COUNT 19
 
 /* The maximum permitted number of command-line (-D) macro definitions. We
 need a limit only to make it easier to generate argument vectors for re-exec
 
 /* The maximum permitted number of command-line (-D) macro definitions. We
 need a limit only to make it easier to generate argument vectors for re-exec
@@ -143,7 +137,7 @@ changed, then the tables in expand.c for accessing them must be changed too. */
 
 /* The size of the buffer holding the processing information string. */
 
 
 /* The size of the buffer holding the processing information string. */
 
-#define PROCESS_INFO_SIZE 256
+#define PROCESS_INFO_SIZE 384
 
 /* The size of buffer to get for constructing log entries. Make it big
 enough to hold all the headers from a normal kind of message. */
 
 /* The size of buffer to get for constructing log entries. Make it big
 enough to hold all the headers from a normal kind of message. */
@@ -153,17 +147,29 @@ enough to hold all the headers from a normal kind of message. */
 /* The size of the circular buffer that remembers recent SMTP commands */
 
 #define SMTP_HBUFF_SIZE 20
 /* The size of the circular buffer that remembers recent SMTP commands */
 
 #define SMTP_HBUFF_SIZE 20
+#define SMTP_HBUFF_PREV(n)     ((n) ? (n)-1 : SMTP_HBUFF_SIZE-1)
 
 /* The initial size of a big buffer for use in various places. It gets put
 into big_buffer_size and in some circumstances increased. It should be at least
 
 /* The initial size of a big buffer for use in various places. It gets put
 into big_buffer_size and in some circumstances increased. It should be at least
-as long as the maximum path length. */
+as long as the maximum path length PLUS room for string additions.
+Let's go with "at least twice as large as maximum path length".
+*/
 
 
-#if defined PATH_MAX && PATH_MAX > 16384
-# define BIG_BUFFER_SIZE PATH_MAX
-#elif defined MAXPATHLEN && MAXPATHLEN > 16384
-# define BIG_BUFFER_SIZE MAXPATHLEN
+#ifdef AUTH_HEIMDAL_GSSAPI
+               /* RFC 4121 section 5.2, SHOULD support 64K input buffers */
+# define __BIG_BUFFER_SIZE 65536
 #else
 #else
-# define BIG_BUFFER_SIZE 16384
+# define __BIG_BUFFER_SIZE 16384
+#endif
+
+#ifndef PATH_MAX
+/* exim.h will have ensured this exists before including us. */
+# error headers confusion, PATH_MAX missing in macros.h
+#endif
+#if (PATH_MAX*2) > __BIG_BUFFER_SIZE
+# define BIG_BUFFER_SIZE (PATH_MAX*2)
+#else
+# define BIG_BUFFER_SIZE __BIG_BUFFER_SIZE
 #endif
 
 /* header size of pipe content
 #endif
 
 /* header size of pipe content
@@ -175,29 +181,16 @@ written on the spool, it gets read into big_buffer. */
 
 #define LOCAL_SCAN_MAX_RETURN (BIG_BUFFER_SIZE - 24)
 
 
 #define LOCAL_SCAN_MAX_RETURN (BIG_BUFFER_SIZE - 24)
 
-/* A limit to the length of an address. RFC 2821 limits the local part to 64
-and the domain to 255, so this should be adequate, taking into account quotings
-etc. */
-
-#define ADDRESS_MAXLENGTH 512
-
 /* The length of the base names of spool files, which consist of an internal
 message id with a trailing "-H" or "-D" added. */
 
 #define SPOOL_NAME_LENGTH (MESSAGE_ID_LENGTH+2)
 
 /* The maximum number of message ids to store in a waiting database
 /* The length of the base names of spool files, which consist of an internal
 message id with a trailing "-H" or "-D" added. */
 
 #define SPOOL_NAME_LENGTH (MESSAGE_ID_LENGTH+2)
 
 /* The maximum number of message ids to store in a waiting database
-record. */
+record, and the max number of continuation records allowed. */
 
 #define WAIT_NAME_MAX 50
 
 #define WAIT_NAME_MAX 50
-
-/* Wait this long before determining that a Proxy Protocol configured
-host isn't speaking the protocol, and so is disallowed. Can be moved to
-runtime configuration if per site settings become needed. */
-#ifdef SUPPORT_PROXY
-#define PROXY_NEGOTIATION_TIMEOUT_SEC 3
-#define PROXY_NEGOTIATION_TIMEOUT_USEC 0
-#endif
+#define WAIT_CONT_MAX 1000
 
 /* Fixed option values for all PCRE functions */
 
 
 /* Fixed option values for all PCRE functions */
 
@@ -206,8 +199,7 @@ runtime configuration if per site settings become needed. */
 
 /* Macros for trivial functions */
 
 
 /* Macros for trivial functions */
 
-#define mac_ismsgid(s) \
-  (pcre_exec(regex_ismsgid,NULL,CS s,Ustrlen(s),0,PCRE_EOPT,NULL,0) >= 0)
+#define mac_ismsgid(s) (regex_match(regex_ismsgid, (s), -1, NULL))
 
 
 /* Options for dns_next_rr */
 
 
 /* Options for dns_next_rr */
@@ -223,9 +215,9 @@ enum { tod_log, tod_log_bare, tod_log_zone, tod_log_datestamp_daily,
 /* For identifying types of driver */
 
 enum {
 /* For identifying types of driver */
 
 enum {
-  DTYPE_NONE,
-  DTYPE_ROUTER,
-  DTYPE_TRANSPORT
+  EXIM_DTYPE_NONE,
+  EXIM_DTYPE_ROUTER,
+  EXIM_DTYPE_TRANSPORT
 };
 
 /* Error numbers for generating error messages when reading a message on the
 };
 
 /* Error numbers for generating error messages when reading a message on the
@@ -244,7 +236,7 @@ enum {
   ERRMESS_TOOMANYRECIP,     /* Too many recipients */
   ERRMESS_LOCAL_SCAN,       /* Rejected by local scan */
   ERRMESS_LOCAL_ACL         /* Rejected by non-SMTP ACL */
   ERRMESS_TOOMANYRECIP,     /* Too many recipients */
   ERRMESS_LOCAL_SCAN,       /* Rejected by local scan */
   ERRMESS_LOCAL_ACL         /* Rejected by non-SMTP ACL */
-#ifdef EXPERIMENTAL_DMARC
+#ifdef SUPPORT_DMARC
  ,ERRMESS_DMARC_FORENSIC    /* DMARC Forensic Report */
 #endif
 };
  ,ERRMESS_DMARC_FORENSIC    /* DMARC Forensic Report */
 #endif
 };
@@ -277,7 +269,9 @@ and some additional values are used only by non-driver functions.
 
 OK, FAIL, DEFER, ERROR, and FAIL_FORCED are also declared in local_scan.h for
 use in the local_scan() function and in ${dlfunc loaded functions. Do not
 
 OK, FAIL, DEFER, ERROR, and FAIL_FORCED are also declared in local_scan.h for
 use in the local_scan() function and in ${dlfunc loaded functions. Do not
-change them unilaterally. */
+change them unilaterally.
+
+Use rc_names[] for debug strings. */
 
 #define  OK            0    /* Successful match */
 #define  DEFER         1    /* Defer - some problem */
 
 #define  OK            0    /* Successful match */
 #define  DEFER         1    /* Defer - some problem */
@@ -298,6 +292,7 @@ change them unilaterally. */
 #define CANCELLED     13    /* Authentication cancelled */
 #define FAIL_SEND     14    /* send() failed in authenticator */
 #define FAIL_DROP     15    /* Fail and drop connection (used in ACL) */
 #define CANCELLED     13    /* Authentication cancelled */
 #define FAIL_SEND     14    /* send() failed in authenticator */
 #define FAIL_DROP     15    /* Fail and drop connection (used in ACL) */
+#define DANE         16    /* Deferred for domain mismatch (used in transport) */
 
 /* Returns from the deliver_message() function */
 
 
 /* Returns from the deliver_message() function */
 
@@ -306,7 +301,7 @@ change them unilaterally. */
 #define DELIVER_MUA_FAILED         2  /* Failure when mua_wrapper is set */
 #define DELIVER_NOT_ATTEMPTED      3  /* Not tried (no msg or is locked */
 
 #define DELIVER_MUA_FAILED         2  /* Failure when mua_wrapper is set */
 #define DELIVER_NOT_ATTEMPTED      3  /* Not tried (no msg or is locked */
 
-/* Returns from DNS lookup functions. */
+/* Returns from DNS lookup functions. Use dns_rc_names[] for debug strings */
 
 enum { DNS_SUCCEED, DNS_NOMATCH, DNS_NODATA, DNS_AGAIN, DNS_FAIL };
 
 
 enum { DNS_SUCCEED, DNS_NOMATCH, DNS_NODATA, DNS_AGAIN, DNS_FAIL };
 
@@ -336,18 +331,18 @@ platforms, but this ensures bit vectors always work the same way. */
 
 /* This macro is for single-word bit vectors: the debug selector,
 and the first word of the log selector. */
 
 /* This macro is for single-word bit vectors: the debug selector,
 and the first word of the log selector. */
-#define BIT(n) (1 << (n))
+#define BIT(n) (1UL << (n))
 
 /* And these are for multi-word vectors. */
 
 /* And these are for multi-word vectors. */
-#define BITWORD(n) (     (n) / BITWORDSIZE)
-#define BITMASK(n) (1 << (n) % BITWORDSIZE)
+#define BITWORD(n) (      (n) / BITWORDSIZE)
+#define BITMASK(n) (1U << (n) % BITWORDSIZE)
 
 #define BIT_CLEAR(s,z,n) ((s)[BITWORD(n)] &= ~BITMASK(n))
 #define BIT_SET(s,z,n)   ((s)[BITWORD(n)] |=  BITMASK(n))
 #define BIT_TEST(s,z,n) (((s)[BITWORD(n)] &   BITMASK(n)) != 0)
 
 /* Used in globals.c for initializing bit_table structures. T will be either
 
 #define BIT_CLEAR(s,z,n) ((s)[BITWORD(n)] &= ~BITMASK(n))
 #define BIT_SET(s,z,n)   ((s)[BITWORD(n)] |=  BITMASK(n))
 #define BIT_TEST(s,z,n) (((s)[BITWORD(n)] &   BITMASK(n)) != 0)
 
 /* Used in globals.c for initializing bit_table structures. T will be either
-D or L correspondong to the debug and log selector bits declared below. */
+D or L corresponding to the debug and log selector bits declared below. */
 
 #define BIT_TABLE(T,name) { US #name, T##i_##name }
 
 
 #define BIT_TABLE(T,name) { US #name, T##i_##name }
 
@@ -361,12 +356,13 @@ masks, alternating between sequential bit index and corresponding mask. */
 
 /* Options bits for debugging. DEBUG_BIT() declares both a bit index and the
 corresponding mask. Di_all is a special value recognized by decode_bits().
 
 /* Options bits for debugging. DEBUG_BIT() declares both a bit index and the
 corresponding mask. Di_all is a special value recognized by decode_bits().
+These must match the debug_options table in globals.c .
 
 Exim's code assumes in a number of places that the debug_selector is one
 word, and this is exposed in the local_scan ABI. The D_v and D_local_scan bit
 masks are part of the local_scan API so are #defined in local_scan.h */
 
 
 Exim's code assumes in a number of places that the debug_selector is one
 word, and this is exposed in the local_scan ABI. The D_v and D_local_scan bit
 masks are part of the local_scan API so are #defined in local_scan.h */
 
-#define DEBUG_BIT(name) Di_##name = IOTA(Di_iota), D_##name = BIT(Di_##name)
+#define DEBUG_BIT(name) Di_##name = IOTA(Di_iota), D_##name = (int)BIT(Di_##name)
 
 enum {
   Di_all        = -1,
 
 enum {
   Di_all        = -1,
@@ -374,12 +370,12 @@ enum {
   Di_local_scan = 1,
 
   Di_iota = IOTA_INIT(2),
   Di_local_scan = 1,
 
   Di_iota = IOTA_INIT(2),
-  DEBUG_BIT(acl),
+  DEBUG_BIT(acl),              /* 2 */
   DEBUG_BIT(auth),
   DEBUG_BIT(deliver),
   DEBUG_BIT(dns),
   DEBUG_BIT(dnsbl),
   DEBUG_BIT(auth),
   DEBUG_BIT(deliver),
   DEBUG_BIT(dns),
   DEBUG_BIT(dnsbl),
-  DEBUG_BIT(exec),
+  DEBUG_BIT(exec),             /* 7 */
   DEBUG_BIT(expand),
   DEBUG_BIT(filter),
   DEBUG_BIT(hints_lookup),
   DEBUG_BIT(expand),
   DEBUG_BIT(filter),
   DEBUG_BIT(hints_lookup),
@@ -387,14 +383,15 @@ enum {
   DEBUG_BIT(ident),
   DEBUG_BIT(interface),
   DEBUG_BIT(lists),
   DEBUG_BIT(ident),
   DEBUG_BIT(interface),
   DEBUG_BIT(lists),
-  DEBUG_BIT(load),
+  DEBUG_BIT(load),             /* 15 */
   DEBUG_BIT(lookup),
   DEBUG_BIT(memory),
   DEBUG_BIT(lookup),
   DEBUG_BIT(memory),
+  DEBUG_BIT(noutf8),
   DEBUG_BIT(pid),
   DEBUG_BIT(process_info),
   DEBUG_BIT(queue_run),
   DEBUG_BIT(receive),
   DEBUG_BIT(pid),
   DEBUG_BIT(process_info),
   DEBUG_BIT(queue_run),
   DEBUG_BIT(receive),
-  DEBUG_BIT(resolver),
+  DEBUG_BIT(resolver),         /* 23 */
   DEBUG_BIT(retry),
   DEBUG_BIT(rewrite),
   DEBUG_BIT(route),
   DEBUG_BIT(retry),
   DEBUG_BIT(rewrite),
   DEBUG_BIT(route),
@@ -402,7 +399,7 @@ enum {
   DEBUG_BIT(tls),
   DEBUG_BIT(transport),
   DEBUG_BIT(uid),
   DEBUG_BIT(tls),
   DEBUG_BIT(transport),
   DEBUG_BIT(uid),
-  DEBUG_BIT(verify),
+  DEBUG_BIT(verify),           /* 31 */
 };
 
 /* Multi-bit debug masks */
 };
 
 /* Multi-bit debug masks */
@@ -411,6 +408,7 @@ enum {
 
 #define D_any                        (D_all & \
                                        ~(D_v           | \
 
 #define D_any                        (D_all & \
                                        ~(D_v           | \
+                                        D_noutf8      | \
                                          D_pid         | \
                                          D_timestamp)  )
 
                                          D_pid         | \
                                          D_timestamp)  )
 
@@ -421,18 +419,27 @@ enum {
                                          D_load        | \
                                          D_local_scan  | \
                                          D_memory      | \
                                          D_load        | \
                                          D_local_scan  | \
                                          D_memory      | \
+                                        D_noutf8      | \
                                          D_pid         | \
                                          D_timestamp   | \
                                          D_resolver))
 
                                          D_pid         | \
                                          D_timestamp   | \
                                          D_resolver))
 
+/* Bits for debug triggers */
+
+enum {
+  DTi_panictrigger,
+  DTi_pretrigger,
+};
+
 /* Options bits for logging. Those that have values < BITWORDSIZE can be used
 in calls to log_write(). The others are put into later words in log_selector
 and are only ever tested independently, so they do not need bit mask
 /* Options bits for logging. Those that have values < BITWORDSIZE can be used
 in calls to log_write(). The others are put into later words in log_selector
 and are only ever tested independently, so they do not need bit mask
-declarations. The Li_all value is recognized specially by decode_bits(). */
+declarations. The Li_all value is recognized specially by decode_bits().
+Add also to log_options[] when creating new ones. */
 
 #define LOG_BIT(name) Li_##name = IOTA(Li_iota), L_##name = BIT(Li_##name)
 
 
 #define LOG_BIT(name) Li_##name = IOTA(Li_iota), L_##name = BIT(Li_##name)
 
-enum {
+enum logbit {
   Li_all = -1,
 
   Li_iota = IOTA_INIT(0),
   Li_all = -1,
 
   Li_iota = IOTA_INIT(0),
@@ -458,16 +465,25 @@ enum {
   Li_arguments,
   Li_deliver_time,
   Li_delivery_size,
   Li_arguments,
   Li_deliver_time,
   Li_delivery_size,
+  Li_dkim,
+  Li_dkim_verbose,
   Li_dnssec,
   Li_ident_timeout,
   Li_incoming_interface,
   Li_incoming_port,
   Li_dnssec,
   Li_ident_timeout,
   Li_incoming_interface,
   Li_incoming_port,
+  Li_millisec,
+  Li_msg_id,
+  Li_msg_id_created,
   Li_outgoing_interface,
   Li_outgoing_port,
   Li_pid,
   Li_outgoing_interface,
   Li_outgoing_port,
   Li_pid,
+  Li_pipelining,
+  Li_protocol_detail,
   Li_proxy,
   Li_queue_time,
   Li_proxy,
   Li_queue_time,
+  Li_queue_time_exclusive,
   Li_queue_time_overall,
   Li_queue_time_overall,
+  Li_receive_time,
   Li_received_sender,
   Li_received_recipients,
   Li_rejected_header,
   Li_received_sender,
   Li_received_recipients,
   Li_rejected_header,
@@ -481,6 +497,7 @@ enum {
   Li_tls_certificate_verified,
   Li_tls_cipher,
   Li_tls_peerdn,
   Li_tls_certificate_verified,
   Li_tls_cipher,
   Li_tls_peerdn,
+  Li_tls_resumption,
   Li_tls_sni,
   Li_unknown_in_list,
 
   Li_tls_sni,
   Li_unknown_in_list,
 
@@ -541,20 +558,22 @@ table exim_errstrings[] in log.c */
 #define ERRNO_DATA4XX        (-46)   /* DATA gave 4xx error */
 #define ERRNO_PROXYFAIL      (-47)   /* Negotiation failed for proxy configured host */
 #define ERRNO_AUTHPROB       (-48)   /* Authenticator "other" failure */
 #define ERRNO_DATA4XX        (-46)   /* DATA gave 4xx error */
 #define ERRNO_PROXYFAIL      (-47)   /* Negotiation failed for proxy configured host */
 #define ERRNO_AUTHPROB       (-48)   /* Authenticator "other" failure */
-
-#ifdef SUPPORT_I18N
-# define ERRNO_UTF8_FWD      (-49)   /* target not supporting SMTPUTF8 */
-#endif
+#define ERRNO_UTF8_FWD       (-49)   /* target not supporting SMTPUTF8 */
+#define ERRNO_HOST_IS_LOCAL  (-50)   /* Transport refuses to talk to localhost */
+#define ERRNO_TAINT          (-51)   /* Transport refuses to talk use tainted filename */
 
 /* These must be last, so all retry deferments can easily be identified */
 
 
 /* These must be last, so all retry deferments can easily be identified */
 
-#define ERRNO_RETRY_BASE     (-51)   /* Base to test against */
-#define ERRNO_RRETRY         (-51)   /* Not time for routing */
-#define ERRNO_LRETRY         (-52)   /* Not time for local delivery */
-#define ERRNO_HRETRY         (-53)   /* Not time for any remote host */
-#define ERRNO_LOCAL_ONLY     (-54)   /* Local-only delivery */
-#define ERRNO_QUEUE_DOMAIN   (-55)   /* Domain in queue_domains */
-#define ERRNO_TRETRY         (-56)   /* Transport concurrency limit */
+#define ERRNO_RETRY_BASE     (-52)   /* Base to test against */
+#define ERRNO_RRETRY         (-52)   /* Not time for routing */
+
+#define ERRNO_WARN_BASE      (-53)   /* Base to test against */
+#define ERRNO_LRETRY         (-53)   /* Not time for local delivery */
+#define ERRNO_HRETRY         (-54)   /* Not time for any remote host */
+#define ERRNO_LOCAL_ONLY     (-55)   /* Local-only delivery */
+#define ERRNO_QUEUE_DOMAIN   (-56)   /* Domain in queue_domains */
+#define ERRNO_TRETRY         (-57)   /* Transport concurrency limit */
+#define ERRNO_EVENT         (-58)   /* Event processing request alternate response */
 
 
 
 
 
 
@@ -716,7 +735,9 @@ enum { v_none, v_sender, v_recipient, v_expn };
 #define vopt_callout_no_cache     0x0040   /* disable callout cache */
 #define vopt_callout_recipsender  0x0080   /* use real sender to verify recip */
 #define vopt_callout_recippmaster 0x0100   /* use postmaster to verify recip */
 #define vopt_callout_no_cache     0x0040   /* disable callout cache */
 #define vopt_callout_recipsender  0x0080   /* use real sender to verify recip */
 #define vopt_callout_recippmaster 0x0100   /* use postmaster to verify recip */
-#define vopt_success_on_redirect  0x0200
+#define vopt_callout_hold        0x0200   /* lazy close connection */
+#define vopt_success_on_redirect  0x0400
+#define vopt_quota                0x0800   /* quota check, to local/appendfile */
 
 /* Values for fields in callout cache records */
 
 
 /* Values for fields in callout cache records */
 
@@ -739,11 +760,17 @@ enum { hstatus_unknown, hstatus_usable, hstatus_unusable,
 
 /* Reasons why a host is unusable (for clearer log messages) */
 
 
 /* Reasons why a host is unusable (for clearer log messages) */
 
-enum { hwhy_unknown, hwhy_retry, hwhy_failed, hwhy_deferred, hwhy_ignored };
+enum { hwhy_unknown, hwhy_retry, hwhy_insecure, hwhy_failed, hwhy_deferred,
+       hwhy_ignored };
 
 /* Domain lookup types for routers */
 
 
 /* Domain lookup types for routers */
 
-enum { lk_default, lk_byname, lk_bydns };
+#define LK_DEFAULT     BIT(0)
+#define LK_BYNAME      BIT(1)
+#define LK_BYDNS       BIT(2)  /* those 3 should be mutually exclusive */
+
+#define LK_IPV4_ONLY   BIT(3)
+#define LK_IPV4_PREFER BIT(4)
 
 /* Values for the self_code fields */
 
 
 /* Values for the self_code fields */
 
@@ -804,6 +831,7 @@ enum { SCH_NONE, SCH_AUTH, SCH_DATA, SCH_BDAT,
 enum {
   HOST_FIND_FAILED,     /* failed to find the host */
   HOST_FIND_AGAIN,      /* could not resolve at this time */
 enum {
   HOST_FIND_FAILED,     /* failed to find the host */
   HOST_FIND_AGAIN,      /* could not resolve at this time */
+  HOST_FIND_SECURITY,   /* dnssec required but not acheived */
   HOST_FOUND,           /* found host */
   HOST_FOUND_LOCAL,     /* found, but MX points to local host */
   HOST_IGNORED          /* found but ignored - used internally only */
   HOST_FOUND,           /* found host */
   HOST_FOUND_LOCAL,     /* found, but MX points to local host */
   HOST_IGNORED          /* found but ignored - used internally only */
@@ -811,17 +839,20 @@ enum {
 
 /* Flags for host_find_bydns() */
 
 
 /* Flags for host_find_bydns() */
 
-#define HOST_FIND_BY_SRV          0x0001
-#define HOST_FIND_BY_MX           0x0002
-#define HOST_FIND_BY_A            0x0004
-#define HOST_FIND_QUALIFY_SINGLE  0x0008
-#define HOST_FIND_SEARCH_PARENTS  0x0010
+#define HOST_FIND_BY_SRV          BIT(0)
+#define HOST_FIND_BY_MX           BIT(1)
+#define HOST_FIND_BY_A            BIT(2)
+#define HOST_FIND_BY_AAAA         BIT(3)
+#define HOST_FIND_QUALIFY_SINGLE  BIT(4)
+#define HOST_FIND_SEARCH_PARENTS  BIT(5)
+#define HOST_FIND_IPV4_FIRST     BIT(6)
+#define HOST_FIND_IPV4_ONLY      BIT(7)
 
 /* Actions applied to specific messages. */
 
 enum { MSG_DELIVER, MSG_FREEZE, MSG_REMOVE, MSG_THAW, MSG_ADD_RECIPIENT,
        MSG_MARK_ALL_DELIVERED, MSG_MARK_DELIVERED, MSG_EDIT_SENDER,
 
 /* Actions applied to specific messages. */
 
 enum { MSG_DELIVER, MSG_FREEZE, MSG_REMOVE, MSG_THAW, MSG_ADD_RECIPIENT,
        MSG_MARK_ALL_DELIVERED, MSG_MARK_DELIVERED, MSG_EDIT_SENDER,
-       MSG_SHOW_COPY, MSG_LOAD,
+       MSG_SHOW_COPY, MSG_LOAD, MSG_SETQUEUE,
        /* These ones must be last: a test for >= MSG_SHOW_BODY is used
        to test for actions that list individual spool files. */
        MSG_SHOW_BODY, MSG_SHOW_HEADER, MSG_SHOW_LOG };
        /* These ones must be last: a test for >= MSG_SHOW_BODY is used
        to test for actions that list individual spool files. */
        MSG_SHOW_BODY, MSG_SHOW_HEADER, MSG_SHOW_LOG };
@@ -837,15 +868,27 @@ enum {
 
 /* Options for transport_write_message */
 
 
 /* Options for transport_write_message */
 
-#define topt_add_return_path    0x001
-#define topt_add_delivery_date  0x002
-#define topt_add_envelope_to    0x004
-#define topt_use_crlf           0x008  /* Terminate lines with CRLF */
-#define topt_end_dot            0x010  /* Send terminting dot line */
-#define topt_no_headers         0x020  /* Omit headers */
-#define topt_no_body            0x040  /* Omit body */
-#define topt_escape_headers     0x080  /* Apply escape check to headers */
-#define topt_use_bdat          0x100  /* prepend chunks with RFC3030 BDAT header */
+#define topt_add_return_path    0x0001
+#define topt_add_delivery_date  0x0002
+#define topt_add_envelope_to    0x0004
+#define topt_escape_headers     0x0008 /* Apply escape check to headers */
+#define topt_use_crlf           0x0010 /* Terminate lines with CRLF */
+#define topt_no_headers         0x0020 /* Omit headers */
+#define topt_no_body            0x0040 /* Omit body */
+#define topt_end_dot            0x0080 /* Send terminating dot line */
+#define topt_no_flush          0x0100  /* more data expected after message (eg QUIT) */
+#define topt_use_bdat          0x0200  /* prepend chunks with RFC3030 BDAT header */
+#define topt_output_string     0x0400  /* create string rather than write to fd */
+#define topt_continuation      0x0800  /* do not reset buffer */
+#define topt_not_socket                0x1000  /* cannot do socket-only syscalls */
+
+/* Options for smtp_write_command */
+
+enum {
+  SCMD_FLUSH = 0,      /* write to kernel */
+  SCMD_MORE,           /* write to kernel, but likely more soon */
+  SCMD_BUFFER          /* stash in application cmd output buffer */
+};
 
 /* Flags for recipient_block, used in DSN support */
 
 
 /* Flags for recipient_block, used in DSN support */
 
@@ -927,6 +970,37 @@ enum { ACL_WHERE_RCPT,       /* Some controls are for RCPT only */
        ACL_WHERE_UNKNOWN     /* Currently used by a ${acl:name} expansion */
      };
 
        ACL_WHERE_UNKNOWN     /* Currently used by a ${acl:name} expansion */
      };
 
+#define ACL_BIT_RCPT           BIT(ACL_WHERE_RCPT)
+#define ACL_BIT_MAIL           BIT(ACL_WHERE_MAIL)
+#define ACL_BIT_PREDATA                BIT(ACL_WHERE_PREDATA)
+#define ACL_BIT_MIME           BIT(ACL_WHERE_MIME)
+#define ACL_BIT_DKIM           BIT(ACL_WHERE_DKIM)
+#define ACL_BIT_DATA           BIT(ACL_WHERE_DATA)
+#ifdef DISABLE_PRDR
+# define ACL_BIT_PRDR          0
+#else
+# define ACL_BIT_PRDR          BIT(ACL_WHERE_PRDR)
+#endif
+#define ACL_BIT_NOTSMTP                BIT(ACL_WHERE_NOTSMTP)
+#define ACL_BIT_AUTH           BIT(ACL_WHERE_AUTH)
+#define ACL_BIT_CONNECT                BIT(ACL_WHERE_CONNECT)
+#define ACL_BIT_ETRN           BIT(ACL_WHERE_ETRN)
+#define ACL_BIT_EXPN           BIT(ACL_WHERE_EXPN)
+#define ACL_BIT_HELO           BIT(ACL_WHERE_HELO)
+#define ACL_BIT_MAILAUTH       BIT(ACL_WHERE_MAILAUTH)
+#define ACL_BIT_NOTSMTP_START  BIT(ACL_WHERE_NOTSMTP_START)
+#define ACL_BIT_NOTQUIT                BIT(ACL_WHERE_NOTQUIT)
+#define ACL_BIT_QUIT           BIT(ACL_WHERE_QUIT)
+#define ACL_BIT_STARTTLS       BIT(ACL_WHERE_STARTTLS)
+#define ACL_BIT_VRFY           BIT(ACL_WHERE_VRFY)
+#define ACL_BIT_DELIVERY       BIT(ACL_WHERE_DELIVERY)
+#define ACL_BIT_UNKNOWN                BIT(ACL_WHERE_UNKNOWN)
+
+#define ACL_BITS_HAVEDATA      (ACL_BIT_MIME | ACL_BIT_DKIM | ACL_BIT_DATA \
+                               | ACL_BIT_PRDR \
+                               | ACL_BIT_NOTSMTP | ACL_BIT_QUIT | ACL_BIT_NOTQUIT)
+
+
 /* Situations for spool_write_header() */
 
 enum { SW_RECEIVING, SW_DELIVERING, SW_MODIFYING };
 /* Situations for spool_write_header() */
 
 enum { SW_RECEIVING, SW_DELIVERING, SW_MODIFYING };
@@ -954,14 +1028,101 @@ enum { FILTER_UNSET, FILTER_FORWARD, FILTER_EXIM, FILTER_SIEVE };
 
 /* Codes for ESMTP facilities offered by peer */
 
 
 /* Codes for ESMTP facilities offered by peer */
 
-#define PEER_OFFERED_TLS       BIT(0)
-#define PEER_OFFERED_IGNQ      BIT(1)
-#define PEER_OFFERED_PRDR      BIT(2)
-#define PEER_OFFERED_UTF8      BIT(3)
-#define PEER_OFFERED_DSN       BIT(4)
-#define PEER_OFFERED_PIPE      BIT(5)
-#define PEER_OFFERED_SIZE      BIT(6)
-#define PEER_OFFERED_CHUNKING  BIT(7)
+#define OPTION_TLS             BIT(0)
+#define OPTION_IGNQ            BIT(1)
+#define OPTION_PRDR            BIT(2)
+#define OPTION_UTF8            BIT(3)
+#define OPTION_DSN             BIT(4)
+#define OPTION_PIPE            BIT(5)
+#define OPTION_SIZE            BIT(6)
+#define OPTION_CHUNKING                BIT(7)
+#define OPTION_EARLY_PIPE      BIT(8)
+
+/* Argument for *_getc */
+
+#define GETC_BUFFER_UNLIMITED  UINT_MAX
+
+/* UTF-8 chars for line-drawing */
+
+#define UTF8_DOWN_RIGHT                "\xE2\x95\xAD"
+#define UTF8_VERT              "\xE2\x94\x82"
+#define UTF8_HORIZ             "\xE2\x94\x80"
+#define UTF8_VERT_RIGHT                "\xE2\x94\x9C"
+#define UTF8_UP_RIGHT          "\xE2\x95\xB0"
+#define UTF8_VERT_2DASH                "\xE2\x95\x8E"
+
+
+/* Options on tls_close */
+#define TLS_NO_SHUTDOWN                0       /* Just forget the context */
+#define TLS_SHUTDOWN_NOWAIT    1       /* Send alert; do not wait */
+#define TLS_SHUTDOWN_WAIT      2       /* Send alert & wait for peer's alert */
+#define TLS_SHUTDOWN_WONLY     3       /* only wait for peer's alert */
+
+
+#ifdef COMPILE_UTILITY
+# define ALARM(seconds) alarm(seconds);
+# define ALARM_CLR(seconds) alarm(seconds);
+#else
+/* For debugging of odd alarm-signal problems, stash caller info while the
+alarm is active.  Clear it down on cancelling the alarm so we can tell there
+should not be one active. */
+
+# define ALARM(seconds) \
+    debug_selector & D_any \
+    ? (sigalarm_setter = CUS __FUNCTION__, alarm(seconds)) : alarm(seconds);
+# define ALARM_CLR(seconds) \
+    debug_selector & D_any \
+    ? (sigalarm_setter = NULL, alarm(seconds)) : alarm(seconds);
+#endif
+
+#define AUTHS_REGEX US"\\n250[\\s\\-]AUTH\\s+([\\-\\w \\t]+)(?:\\n|$)"
+
+#define EARLY_PIPE_FEATURE_NAME "PIPECONNECT"
+#define EARLY_PIPE_FEATURE_LEN  11
+
+
+/* Flags for auth_client_item() */
+
+#define AUTH_ITEM_FIRST        BIT(0)
+#define AUTH_ITEM_LAST BIT(1)
+#define AUTH_ITEM_IGN64        BIT(2)
+
+
+/* Flags for tls_{in,out}_resumption */
+#define RESUME_SUPPORTED       BIT(0)
+#define RESUME_CLIENT_REQUESTED        BIT(1)
+#define RESUME_CLIENT_SUGGESTED        BIT(2)
+#define RESUME_SERVER_TICKET   BIT(3)
+#define RESUME_USED            BIT(4)
+
+#define RESUME_DECODE_STRING \
+         US"not requested or offered : 0x02 :client requested, no server ticket" \
+    ": 0x04 : 0x05 : 0x06 :client offered session, no server action" \
+    ": 0x08 :no client request: 0x0A :client requested new ticket, server provided" \
+    ": 0x0C :client offered session, not used: 0x0E :client offered session, server only provided new ticket" \
+    ": 0x10 :session resumed unasked: 0x12 :session resumed unasked" \
+    ": 0x14 : 0x15 : 0x16 :session resumed" \
+    ": 0x18 :session resumed unasked: 0x1A :session resumed unasked" \
+    ": 0x1C :session resumed: 0x1E :session resumed, also new ticket"
+
+/* Flags for string_vformat */
+#define SVFMT_EXTEND           BIT(0)
+#define SVFMT_REBUFFER         BIT(1)
+#define SVFMT_TAINT_NOCHK      BIT(2)
+
+
+#define NOTIFIER_SOCKET_NAME   "exim_daemon_notify"
+/* Notify message types */
+#define NOTIFY_MSG_QRUN                1
+#define NOTIFY_QUEUE_SIZE_REQ  2
+#define NOTIFY_REGEX           3
 
 
+/* Flags for match_check_string() */
+typedef unsigned mcs_flags;
+#define MCS_NOFLAGS            0
+#define MCS_PARTIAL            BIT(0)  /* permit partial- search types */
+#define MCS_CASELESS           BIT(1)  /* caseless matching where possible */
+#define MCS_AT_SPECIAL         BIT(2)  /* recognize @, @[], etc. */
+#define MCS_CACHEABLE          BIT(3)  /* no dynamic expansions used for pattern */
 
 /* End of macros.h */
 
 /* End of macros.h */