- rel 6; fixes from upstream branch auto/th/exim-4.89-6
authorArkadiusz Miśkiewicz <arekm@maven.pl>
Tue, 8 Aug 2017 06:54:39 +0000 (08:54 +0200)
committerArkadiusz Miśkiewicz <arekm@maven.pl>
Tue, 8 Aug 2017 06:54:39 +0000 (08:54 +0200)
branch.sh [new file with mode: 0755]
exim-git.patch [deleted file]
exim-memleak.patch [deleted file]
exim.spec

diff --git a/branch.sh b/branch.sh
new file mode 100755 (executable)
index 0000000..4dbf809
--- /dev/null
+++ b/branch.sh
@@ -0,0 +1,32 @@
+#!/bin/sh
+set -e
+url=git://git.exim.org/exim.git
+package=exim
+tag=exim-4_89
+branch=exim-4_89+fixes
+out=$package-git.patch
+repo=$package.git
+
+# use filterdiff, etc to exclude bad chunks from diff
+filter() {
+       cat
+}
+
+if [ ! -d $repo ]; then
+       git clone --bare $url -b $branch $repo
+fi
+
+cd $repo
+       git fetch origin +$branch:$branch +refs/tags/$tag:refs/tags/$tag
+       git log -p --reverse $tag..$branch ":(exclude)doc/doc-*" ":(exclude)test" ":(exclude).*" | filter > ../$out.tmp
+cd ..
+
+if cmp -s $out{,.tmp}; then
+       echo >&2 "No new diffs..."
+       rm -f $out.tmp
+       exit 0
+fi
+mv -f $out{.tmp,}
+
+../md5 $package.spec
+../dropin $out
diff --git a/exim-git.patch b/exim-git.patch
deleted file mode 100644 (file)
index 915f246..0000000
+++ /dev/null
@@ -1,1394 +0,0 @@
-commit da1aecfce80fba32b9abb328cf78088d95b7700a
-Author: Heiko Schlittermann (HS12-RIPE) <hs@schlittermann.de>
-Date:   Wed Aug 19 15:22:41 2015 +0200
-
-    Fix post-transport-crash.
-    
-    The crash probably was introduced in a39bd74d3e94 and
-    needs 'split_spool_directory=yes' to expose.
-    
-    Thanks to Wolfgang Breyha, who found the same fix.
-    
-    (cherry picked from commit 6b51df8340eacc95e3def9a4376506610e91996c)
-
-diff --git a/src/src/transport.c b/src/src/transport.c
-index fa6f869..a6ad3ed 100644
---- a/src/src/transport.c
-+++ b/src/src/transport.c
-@@ -1752,7 +1752,7 @@ while (1)
-     {
-     if (split_spool_directory)
-       sprintf(CS spool_file, "%s%c/%s-D",
--                    spool_dir, new_message_id[5], msgq[i].message_id);
-+                    spool_dir, msgq[i].message_id[5], msgq[i].message_id);
-     else
-       sprintf(CS spool_file, "%s%s-D", spool_dir, msgq[i].message_id);
-
-commit d7168d8b112d3ba642a25ed04de36fb76d4a847d
-Author: Heiko Schlittermann (HS12-RIPE) <hs@schlittermann.de>
-Date:   Thu Aug 20 13:58:06 2015 +0200
-
-    Fix post-transport-crash: safeguard for missing spool BUG 1671
-    
-    Based on a proposal from Wolfgang Breyha.
-    
-    (cherry picked from commit dadff1d47e54962b0fdf98e8ce5cef42b6cb7fb5)
-
-diff --git a/src/src/deliver.c b/src/src/deliver.c
-index 78f8f4b..4154ff7 100644
---- a/src/src/deliver.c
-+++ b/src/src/deliver.c
-@@ -9,6 +9,7 @@
- #include "exim.h"
-+#include <assert.h>
- /* Data block for keeping track of subprocesses for parallel remote
-@@ -7904,17 +7905,36 @@ if (!regex_IGNOREQUOTA) regex_IGNOREQUOTA =
- uschar *
- deliver_get_sender_address (uschar * id)
- {
-+int rc;
-+uschar * new_sender_address,
-+       * save_sender_address;
-+
- if (!spool_open_datafile(id))
-   return NULL;
-+/* Save and restore the global sender_address.  I'm not sure if we should
-+not save/restore all the other global variables too, because
-+spool_read_header() may change all of them. But OTOH, when this
-+deliver_get_sender_address() gets called, the current message is done
-+already and nobody needs the globals anymore. (HS12, 2015-08-21) */
-+
- sprintf(CS spoolname, "%s-H", id);
--if (spool_read_header(spoolname, TRUE, TRUE) != spool_read_OK)
-+save_sender_address = sender_address;
-+
-+rc = spool_read_header(spoolname, TRUE, TRUE);
-+
-+new_sender_address = sender_address;
-+sender_address = save_sender_address;
-+
-+if (rc != spool_read_OK)
-   return NULL;
-+assert(new_sender_address);
-+
- (void)close(deliver_datafile);
- deliver_datafile = -1;
--return sender_address;
-+return new_sender_address;
- }
- /* vi: aw ai sw=2
-diff --git a/src/src/transports/smtp.c b/src/src/transports/smtp.c
-index a952413..5ac5533 100644
---- a/src/src/transports/smtp.c
-+++ b/src/src/transports/smtp.c
-@@ -1274,14 +1274,19 @@ we will veto this new message.  */
- static BOOL
- smtp_are_same_identities(uschar * message_id, smtp_compare_t * s_compare)
- {
--uschar * save_sender_address = sender_address;
--uschar * current_local_identity =
-+
-+uschar * message_local_identity,
-+       * current_local_identity,
-+       * new_sender_address;
-+
-+current_local_identity =
-   smtp_local_identity(s_compare->current_sender_address, s_compare->tblock);
--uschar * new_sender_address = deliver_get_sender_address(message_id);
--uschar * message_local_identity =
--  smtp_local_identity(new_sender_address, s_compare->tblock);
--sender_address = save_sender_address;
-+if (!(new_sender_address = deliver_get_sender_address(message_id)))
-+    return 0;
-+
-+message_local_identity =
-+  smtp_local_identity(new_sender_address, s_compare->tblock);
- return Ustrcmp(current_local_identity, message_local_identity) == 0;
- }
-
-commit 9e1acebc3fbb288da804ab9031c7c448dffd841a
-Author: Heiko Schlittermann (HS12-RIPE) <hs@schlittermann.de>
-Date:   Tue Aug 11 17:36:29 2015 +0200
-
-    Fix ESMTP MAIL command option processing
-    
-    If the address containes spaces, the option processing
-    was confused.
-    
-    (cherry picked from commit 2ef7ed082481b2dccd3c2e0eae849b24bf0b172a)
-
-diff --git a/src/src/smtp_in.c b/src/src/smtp_in.c
-index cf0a5d6..980d54b 100644
---- a/src/src/smtp_in.c
-+++ b/src/src/smtp_in.c
-@@ -9,6 +9,7 @@
- #include "exim.h"
-+#include <assert.h>
- /* Initialize for TCP wrappers if so configured. It appears that the macro
-@@ -232,6 +233,7 @@ static uschar *protocols[] = {
- /* Sanity check and validate optional args to MAIL FROM: envelope */
- enum {
-+  ENV_MAIL_OPT_NULL,
-   ENV_MAIL_OPT_SIZE, ENV_MAIL_OPT_BODY, ENV_MAIL_OPT_AUTH,
- #ifndef DISABLE_PRDR
-   ENV_MAIL_OPT_PRDR,
-@@ -240,7 +242,6 @@ enum {
- #ifdef EXPERIMENTAL_INTERNATIONAL
-   ENV_MAIL_OPT_UTF8,
- #endif
--  ENV_MAIL_OPT_NULL
-   };
- typedef struct {
-   uschar *   name;  /* option requested during MAIL cmd */
-@@ -260,7 +261,8 @@ static env_mail_type_t env_mail_type_list[] = {
- #ifdef EXPERIMENTAL_INTERNATIONAL
-     { US"SMTPUTF8",ENV_MAIL_OPT_UTF8,  FALSE },               /* rfc6531 */
- #endif
--    { US"NULL",   ENV_MAIL_OPT_NULL,   FALSE }
-+    /* keep this the last entry */
-+    { US"NULL",   ENV_MAIL_OPT_NULL,   FALSE },
-   };
- /* When reading SMTP from a remote host, we have to use our own versions of the
-@@ -3887,7 +3889,7 @@ while (done <= 0)
-       if (!extract_option(&name, &value)) break;
-       for (mail_args = env_mail_type_list;
--           (char *)mail_args < (char *)env_mail_type_list + sizeof(env_mail_type_list);
-+           mail_args->value != ENV_MAIL_OPT_NULL;
-            mail_args++
-           )
-         if (strcmpic(name, mail_args->name) == 0)
-@@ -4066,15 +4068,17 @@ while (done <= 0)
-           }
-         break;
- #endif
--        /* Unknown option. Stick back the terminator characters and break
-+        /* No valid option. Stick back the terminator characters and break
-         the loop.  Do the name-terminator second as extract_option sets
--      value==name when it found no equal-sign.
--      An error for a malformed address will occur. */
--        default:
-+        value==name when it found no equal-sign.
-+        An error for a malformed address will occur. */
-+        case ENV_MAIL_OPT_NULL:
-           value[-1] = '=';
-           name[-1] = ' ';
-           arg_error = TRUE;
-           break;
-+
-+        default:  assert(0);
-         }
-       /* Break out of for loop if switch() had bad argument or
-          when start of the email address is reached */
-
-commit 22c82c48aa5d23c49d38e3581810ea54587df61b
-Author: Jeremy Harris <jgh146exb@wizmail.org>
-Date:   Tue Aug 25 10:36:27 2015 +0100
-
-    Close logs after daemon-process exceptional write.  Bug 728
-    
-    (cherry picked from commit c8899c20aa08c9ae6a4c291aad23ba90512bebe4)
-
-diff --git a/src/src/daemon.c b/src/src/daemon.c
-index 894a96f..a7a49f0 100644
---- a/src/src/daemon.c
-+++ b/src/src/daemon.c
-@@ -735,6 +735,7 @@ else (void)close(dup_accept_socket);
- /* Release any store used in this process, including the store used for holding
- the incoming host address and an expanded active_hostname. */
-+log_close_all();
- store_reset(reset_point);
- sender_host_address = NULL;
- }
-
-commit 4d3b8805796ffa39889060d9f216bfaf7391c542
-Author: Jeremy Harris <jgh146exb@wizmail.org>
-Date:   Thu Sep 17 13:35:16 2015 +0100
-
-    DNS: time-limit cached returns, using TTL.  Bug 1395
-    
-    This can matter for fast-changing data such as DNSBLs.
-    
-    (cherry picked from commit 14b3c5bc64a16df07583fe4b5ef2e0129d063893)
-    
-    DNS: avoid overflow in cache TTL for negative entries.  Bug 1395
-    
-    (cherry picked from commit e162fc9757d4b8cb41aca74214e968622d6c3dee)
-
-diff --git a/src/src/dns.c b/src/src/dns.c
-index 64958d9..abed126 100644
---- a/src/src/dns.c
-+++ b/src/src/dns.c
-@@ -390,7 +390,8 @@ from the following bytes. */
- dnss->aptr += namelen;
- GETSHORT(dnss->srr.type, dnss->aptr); /* Record type */
--dnss->aptr += 6;                      /* Don't want class or TTL */
-+dnss->aptr += 2;                      /* Don't want class */
-+GETLONG(dnss->srr.ttl, dnss->aptr);   /* TTL */
- GETSHORT(dnss->srr.size, dnss->aptr); /* Size of data portion */
- dnss->srr.data = dnss->aptr;          /* The record's data follows */
- dnss->aptr += dnss->srr.size;         /* Advance to next RR */
-diff --git a/src/src/lookupapi.h b/src/src/lookupapi.h
-index cdd1c85..03de8f6 100644
---- a/src/src/lookupapi.h
-+++ b/src/src/lookupapi.h
-@@ -34,7 +34,7 @@ typedef struct lookup_info {
-     int,                          /* length of key or query */
-     uschar **,                    /* for returning answer */
-     uschar **,                    /* for error message */
--    BOOL *);                      /* to request cache cleanup */
-+    uint *);                      /* cache TTL, sconds */
-   void (*close)(                  /* close function */
-     void *);                      /* handle */
-   void (*tidy)(void);             /* tidy function */
-@@ -46,9 +46,10 @@ typedef struct lookup_info {
- } lookup_info;
- /* This magic number is used by the following lookup_module_info structure
--   for checking API compatibility. It's equivalent to the string"LMM2" */
--#define LOOKUP_MODULE_INFO_MAGIC 0x4c4d4d32
-+   for checking API compatibility. It used to be equivalent to the string"LMM3" */
-+#define LOOKUP_MODULE_INFO_MAGIC 0x4c4d4933
- /* Version 2 adds: version_report */
-+/* Version 3 change: non/cache becomes TTL in seconds */
- typedef struct lookup_module_info {
-   uint magic;
-diff --git a/src/src/lookups/README b/src/src/lookups/README
-index 98905dc..31fea64 100644
---- a/src/src/lookups/README
-+++ b/src/src/lookups/README
-@@ -122,12 +122,15 @@ DEFER. The arguments are:
-   uschar **errmsg     where to put an error message on failure;
-                       this is initially set to "", and should be left
-                       as that for a standard "entry not found" error
--  BOOL *do_cache      the lookup should set this to FALSE when it changes data.
--                      This is TRUE by default. When set to FALSE the cache tree
-+  uint *do_cache      the lookup should set this to 0 when it changes data.
-+                      This is MAXINT by default. When set to 0 the cache tree
-                       of the current search handle will be cleaned and the
-                       current result will NOT be cached. Currently the mysql
-                       and pgsql lookups use this when UPDATE/INSERT queries are
-                       executed.
-+                      If set to a nonzero number of seconds, the cached value
-+                      becomes unusable after this time. Currently the dnsdb
-+                      lookup uses this to support the TTL value.
- Even though the key is zero-terminated, the length is passed because in the
- common case it has been computed already and is often needed.
-diff --git a/src/src/lookups/cdb.c b/src/src/lookups/cdb.c
-index ea017de..ba925dc 100644
---- a/src/src/lookups/cdb.c
-+++ b/src/src/lookups/cdb.c
-@@ -279,7 +279,7 @@ cdb_find(void *handle,
-         int  key_len,
-         uschar **result,
-         uschar **errmsg,
--        BOOL *do_cache)
-+        uint *do_cache)
- {
-   struct cdb_state * cdbp = handle;
-   uint32 item_key_len,
-diff --git a/src/src/lookups/dbmdb.c b/src/src/lookups/dbmdb.c
-index 03248e4..b8c42d5 100644
---- a/src/src/lookups/dbmdb.c
-+++ b/src/src/lookups/dbmdb.c
-@@ -87,7 +87,7 @@ the keylength in order to include the terminating zero. */
- static int
- dbmdb_find(void *handle, uschar *filename, const uschar *keystring, int length,
--  uschar **result, uschar **errmsg, BOOL *do_cache)
-+  uschar **result, uschar **errmsg, uint *do_cache)
- {
- EXIM_DB *d = (EXIM_DB *)handle;
- EXIM_DATUM key, data;
-@@ -120,7 +120,7 @@ return FAIL;
- int
- static dbmnz_find(void *handle, uschar *filename, const uschar *keystring, int length,
--  uschar **result, uschar **errmsg, BOOL *do_cache)
-+  uschar **result, uschar **errmsg, uint *do_cache)
- {
- return dbmdb_find(handle, filename, keystring, length-1, result, errmsg,
-   do_cache);
-@@ -140,7 +140,7 @@ return dbmdb_find(handle, filename, keystring, length-1, result, errmsg,
- static int
- dbmjz_find(void *handle, uschar *filename, const uschar *keystring, int length,
--  uschar **result, uschar **errmsg, BOOL *do_cache)
-+  uschar **result, uschar **errmsg, uint *do_cache)
- {
- uschar *key_item, *key_buffer, *key_p;
- const uschar *key_elems = keystring;
-diff --git a/src/src/lookups/dnsdb.c b/src/src/lookups/dnsdb.c
-index e3de279..70e6c8c 100644
---- a/src/src/lookups/dnsdb.c
-+++ b/src/src/lookups/dnsdb.c
-@@ -131,7 +131,7 @@ separator, as always, is colon. */
- static int
- dnsdb_find(void *handle, uschar *filename, const uschar *keystring, int length,
--  uschar **result, uschar **errmsg, BOOL *do_cache)
-+  uschar **result, uschar **errmsg, uint *do_cache)
- {
- int rc;
- int size = 256;
-@@ -388,6 +388,9 @@ while ((domain = string_nextinlist(&keystring, &sep, NULL, 0)))
-       {
-       if (rr->type != searchtype) continue;
-+      if (*do_cache > rr->ttl)
-+      *do_cache = rr->ttl;
-+
-       if (type == T_A || type == T_AAAA || type == T_ADDRESSES)
-         {
-         dns_address *da;
-diff --git a/src/src/lookups/dsearch.c b/src/src/lookups/dsearch.c
-index f8c592a..9f7dd8d 100644
---- a/src/src/lookups/dsearch.c
-+++ b/src/src/lookups/dsearch.c
-@@ -67,7 +67,7 @@ for us. */
- int
- static dsearch_find(void *handle, uschar *dirname, const uschar *keystring, int length,
--  uschar **result, uschar **errmsg, BOOL *do_cache)
-+  uschar **result, uschar **errmsg, uint *do_cache)
- {
- struct stat statbuf;
- int save_errno;
-diff --git a/src/src/lookups/ibase.c b/src/src/lookups/ibase.c
-index 23e1dea..7fd53d0 100644
---- a/src/src/lookups/ibase.c
-+++ b/src/src/lookups/ibase.c
-@@ -451,7 +451,7 @@ deferred with a retryable error. */
- static int
- ibase_find(void *handle, uschar * filename, uschar * query, int length,
--           uschar ** result, uschar ** errmsg, BOOL *do_cache)
-+           uschar ** result, uschar ** errmsg, uint *do_cache)
- {
-     int sep = 0;
-     uschar *server;
-diff --git a/src/src/lookups/ldap.c b/src/src/lookups/ldap.c
-index a56eff3..b870df1 100644
---- a/src/src/lookups/ldap.c
-+++ b/src/src/lookups/ldap.c
-@@ -1339,7 +1339,7 @@ The handle and filename arguments are not used. */
- static int
- eldap_find(void *handle, uschar *filename, const uschar *ldap_url, int length,
--  uschar **result, uschar **errmsg, BOOL *do_cache)
-+  uschar **result, uschar **errmsg, uint *do_cache)
- {
- /* Keep picky compilers happy */
- do_cache = do_cache;
-@@ -1348,7 +1348,7 @@ return(control_ldap_search(ldap_url, SEARCH_LDAP_SINGLE, result, errmsg));
- static int
- eldapm_find(void *handle, uschar *filename, const uschar *ldap_url, int length,
--  uschar **result, uschar **errmsg, BOOL *do_cache)
-+  uschar **result, uschar **errmsg, uint *do_cache)
- {
- /* Keep picky compilers happy */
- do_cache = do_cache;
-@@ -1357,7 +1357,7 @@ return(control_ldap_search(ldap_url, SEARCH_LDAP_MULTIPLE, result, errmsg));
- static int
- eldapdn_find(void *handle, uschar *filename, const uschar *ldap_url, int length,
--  uschar **result, uschar **errmsg, BOOL *do_cache)
-+  uschar **result, uschar **errmsg, uint *do_cache)
- {
- /* Keep picky compilers happy */
- do_cache = do_cache;
-@@ -1366,7 +1366,7 @@ return(control_ldap_search(ldap_url, SEARCH_LDAP_DN, result, errmsg));
- int
- eldapauth_find(void *handle, uschar *filename, const uschar *ldap_url, int length,
--  uschar **result, uschar **errmsg, BOOL *do_cache)
-+  uschar **result, uschar **errmsg, uint *do_cache)
- {
- /* Keep picky compilers happy */
- do_cache = do_cache;
-diff --git a/src/src/lookups/lf_functions.h b/src/src/lookups/lf_functions.h
-index 73e9303..d2487d3 100644
---- a/src/src/lookups/lf_functions.h
-+++ b/src/src/lookups/lf_functions.h
-@@ -12,7 +12,7 @@ extern int     lf_check_file(int, uschar *, int, int, uid_t *, gid_t *,
- extern uschar *lf_quote(uschar *, uschar *, int, uschar *, int *, int *);
- extern int     lf_sqlperform(const uschar *, const uschar *, const uschar *,
-                const uschar *, uschar **,
--                 uschar **, BOOL *, int(*)(const uschar *, uschar *, uschar **,
--                 uschar **, BOOL *, BOOL *));
-+                 uschar **, uint *, int(*)(const uschar *, uschar *, uschar **,
-+                 uschar **, BOOL *, uint *));
- /* End of lf_functions.h */
-diff --git a/src/src/lookups/lf_sqlperform.c b/src/src/lookups/lf_sqlperform.c
-index 2d7f326..6d4f7a7 100644
---- a/src/src/lookups/lf_sqlperform.c
-+++ b/src/src/lookups/lf_sqlperform.c
-@@ -27,7 +27,7 @@ Arguments:
-   query          the query
-   result         where to pass back the result
-   errmsg         where to pass back an error message
--  do_cache       to be set FALSE if data is changed
-+  do_cache       to be set zero if data is changed
-   func           the lookup function to call
- Returns:         the return from the lookup function, or DEFER
-@@ -36,8 +36,8 @@ Returns:         the return from the lookup function, or DEFER
- int
- lf_sqlperform(const uschar *name, const uschar *optionname,
-   const uschar *optserverlist, const uschar *query,
--  uschar **result, uschar **errmsg, BOOL *do_cache,
--  int(*fn)(const uschar *, uschar *, uschar **, uschar **, BOOL *, BOOL *))
-+  uschar **result, uschar **errmsg, uint *do_cache,
-+  int(*fn)(const uschar *, uschar *, uschar **, uschar **, BOOL *, uint *))
- {
- int sep, rc;
- uschar *server;
-diff --git a/src/src/lookups/lsearch.c b/src/src/lookups/lsearch.c
-index 3883d4b..eb70a45 100644
---- a/src/src/lookups/lsearch.c
-+++ b/src/src/lookups/lsearch.c
-@@ -323,7 +323,7 @@ return FAIL;
- static int
- lsearch_find(void *handle, uschar *filename, const uschar *keystring, int length,
--  uschar **result, uschar **errmsg, BOOL *do_cache)
-+  uschar **result, uschar **errmsg, uint *do_cache)
- {
- do_cache = do_cache;  /* Keep picky compilers happy */
- return internal_lsearch_find(handle, filename, keystring, length, result,
-@@ -340,7 +340,7 @@ return internal_lsearch_find(handle, filename, keystring, length, result,
- static int
- wildlsearch_find(void *handle, uschar *filename, const uschar *keystring, int length,
--  uschar **result, uschar **errmsg, BOOL *do_cache)
-+  uschar **result, uschar **errmsg, uint *do_cache)
- {
- do_cache = do_cache;  /* Keep picky compilers happy */
- return internal_lsearch_find(handle, filename, keystring, length, result,
-@@ -357,7 +357,7 @@ return internal_lsearch_find(handle, filename, keystring, length, result,
- static int
- nwildlsearch_find(void *handle, uschar *filename, const uschar *keystring, int length,
--  uschar **result, uschar **errmsg, BOOL *do_cache)
-+  uschar **result, uschar **errmsg, uint *do_cache)
- {
- do_cache = do_cache;  /* Keep picky compilers happy */
- return internal_lsearch_find(handle, filename, keystring, length, result,
-@@ -375,7 +375,7 @@ return internal_lsearch_find(handle, filename, keystring, length, result,
- static int
- iplsearch_find(void *handle, uschar *filename, const uschar *keystring, int length,
--  uschar **result, uschar **errmsg, BOOL *do_cache)
-+  uschar **result, uschar **errmsg, uint *do_cache)
- {
- do_cache = do_cache;  /* Keep picky compilers happy */
- if ((length == 1 && keystring[0] == '*') ||
-diff --git a/src/src/lookups/mysql.c b/src/src/lookups/mysql.c
-index 8dff86a..1ce8831 100644
---- a/src/src/lookups/mysql.c
-+++ b/src/src/lookups/mysql.c
-@@ -74,7 +74,7 @@ Arguments:
-   resultptr    where to store the result
-   errmsg       where to point an error message
-   defer_break  TRUE if no more servers are to be tried after DEFER
--  do_cache     set false if data is changed
-+  do_cache     set zero if data is changed
- The server string is of the form "host/dbname/user/password". The host can be
- host:port. This string is in a nextinlist temporary buffer, so can be
-@@ -85,7 +85,7 @@ Returns:       OK, FAIL, or DEFER
- static int
- perform_mysql_search(const uschar *query, uschar *server, uschar **resultptr,
--  uschar **errmsg, BOOL *defer_break, BOOL *do_cache)
-+  uschar **errmsg, BOOL *defer_break, uint *do_cache)
- {
- MYSQL *mysql_handle = NULL;        /* Keep compilers happy */
- MYSQL_RES *mysql_result = NULL;
-@@ -225,7 +225,7 @@ can be detected by calling mysql_field_count(). If its result is zero, no data
- was expected (this is all explained clearly in the MySQL manual). In this case,
- we return the number of rows affected by the command. In this event, we do NOT
- want to cache the result; also the whole cache for the handle must be cleaned
--up. Setting do_cache FALSE requests this. */
-+up. Setting do_cache zero requests this. */
- if ((mysql_result = mysql_use_result(mysql_handle)) == NULL)
-   {
-@@ -233,7 +233,7 @@ if ((mysql_result = mysql_use_result(mysql_handle)) == NULL)
-     {
-     DEBUG(D_lookup) debug_printf("MYSQL: query was not one that returns data\n");
-     result = string_sprintf("%d", mysql_affected_rows(mysql_handle));
--    *do_cache = FALSE;
-+    *do_cache = 0;
-     goto MYSQL_EXIT;
-     }
-   *errmsg = string_sprintf("MYSQL: lookup result failed: %s\n",
-@@ -341,7 +341,7 @@ shared with other SQL lookups. */
- static int
- mysql_find(void *handle, uschar *filename, const uschar *query, int length,
--  uschar **result, uschar **errmsg, BOOL *do_cache)
-+  uschar **result, uschar **errmsg, uint *do_cache)
- {
- return lf_sqlperform(US"MySQL", US"mysql_servers", mysql_servers, query,
-   result, errmsg, do_cache, perform_mysql_search);
-diff --git a/src/src/lookups/nis.c b/src/src/lookups/nis.c
-index 7b012b1..1faa884 100644
---- a/src/src/lookups/nis.c
-+++ b/src/src/lookups/nis.c
-@@ -42,7 +42,7 @@ code. */
- static int
- nis_find(void *handle, uschar *filename, uschar *keystring, int length,
--  uschar **result, uschar **errmsg, BOOL *do_cache)
-+  uschar **result, uschar **errmsg, uint *do_cache)
- {
- int rc;
- uschar *nis_data;
-@@ -68,7 +68,7 @@ return (rc == YPERR_KEY || rc == YPERR_MAP)? FAIL : DEFER;
- static int
- nis0_find(void *handle, uschar *filename, uschar *keystring, int length,
--  uschar **result, uschar **errmsg, BOOL *do_cache)
-+  uschar **result, uschar **errmsg, uint *do_cache)
- {
- int rc;
- uschar *nis_data;
-diff --git a/src/src/lookups/nisplus.c b/src/src/lookups/nisplus.c
-index 8895cee..a4a7a2d 100644
---- a/src/src/lookups/nisplus.c
-+++ b/src/src/lookups/nisplus.c
-@@ -43,7 +43,7 @@ equals sign. */
- static int
- nisplus_find(void *handle, uschar *filename, uschar *query, int length,
--  uschar **result, uschar **errmsg, BOOL *do_cache)
-+  uschar **result, uschar **errmsg, uint *do_cache)
- {
- int i;
- int ssize = 0;
-diff --git a/src/src/lookups/oracle.c b/src/src/lookups/oracle.c
-index 1f2520a..adb17b4 100644
---- a/src/src/lookups/oracle.c
-+++ b/src/src/lookups/oracle.c
-@@ -517,7 +517,7 @@ deferred with a retryable error. */
- static int
- oracle_find(void *handle, uschar *filename, uschar *query, int length,
--  uschar **result, uschar **errmsg, BOOL *do_cache)
-+  uschar **result, uschar **errmsg, uint *do_cache)
- {
- int sep = 0;
- uschar *server;
-diff --git a/src/src/lookups/passwd.c b/src/src/lookups/passwd.c
-index e726f3e..315677f 100644
---- a/src/src/lookups/passwd.c
-+++ b/src/src/lookups/passwd.c
-@@ -34,7 +34,7 @@ return (void *)(-1);     /* Just return something non-null */
- static int
- passwd_find(void *handle, uschar *filename, const uschar *keystring, int length,
--  uschar **result, uschar **errmsg, BOOL *do_cache)
-+  uschar **result, uschar **errmsg, uint *do_cache)
- {
- struct passwd *pw;
-diff --git a/src/src/lookups/pgsql.c b/src/src/lookups/pgsql.c
-index c86ac23..4be3d98 100644
---- a/src/src/lookups/pgsql.c
-+++ b/src/src/lookups/pgsql.c
-@@ -119,7 +119,7 @@ Returns:       OK, FAIL, or DEFER
- static int
- perform_pgsql_search(const uschar *query, uschar *server, uschar **resultptr,
--  uschar **errmsg, BOOL *defer_break, BOOL *do_cache)
-+  uschar **errmsg, BOOL *defer_break, uint *do_cache)
- {
- PGconn *pg_conn = NULL;
- PGresult *pg_result = NULL;
-@@ -290,10 +290,10 @@ else
-     /* The command was successful but did not return any data since it was
-      * not SELECT but either an INSERT, UPDATE or DELETE statement. Tell the
-      * high level code to not cache this query, and clean the current cache for
--     * this handle by setting *do_cache FALSE. */
-+     * this handle by setting *do_cache zero. */
-     result = string_copy(US PQcmdTuples(pg_result));
-     offset = Ustrlen(result);
--    *do_cache = FALSE;
-+    *do_cache = 0;
-     DEBUG(D_lookup) debug_printf("PGSQL: command does not return any data "
-       "but was successful. Rows affected: %s\n", result);
-@@ -399,7 +399,7 @@ shared with other SQL lookups. */
- static int
- pgsql_find(void *handle, uschar *filename, const uschar *query, int length,
--  uschar **result, uschar **errmsg, BOOL *do_cache)
-+  uschar **result, uschar **errmsg, uint *do_cache)
- {
- return lf_sqlperform(US"PostgreSQL", US"pgsql_servers", pgsql_servers, query,
-   result, errmsg, do_cache, perform_pgsql_search);
-diff --git a/src/src/lookups/redis.c b/src/src/lookups/redis.c
-index ac4d0ec..18cd3a0 100644
---- a/src/src/lookups/redis.c
-+++ b/src/src/lookups/redis.c
-@@ -65,7 +65,7 @@ redis_tidy(void)
-  */
- static int
- perform_redis_search(uschar *command, uschar *server, uschar **resultptr,
--  uschar **errmsg, BOOL *defer_break, BOOL *do_cache)
-+  uschar **errmsg, BOOL *defer_break, uint *do_cache)
- {
-        redisContext *redis_handle = NULL;        /* Keep compilers happy */
-        redisReply *redis_reply = NULL;
-@@ -197,7 +197,7 @@ perform_redis_search(uschar *command, uschar *server, uschar **resultptr,
-        case REDIS_REPLY_ERROR:
-                *errmsg = string_sprintf("REDIS: lookup result failed: %s\n", redis_reply->str);
-                *defer_break = FALSE;
--               *do_cache = FALSE;
-+               *do_cache = 0;
-                goto REDIS_EXIT;
-                /* NOTREACHED */
-@@ -205,7 +205,7 @@ perform_redis_search(uschar *command, uschar *server, uschar **resultptr,
-        case REDIS_REPLY_NIL:
-                DEBUG(D_lookup) debug_printf("REDIS: query was not one that returned any data\n");
-                result = string_sprintf("");
--               *do_cache = FALSE;
-+               *do_cache = 0;
-                goto REDIS_EXIT;
-                /* NOTREACHED */
-@@ -304,7 +304,7 @@ perform_redis_search(uschar *command, uschar *server, uschar **resultptr,
- static int
- redis_find(void *handle __attribute__((unused)), uschar *filename __attribute__((unused)),
--           uschar *command, int length, uschar **result, uschar **errmsg, BOOL *do_cache)
-+           uschar *command, int length, uschar **result, uschar **errmsg, uint *do_cache)
- {
-        return lf_sqlperform(US"Redis", US"redis_servers", redis_servers, command,
-          result, errmsg, do_cache, perform_redis_search);
-diff --git a/src/src/lookups/spf.c b/src/src/lookups/spf.c
-index 23ad2ad..2671fc9 100644
---- a/src/src/lookups/spf.c
-+++ b/src/src/lookups/spf.c
-@@ -31,7 +31,9 @@ static void dummy(int x) { dummy2(x-1); }
- #include <spf2/spf_dns_resolv.h>
- #include <spf2/spf_dns_cache.h>
--static void *spf_open(uschar *filename, uschar **errmsg) {
-+static void *
-+spf_open(uschar *filename, uschar **errmsg)
-+{
-   SPF_server_t *spf_server = NULL;
-   spf_server = SPF_server_new(SPF_DNS_CACHE, 0);
-   if (spf_server == NULL) {
-@@ -41,13 +43,17 @@ static void *spf_open(uschar *filename, uschar **errmsg) {
-   return (void *) spf_server;
- }
--static void spf_close(void *handle) {
-+static void
-+spf_close(void *handle)
-+{
-   SPF_server_t *spf_server = handle;
-   if (spf_server) SPF_server_free(spf_server);
- }
--static int spf_find(void *handle, uschar *filename, uschar *keystring, int key_len,
--             uschar **result, uschar **errmsg, BOOL *do_cache) {
-+static int
-+spf_find(void *handle, uschar *filename, uschar *keystring, int key_len,
-+             uschar **result, uschar **errmsg, uint *do_cache)
-+{
-   SPF_server_t *spf_server = handle;
-   SPF_request_t *spf_request = NULL;
-   SPF_response_t *spf_response = NULL;
-diff --git a/src/src/lookups/sqlite.c b/src/src/lookups/sqlite.c
-index bb92c8c..e2330f9 100644
---- a/src/src/lookups/sqlite.c
-+++ b/src/src/lookups/sqlite.c
-@@ -81,7 +81,7 @@ return 0;
- static int
- sqlite_find(void *handle, uschar *filename, const uschar *query, int length,
--  uschar **result, uschar **errmsg, BOOL *do_cache)
-+  uschar **result, uschar **errmsg, uint *do_cache)
- {
- int ret;
- struct strbuf res = { NULL, 0, 0 };
-@@ -93,7 +93,7 @@ if (ret != SQLITE_OK)
-   return FAIL;
-   }
--if (res.string == NULL) *do_cache = FALSE;
-+if (res.string == NULL) *do_cache = 0;
- *result = res.string;
- return OK;
-diff --git a/src/src/lookups/testdb.c b/src/src/lookups/testdb.c
-index c82fa7f..401f7c8 100644
---- a/src/src/lookups/testdb.c
-+++ b/src/src/lookups/testdb.c
-@@ -38,7 +38,7 @@ return (void *)(1);    /* Just return something non-null */
- static int
- testdb_find(void *handle, uschar *filename, const uschar *query, int length,
--  uschar **result, uschar **errmsg, BOOL *do_cache)
-+  uschar **result, uschar **errmsg, uint *do_cache)
- {
- handle = handle;          /* Keep picky compilers happy */
- filename = filename;
-@@ -57,7 +57,7 @@ if (Ustrcmp(query, "defer") == 0)
-   return DEFER;
-   }
--if (Ustrcmp(query, "nocache") == 0) *do_cache = FALSE;
-+if (Ustrcmp(query, "nocache") == 0) *do_cache = 0;
- *result = string_copy(query);
- return OK;
-diff --git a/src/src/lookups/whoson.c b/src/src/lookups/whoson.c
-index 4166089..9ac5a3a 100644
---- a/src/src/lookups/whoson.c
-+++ b/src/src/lookups/whoson.c
-@@ -36,7 +36,7 @@ return (void *)(1);    /* Just return something non-null */
- static int
- whoson_find(void *handle, uschar *filename, uschar *query, int length,
--  uschar **result, uschar **errmsg, BOOL *do_cache)
-+  uschar **result, uschar **errmsg, uint *do_cache)
- {
- uschar buffer[80];
- handle = handle;          /* Keep picky compilers happy */
-diff --git a/src/src/search.c b/src/src/search.c
-index a055291..cd522da 100644
---- a/src/src/search.c
-+++ b/src/src/search.c
-@@ -466,6 +466,7 @@ internal_search_find(void *handle, uschar *filename, uschar *keystring)
- {
- tree_node *t = (tree_node *)handle;
- search_cache *c = (search_cache *)(t->data.ptr);
-+expiring_data *e;
- uschar *data = NULL;
- int search_type = t->name[0] - '0';
- int old_pool = store_pool;
-@@ -491,18 +492,27 @@ store_pool = POOL_SEARCH;
- /* Look up the data for the key, unless it is already in the cache for this
- file. No need to check c->item_cache for NULL, tree_search will do so. */
--if ((t = tree_search(c->item_cache, keystring)) == NULL)
-+if (  (t = tree_search(c->item_cache, keystring))
-+   && (!(e = t->data.ptr)->expiry || e->expiry > time(NULL))
-+   )
-+  { /* Data was in the cache already; set the pointer from the tree node */
-+  data = e->ptr;
-+  DEBUG(D_lookup) debug_printf("cached data used for lookup of %s%s%s\n",
-+    keystring,
-+    filename ? US"\n  in " : US"", filename ? filename : US"");
-+  }
-+else
-   {
--  BOOL do_cache = TRUE;
-+  uint do_cache = UINT_MAX;
-   int keylength = Ustrlen(keystring);
-   DEBUG(D_lookup)
-     {
--    if (filename != NULL)
--      debug_printf("file lookup required for %s\n  in %s\n",
--        keystring, filename);
--    else
--      debug_printf("database lookup required for %s\n", keystring);
-+    if (t) debug_printf("cached data found but past valid time; ");
-+    debug_printf("%s lookup required for %s%s%s\n",
-+      filename ? US"file" : US"database",
-+      keystring,
-+      filename ? US"\n  in " : US"", filename ? filename : US"");
-     }
-   /* Call the code for the different kinds of search. DEFER is handled
-@@ -511,9 +521,7 @@ if ((t = tree_search(c->item_cache, keystring)) == NULL)
-   if (lookup_list[search_type]->find(c->handle, filename, keystring, keylength,
-       &data, &search_error_message, &do_cache) == DEFER)
--    {
-     search_find_defer = TRUE;
--    }
-   /* A record that has been found is now in data, which is either NULL
-   or points to a bit of dynamic store. Cache the result of the lookup if
-@@ -524,10 +532,22 @@ if ((t = tree_search(c->item_cache, keystring)) == NULL)
-   else if (do_cache)
-     {
-     int len = keylength + 1;
--    t = store_get(sizeof(tree_node) + len);
--    memcpy(t->name, keystring, len);
--    t->data.ptr = data;
--    tree_insertnode(&c->item_cache, t);
-+
-+    if (t)    /* Previous, out-of-date cache entry.  Update with the */
-+      {       /* new result and forget the old one */
-+      e->expiry = do_cache == UINT_MAX ? 0 : time(NULL)+do_cache;
-+      e->ptr = data;
-+      }
-+    else
-+      {
-+      t = store_get(sizeof(tree_node) + len + sizeof(expiring_data));
-+      e = (expiring_data *)((char *)t + sizeof(tree_node) + len);
-+      e->expiry = do_cache == UINT_MAX ? 0 : time(NULL)+do_cache;
-+      e->ptr = data;
-+      memcpy(t->name, keystring, len);
-+      t->data.ptr = e;
-+      tree_insertnode(&c->item_cache, t);
-+      }
-     }
-   /* If caching was disabled, empty the cache tree. We just set the cache
-@@ -540,34 +560,19 @@ if ((t = tree_search(c->item_cache, keystring)) == NULL)
-     }
-   }
--/* Data was in the cache already; set the pointer from the tree node */
--
--else
--  {
--  data = US t->data.ptr;
--  DEBUG(D_lookup) debug_printf("cached data used for lookup of %s%s%s\n",
--    keystring,
--    (filename == NULL)? US"" : US"\n  in ",
--    (filename == NULL)? US"" : filename);
--  }
--
--/* Debug: output the answer */
--
- DEBUG(D_lookup)
-   {
--  if (data == NULL)
--    {
--    if (search_find_defer) debug_printf("lookup deferred: %s\n",
--      search_error_message);
--    else debug_printf("lookup failed\n");
--    }
--  else debug_printf("lookup yielded: %s\n", data);
-+  if (data)
-+    debug_printf("lookup yielded: %s\n", data);
-+  else if (search_find_defer)
-+    debug_printf("lookup deferred: %s\n", search_error_message);
-+  else debug_printf("lookup failed\n");
-   }
- /* Return it in new dynamic store in the regular pool */
- store_pool = old_pool;
--return (data == NULL)? NULL : string_copy(data);
-+return data ? string_copy(data) : NULL;
- }
-diff --git a/src/src/structs.h b/src/src/structs.h
-index 6f143d6..d9da38b 100644
---- a/src/src/structs.h
-+++ b/src/src/structs.h
-@@ -657,6 +657,16 @@ typedef struct tree_node {
-   uschar  name[1];                /* node name - variable length */
- } tree_node;
-+/* Structure for holding time-limited data such as DNS returns.
-+We use this rather than extending tree_node to avoid wasting
-+space for most tree use (variables...) at the cost of complexity
-+for the lookups cache */
-+
-+typedef struct expiring_data {
-+  time_t expiry;                /* if nonzero, data invalid after this time */
-+  void   *ptr;                          /* pointer to data */
-+} expiring_data;
-+
- /* Structure for holding the handle and the cached last lookup for searches.
- This block is pointed to by the tree entry for the file. The file can get
- closed if too many are opened at once. There is a LRU chain for deciding which
-@@ -676,6 +686,7 @@ uncompressed, but the data pointer is into the raw data. */
- typedef struct {
-   uschar  name[DNS_MAXNAME];      /* domain name */
-   int     type;                   /* record type */
-+  unsigned short ttl;           /* time-to-live, seconds */
-   int     size;                   /* size of data */
-   uschar *data;                   /* pointer to data */
- } dns_record;
-diff --git a/src/src/verify.c b/src/src/verify.c
-index e00e7b9..d392fda 100644
---- a/src/src/verify.c
-+++ b/src/src/verify.c
-@@ -21,6 +21,7 @@ uschar ctbuffer[8192];
- /* Structure for caching DNSBL lookups */
- typedef struct dnsbl_cache_block {
-+  time_t expiry;
-   dns_address *rhs;
-   uschar *text;
-   int rc;
-@@ -3584,21 +3585,37 @@ if (!string_format(query, sizeof(query), "%s.%s", prepend, domain))
- /* Look for this query in the cache. */
--t = tree_search(dnsbl_cache, query);
-+if (  (t = tree_search(dnsbl_cache, query))
-+   && (cb = t->data.ptr)->expiry > time(NULL)
-+   )
-+
-+/* Previous lookup was cached */
-+
-+  {
-+  HDEBUG(D_dnsbl) debug_printf("using result of previous DNS lookup\n");
-+  }
- /* If not cached from a previous lookup, we must do a DNS lookup, and
- cache the result in permanent memory. */
--if (t == NULL)
-+else
-   {
-+  uint ttl = 3600;
-+
-   store_pool = POOL_PERM;
--  /* Set up a tree entry to cache the lookup */
-+  if (t)
-+    {
-+    HDEBUG(D_dnsbl) debug_printf("cached data found but past valid time; ");
-+    }
--  t = store_get(sizeof(tree_node) + Ustrlen(query));
--  Ustrcpy(t->name, query);
--  t->data.ptr = cb = store_get(sizeof(dnsbl_cache_block));
--  (void)tree_insertnode(&dnsbl_cache, t);
-+  else
-+    { /* Set up a tree entry to cache the lookup */
-+    t = store_get(sizeof(tree_node) + Ustrlen(query));
-+    Ustrcpy(t->name, query);
-+    t->data.ptr = cb = store_get(sizeof(dnsbl_cache_block));
-+    (void)tree_insertnode(&dnsbl_cache, t);
-+    }
-   /* Do the DNS loopup . */
-@@ -3616,7 +3633,10 @@ if (t == NULL)
-   Quite apart from one A6 RR generating multiple addresses, there are DNS
-   lists that return more than one A record, so we must handle multiple
--  addresses generated in that way as well. */
-+  addresses generated in that way as well.
-+
-+  Mark the cache entry with the "now" plus the minimum of the address TTLs,
-+  or some suitably far-future time if none were found. */
-   if (cb->rc == DNS_SUCCEED)
-     {
-@@ -3634,6 +3654,7 @@ if (t == NULL)
-           *addrp = da;
-           while (da->next != NULL) da = da->next;
-           addrp = &(da->next);
-+        if (ttl > rr->ttl) ttl = rr->ttl;
-           }
-         }
-       }
-@@ -3645,17 +3666,10 @@ if (t == NULL)
-     if (cb->rhs == NULL) cb->rc = DNS_NODATA;
-     }
-+  cb->expiry = time(NULL)+ttl;
-   store_pool = old_pool;
-   }
--/* Previous lookup was cached */
--
--else
--  {
--  HDEBUG(D_dnsbl) debug_printf("using result of previous DNS lookup\n");
--  cb = t->data.ptr;
--  }
--
- /* We now have the result of the DNS lookup, either newly done, or cached
- from a previous call. If the lookup succeeded, check against the address
- list if there is one. This may be a positive equality list (introduced by
-
-commit c4dcf906ceb3a45c6b30f76476d73ca836b262cd
-Author: Jeremy Harris <jgh146exb@wizmail.org>
-Date:   Sat Sep 19 13:59:22 2015 +0100
-
-    Retry: always use interface, if set, for retry DB key.  Bug 1678
-    
-    Even constant values must be used, as multiple transports with
-    different values may be in play and should be kept distinct.
-    
-    (cherry picked from commit 6f6dedccb47f231a0712d882da20feffbac8d0bc)
-
-diff --git a/src/src/functions.h b/src/src/functions.h
-index 0257904..94e3f5f 100644
---- a/src/src/functions.h
-+++ b/src/src/functions.h
-@@ -374,7 +374,7 @@ extern int     smtp_sock_connect(host_item *, int, int, uschar *,
- extern int     smtp_feof(void);
- extern int     smtp_ferror(void);
- extern uschar *smtp_get_connection_info(void);
--extern BOOL    smtp_get_interface(uschar *, int, address_item *, BOOL *,
-+extern BOOL    smtp_get_interface(uschar *, int, address_item *,
-                  uschar **, uschar *);
- extern BOOL    smtp_get_port(uschar *, address_item *, int *, uschar *);
- extern int     smtp_getc(void);
-diff --git a/src/src/smtp_out.c b/src/src/smtp_out.c
-index c704a0b..2fdf38b 100644
---- a/src/src/smtp_out.c
-+++ b/src/src/smtp_out.c
-@@ -26,7 +26,6 @@ Arguments:
-                which case the function does nothing
-   host_af    AF_INET or AF_INET6 for the outgoing IP address
-   addr       the mail address being handled (for setting errors)
--  changed    if not NULL, set TRUE if expansion actually changed istring
-   interface  point this to the interface
-   msg        to add to any error message
-@@ -36,7 +35,7 @@ Returns:     TRUE on success, FALSE on failure, with error message
- BOOL
- smtp_get_interface(uschar *istring, int host_af, address_item *addr,
--  BOOL *changed, uschar **interface, uschar *msg)
-+  uschar **interface, uschar *msg)
- {
- const uschar * expint;
- uschar *iface;
-@@ -54,8 +53,6 @@ if (expint == NULL)
-   return FALSE;
-   }
--if (changed != NULL) *changed = expint != istring;
--
- while (isspace(*expint)) expint++;
- if (*expint == 0) return TRUE;
-diff --git a/src/src/transports/smtp.c b/src/src/transports/smtp.c
-index 5ac5533..ba7fb5e 100644
---- a/src/src/transports/smtp.c
-+++ b/src/src/transports/smtp.c
-@@ -3174,7 +3174,6 @@ for (cutoff_retry = 0; expired &&
-     BOOL serialized = FALSE;
-     BOOL host_is_expired = FALSE;
-     BOOL message_defer = FALSE;
--    BOOL ifchanges = FALSE;
-     BOOL some_deferred = FALSE;
-     address_item *first_addr = NULL;
-     uschar *interface = NULL;
-@@ -3350,15 +3349,18 @@ for (cutoff_retry = 0; expired &&
-     if (Ustrcmp(pistring, ":25") == 0) pistring = US"";
-     /* Select IPv4 or IPv6, and choose an outgoing interface. If the interface
--    string changes upon expansion, we must add it to the key that is used for
--    retries, because connections to the same host from a different interface
--    should be treated separately. */
-+    string is set, even if constant (as different transports can have different
-+    constant settings), we must add it to the key that is used for retries,
-+    because connections to the same host from a different interface should be
-+    treated separately. */
-     host_af = (Ustrchr(host->address, ':') == NULL)? AF_INET : AF_INET6;
--    if (!smtp_get_interface(ob->interface, host_af, addrlist, &ifchanges,
--         &interface, tid))
--      return FALSE;
--    if (ifchanges) pistring = string_sprintf("%s/%s", pistring, interface);
-+    if ((rs = ob->interface) && *rs)
-+      {
-+      if (!smtp_get_interface(rs, host_af, addrlist, &interface, tid))
-+      return FALSE;
-+      pistring = string_sprintf("%s/%s", pistring, interface);
-+      }
-     /* The first time round the outer loop, check the status of the host by
-     inspecting the retry data. The second time round, we are interested only
-diff --git a/src/src/verify.c b/src/src/verify.c
-index d392fda..6411c7e 100644
---- a/src/src/verify.c
-+++ b/src/src/verify.c
-@@ -444,7 +444,7 @@ can do it there for the non-rcpt-verify case.  For this we keep an addresscount.
-         host_af = (Ustrchr(host->address, ':') == NULL)? AF_INET:AF_INET6;
--        if (!smtp_get_interface(tf->interface, host_af, addr, NULL, &interface,
-+        if (!smtp_get_interface(tf->interface, host_af, addr, &interface,
-                 US"callout") ||
-             !smtp_get_port(tf->port, addr, &port, US"callout"))
-           log_write(0, LOG_MAIN|LOG_PANIC, "<%s>: %s", addr->address,
-@@ -579,7 +579,7 @@ can do it there for the non-rcpt-verify case.  For this we keep an addresscount.
-     deliver_domain = addr->domain;
-     transport_name = addr->transport->name;
--    if (  !smtp_get_interface(tf->interface, host_af, addr, NULL, &interface,
-+    if (  !smtp_get_interface(tf->interface, host_af, addr, &interface,
-             US"callout")
-        || !smtp_get_port(tf->port, addr, &port, US"callout")
-        )
-
-commit 1bd52978055bc07dfa150d296ffb344f10fff7fe
-Author: Jeremy Harris <jgh146exb@wizmail.org>
-Date:   Mon Nov 2 19:03:26 2015 +0000
-
-    Avoid misaligned access in cached lookup.  Bug 1708
-    
-    (cherry picked from commit 98b98887f926be87eabccc7919e57ce625c63c03)
-
-diff --git a/src/src/search.c b/src/src/search.c
-index cd522da..ccad250 100644
---- a/src/src/search.c
-+++ b/src/src/search.c
-@@ -540,10 +540,10 @@ else
-       }
-     else
-       {
--      t = store_get(sizeof(tree_node) + len + sizeof(expiring_data));
--      e = (expiring_data *)((char *)t + sizeof(tree_node) + len);
-+      e = store_get(sizeof(expiring_data) + sizeof(tree_node) + len);
-       e->expiry = do_cache == UINT_MAX ? 0 : time(NULL)+do_cache;
-       e->ptr = data;
-+      t = (tree_node *)(e+1);
-       memcpy(t->name, keystring, len);
-       t->data.ptr = e;
-       tree_insertnode(&c->item_cache, t);
-
-commit e7c3de301824738c6f302e02e566f9da75d3130c
-Author: Jeremy Harris <jgh146exb@wizmail.org>
-Date:   Thu Oct 15 21:40:17 2015 +0100
-
-    DKIM: ignore space & tab embedded in base64 during decode.  Bug 1700
-    
-    (cherry picked from commit 0f557e9065b0bcfce38ee1fea5fc947bf0c5431c)
-
-diff --git a/src/src/pdkim/base64.c b/src/src/pdkim/base64.c
-index a82fc2d..1395be4 100644
---- a/src/src/pdkim/base64.c
-+++ b/src/src/pdkim/base64.c
-@@ -128,20 +128,22 @@ int base64_decode( unsigned char *dst, int *dlen,
-     for( i = j = n = 0; i < slen; i++ )
-     {
-+      unsigned char c = src[i];
-+
-         if( ( slen - i ) >= 2 &&
--            src[i] == '\r' && src[i + 1] == '\n' )
-+            c == '\r' && src[i + 1] == '\n' )
-             continue;
--        if( src[i] == '\n' )
-+        if( c == '\n' || c == ' ' || c == '\t' )
-             continue;
--        if( src[i] == '=' && ++j > 2 )
-+        if( c == '=' && ++j > 2 )
-             return( POLARSSL_ERR_BASE64_INVALID_CHARACTER );
--        if( src[i] > 127 || base64_dec_map[src[i]] == 127 )
-+        if( c > 127 || base64_dec_map[src[i]] == 127 )
-             return( POLARSSL_ERR_BASE64_INVALID_CHARACTER );
--        if( base64_dec_map[src[i]] < 64 && j != 0 )
-+        if( base64_dec_map[c] < 64 && j != 0 )
-             return( POLARSSL_ERR_BASE64_INVALID_CHARACTER );
-         n++;
-@@ -160,11 +162,13 @@ int base64_decode( unsigned char *dst, int *dlen,
-    for( j = 3, n = x = 0, p = dst; i > 0; i--, src++ )
-    {
--        if( *src == '\r' || *src == '\n' )
-+      unsigned char c = *src;
-+
-+        if( c == '\r' || c == '\n' || c == ' ' || c == '\t' )
-             continue;
--        j -= ( base64_dec_map[*src] == 64 );
--        x  = (x << 6) | ( base64_dec_map[*src] & 0x3F );
-+        j -= ( base64_dec_map[c] == 64 );
-+        x  = (x << 6) | ( base64_dec_map[c] & 0x3F );
-         if( ++n == 4 )
-         {
-
-commit a23a9d099ac9d112a6d961e00539bcf1bbb1ef7e
-Author: Jeremy Harris <jgh146exb@wizmail.org>
-Date:   Wed Nov 25 17:49:03 2015 +0000
-
-    MIME: fix crash on filenames having null charset.  Bug 1730
-    
-    (cherry picked from commit 622dbd6a512d2c7786125e3b80e96a43e54b8e90)
-
-diff --git a/src/src/mime.c b/src/src/mime.c
-index 618364a..cc9ffb7 100644
---- a/src/src/mime.c
-+++ b/src/src/mime.c
-@@ -550,7 +550,8 @@ int size = 0, ptr = 0;
- uschar * val = string_cat(NULL, &size, &ptr, US"=?", 2);
- uschar c;
--val = string_cat(val, &size, &ptr, charset, Ustrlen(charset));
-+if (charset)
-+  val = string_cat(val, &size, &ptr, charset, Ustrlen(charset));
- val = string_cat(val, &size, &ptr, US"?Q?", 3);
- while ((c = *fname))
-@@ -607,7 +608,7 @@ while(1)
-     if (!fgets(CS header, MIME_MAX_HEADER_SIZE, f))
-       {
-       /* Hit EOF or read error. Ugh. */
--      DEBUG(D_acl) debug_printf("Hit EOF ...\n");
-+      DEBUG(D_acl) debug_printf("MIME: Hit EOF ...\n");
-       return rc;
-       }
-@@ -619,12 +620,12 @@ while(1)
-       if (Ustrncmp((header+2+Ustrlen(context->boundary)), "--", 2) == 0)
-       {
-       /* END boundary found */
--      DEBUG(D_acl) debug_printf("End boundary found %s\n",
-+      DEBUG(D_acl) debug_printf("MIME: End boundary found %s\n",
-         context->boundary);
-       return rc;
-       }
--      DEBUG(D_acl) debug_printf("Next part with boundary %s\n",
-+      DEBUG(D_acl) debug_printf("MIME: Next part with boundary %s\n",
-       context->boundary);
-       break;
-       }
-@@ -648,7 +649,7 @@ while(1)
-       for (q = p; *q != ';' && *q; q++) ;
-       *mh->value = string_copynlc(p, q-p);
--      DEBUG(D_acl) debug_printf("found %s MIME header, value is '%s'\n",
-+      DEBUG(D_acl) debug_printf("MIME: found %s header, value is '%s'\n",
-       mh->name, *mh->value);
-       if (*(p = q)) p++;                      /* jump past the ; */
-@@ -666,7 +667,7 @@ while(1)
-         {
-         mime_parameter * mp;
--        DEBUG(D_acl) debug_printf("  considering paramlist '%s'\n", p);
-+        DEBUG(D_acl) debug_printf("MIME:   considering paramlist '%s'\n", p);
-         if (  !mime_filename
-            && strncmpic(CUS"content-disposition:", header, 20) == 0
-@@ -700,22 +701,27 @@ while(1)
-                 uschar * s = q;
-                 /* look for a ' in the "filename" */
--                while(*s != '\'' && *s) s++;  /* s is ' or NUL */
-+                while(*s != '\'' && *s) s++;  /* s is 1st ' or NUL */
-                 if ((size = s-q) > 0)
--                  {
-                   mime_filename_charset = string_copyn(q, size);
--                  p = s;
--                  while(*p == '\'' && *p) p++; /* p is after ' */
--                  }
-+                if (*(p = s)) p++;
-+                while(*p == '\'') p++;        /* p is after 2nd ' */
-                 }
-               else
-                 p = q;
-+              DEBUG(D_acl) debug_printf("MIME:    charset %s fname '%s'\n",
-+                mime_filename_charset ? mime_filename_charset : US"<NULL>", p);
-+
-               temp_string = rfc2231_to_2047(p, mime_filename_charset, &slen);
--              temp_string = rfc2047_decode(temp_string, FALSE, NULL, 32,
-+              DEBUG(D_acl) debug_printf("MIME:    2047-name %s\n", temp_string);
-+
-+              temp_string = rfc2047_decode(temp_string, FALSE, NULL, ' ',
-                 NULL, &err_msg);
-+              DEBUG(D_acl) debug_printf("MIME:    plain-name %s\n", temp_string);
-+
-               size = Ustrlen(temp_string);
-               if (size == slen)
-@@ -750,7 +756,7 @@ while(1)
-                   &dummy_errstr)
-               : NULL;
-             DEBUG(D_acl) debug_printf(
--              " found %s MIME parameter in %s header, value '%s'\n",
-+              "MIME:  found %s parameter in %s header, value '%s'\n",
-               mp->name, mh->name, *mp->value);
-             break;                    /* done matching param names */
-@@ -768,7 +774,7 @@ while(1)
-         if (decoding_failed) mime_filename = mime_fname_rfc2231;
-         DEBUG(D_acl) debug_printf(
--          " found %s MIME parameter in %s header, value is '%s'\n",
-+          "MIME:  found %s parameter in %s header, value is '%s'\n",
-           "filename", mh->name, mime_filename);
-         }
-       }
-@@ -809,8 +815,9 @@ while(1)
-        (nested_context.boundary != NULL) &&
-        (Ustrncmp(mime_content_type,"multipart",9) == 0) )
-     {
--    DEBUG(D_acl) debug_printf("Entering multipart recursion, boundary '%s'\n",
--      nested_context.boundary);
-+    DEBUG(D_acl)
-+      debug_printf("MIME: Entering multipart recursion, boundary '%s'\n",
-+      nested_context.boundary);
-     nested_context.context =
-       context && context->context == MBC_ATTACHMENT
-
-commit 8d58e3501ce731c5d6d5efc9e76058832d4bc941
-Author: Jeremy Harris <jgh146exb@wizmail.org>
-Date:   Thu Jan 21 15:37:08 2016 +0000
-
-    Cutthrough: Fix bug with dot-only line
-    
-    (cherry picked from commit 1bc460a64a0de0766d21f4f8660c6597bc410cbc)
-
-diff --git a/src/src/receive.c b/src/src/receive.c
-index 64cf1ae..d1f81d3 100644
---- a/src/src/receive.c
-+++ b/src/src/receive.c
-@@ -835,7 +835,15 @@ while ((ch = (receive_getc)()) != EOF)
-       ch_state = 4;
-       continue;
-       }
--    ch_state = 1;                       /* The dot itself is removed */
-+    /* The dot was removed at state 3. For a doubled dot, here, reinstate
-+    it to cutthrough. The current ch, dot or not, is passed both to cutthrough
-+    and to file below. */
-+    if (ch == '.')
-+      {
-+      uschar c= ch;
-+      (void) cutthrough_puts(&c, 1);
-+      }
-+    ch_state = 1;
-     break;
-     case 4:                             /* After [CR] LF . CR */
diff --git a/exim-memleak.patch b/exim-memleak.patch
deleted file mode 100644 (file)
index 8fd83ec..0000000
+++ /dev/null
@@ -1,43 +0,0 @@
-commit 65e061b76867a9ea7aeeb535341b790b90ae6c21
-Author: Heiko Schlittermann (HS12-RIPE) <hs@schlittermann.de>
-Date:   Wed May 31 23:08:56 2017 +0200
-
-    Cleanup (prevent repeated use of -p/-oMr to avoid mem leak)
-
-diff --git a/src/src/exim.c b/src/src/exim.c
-index 67583e58..88e11977 100644
---- a/src/src/exim.c
-+++ b/src/src/exim.c
-@@ -3106,7 +3106,14 @@ for (i = 1; i < argc; i++)
-       /* -oMr: Received protocol */
--      else if (Ustrcmp(argrest, "Mr") == 0) received_protocol = argv[++i];
-+      else if (Ustrcmp(argrest, "Mr") == 0)
-+
-+        if (received_protocol)
-+          {
-+          fprintf(stderr, "received_protocol is set already\n");
-+          exit(EXIT_FAILURE);
-+          }
-+        else received_protocol = argv[++i];
-       /* -oMs: Set sender host name */
-@@ -3202,7 +3209,15 @@ for (i = 1; i < argc; i++)
-     if (*argrest != 0)
-       {
--      uschar *hn = Ustrchr(argrest, ':');
-+      uschar *hn;
-+
-+      if (received_protocol)
-+        {
-+        fprintf(stderr, "received_protocol is set already\n");
-+        exit(EXIT_FAILURE);
-+        }
-+
-+      hn = Ustrchr(argrest, ':');
-       if (hn == NULL)
-         {
-         received_protocol = argrest;
index 4d771ef..d079188 100644 (file)
--- a/exim.spec
+++ b/exim.spec
@@ -24,7 +24,7 @@ Summary(pl.UTF-8):    Agent Transferu Poczty Uniwersytetu w Cambridge
 Summary(pt_BR.UTF-8):  Servidor de correio eletrônico exim
 Name:          exim
 Version:       4.89
-Release:       5
+Release:       6
 Epoch:         2
 License:       GPL
 Group:         Networking/Daemons/SMTP
@@ -50,6 +50,7 @@ Source15:     %{name}4-smtp.pamd
 Source16:      %{name}on.png
 # git log -p exim-4_87..exim-4_87+fixes --reverse -- . ":(exclude)doc/doc-*" ":(exclude)test" ":(exclude).*" > exim-git.patch
 Patch100:      %{name}-git.patch
+# Patch100-md5:        a57cd93f4d57b26258aab2670668497e
 Patch0:                %{name}4-EDITME.patch
 Patch1:                %{name}4-monitor-EDITME.patch
 Patch2:                %{name}4-cflags.patch
@@ -58,7 +59,7 @@ Patch4:               %{name}4-Makefile-Default.patch
 # http://marc.merlins.org/linux/exim/files/sa-exim-cvs/localscan_dlopen_exim_4.20_or_better.patch
 Patch5:                localscan_dlopen_%{name}_4.20_or_better.patch
 Patch6:                exim-commandline_checks_require_admin.patch
-Patch7:                exim-memleak.patch
+
 Patch8:                %{name}-spam-timeout.patch
 
 Patch10:       %{name}-force-sigalrm.patch
@@ -176,7 +177,7 @@ Pliki nagłówkowe dla Exima.
 
 %prep
 %setup -q -a1 -a7
-#%patch100 -p2
+%patch100 -p2
 
 %patch0 -p1
 %patch1 -p1
@@ -185,7 +186,7 @@ Pliki nagłówkowe dla Exima.
 %patch4 -p1
 %patch5 -p1
 %patch6 -p2
-%patch7 -p2
+
 %patch8 -p1
 
 %patch10 -p1
This page took 0.152136 seconds and 4 git commands to generate.