[exim-cvs] constification

Páxina inicial
Borrar esta mensaxe
Responder a esta mensaxe
Autor: Exim Git Commits Mailing List
Data:  
Para: exim-cvs
Asunto: [exim-cvs] constification
Gitweb: http://git.exim.org/exim.git/commitdiff/55414b25bee9f0195ccd1e47f3d3b5cba766e099
Commit:     55414b25bee9f0195ccd1e47f3d3b5cba766e099
Parent:     2ad7897851d62bc690844f416d4ca2fabedf9459
Author:     Jeremy Harris <jgh146exb@???>
AuthorDate: Sat Jan 31 22:33:53 2015 +0000
Committer:  Jeremy Harris <jgh146exb@???>
CommitDate: Sun Feb 1 23:29:03 2015 +0000


    constification
---
 src/src/acl.c                           |  591 ++++++++++++++++---------------
 src/src/auths/plaintext.c               |    6 +-
 src/src/child.c                         |   13 +-
 src/src/daemon.c                        |    9 +-
 src/src/dbfn.c                          |   30 ++-
 src/src/dbfunctions.h                   |    6 +-
 src/src/dcc.c                           |    6 +-
 src/src/debug.c                         |    2 +-
 src/src/deliver.c                       |   39 ++-
 src/src/dkim.c                          |   15 +-
 src/src/dkim.h                          |    2 +-
 src/src/dns.c                           |   18 +-
 src/src/exim.c                          |    6 +-
 src/src/exim_dbmbuild.c                 |    6 +-
 src/src/exim_dbutil.c                   |   30 ++-
 src/src/expand.c                        |  127 ++++---
 src/src/filter.c                        |    8 +-
 src/src/functions.h                     |  120 ++++---
 src/src/globals.c                       |   52 ++--
 src/src/globals.h                       |   18 +-
 src/src/host.c                          |   76 ++--
 src/src/ip.c                            |    2 +-
 src/src/log.c                           |    9 +-
 src/src/lookupapi.h                     |    2 +-
 src/src/lookups/cdb.c                   |    2 +-
 src/src/lookups/dbmdb.c                 |    8 +-
 src/src/lookups/dnsdb.c                 |   10 +-
 src/src/lookups/dsearch.c               |    2 +-
 src/src/lookups/ldap.c                  |   26 +-
 src/src/lookups/ldap.h                  |    2 +-
 src/src/lookups/lf_functions.h          |    5 +-
 src/src/lookups/lf_sqlperform.c         |   13 +-
 src/src/lookups/lsearch.c               |   14 +-
 src/src/lookups/mysql.c                 |    4 +-
 src/src/lookups/passwd.c                |    2 +-
 src/src/lookups/pgsql.c                 |    4 +-
 src/src/lookups/sqlite.c                |    2 +-
 src/src/lookups/testdb.c                |    2 +-
 src/src/lss.c                           |    8 +-
 src/src/macros.h                        |    7 +
 src/src/malware.c                       |    5 +-
 src/src/match.c                         |   51 ++--
 src/src/mime.c                          |    6 +-
 src/src/moan.c                          |    6 +-
 src/src/mytypes.h                       |    1 +
 src/src/parse.c                         |   17 +-
 src/src/queue.c                         |    3 +-
 src/src/rda.c                           |    2 +-
 src/src/readconf.c                      |   50 ++--
 src/src/receive.c                       |   23 +-
 src/src/regex.c                         |   14 +-
 src/src/retry.c                         |   43 +--
 src/src/rewrite.c                       |   15 +-
 src/src/route.c                         |   42 ++--
 src/src/routers/dnslookup.c             |   13 +-
 src/src/routers/ipliteral.c             |   19 +-
 src/src/routers/iplookup.c              |    3 +-
 src/src/routers/manualroute.c           |   34 +-
 src/src/routers/queryprogram.c          |    2 +-
 src/src/routers/redirect.c              |    2 +-
 src/src/routers/rf_change_domain.c      |    2 +-
 src/src/routers/rf_functions.h          |    2 +-
 src/src/routers/rf_get_errors_address.c |    4 +-
 src/src/routers/rf_get_munge_headers.c  |    4 +-
 src/src/routers/rf_lookup_hostlist.c    |    2 +-
 src/src/search.c                        |    8 +-
 src/src/sieve.c                         |    7 +-
 src/src/smtp_in.c                       |    8 +-
 src/src/smtp_out.c                      |    2 +-
 src/src/spam.c                          |    8 +-
 src/src/string.c                        |   26 +-
 src/src/structs.h                       |   16 +-
 src/src/tls-gnu.c                       |    4 +-
 src/src/tls-openssl.c                   |    6 +-
 src/src/tls.c                           |   10 +-
 src/src/tlscert-gnu.c                   |    2 +-
 src/src/transport.c                     |   44 ++--
 src/src/transports/appendfile.c         |    2 +-
 src/src/transports/autoreply.c          |    9 +-
 src/src/transports/lmtp.c               |   69 ++--
 src/src/transports/pipe.c               |   40 +--
 src/src/transports/smtp.c               |   31 +-
 src/src/tree.c                          |    2 +-
 src/src/verify.c                        |   44 ++--
 test/stderr/0432                        |    6 -
 85 files changed, 1042 insertions(+), 971 deletions(-)


diff --git a/src/src/acl.c b/src/src/acl.c
index f0716e0..0f1d497 100644
--- a/src/src/acl.c
+++ b/src/src/acl.c
@@ -802,7 +802,7 @@ static uschar *ratelimit_option_string[] = {

/* Enable recursion between acl_check_internal() and acl_check_condition() */

-static int acl_check_wargs(int, address_item *, uschar *, int, uschar **,
+static int acl_check_wargs(int, address_item *, const uschar *, int, uschar **,
     uschar **);



@@ -1049,9 +1049,9 @@ Returns:    nothing
 */


static void
-setup_header(uschar *hstring)
+setup_header(const uschar *hstring)
{
-uschar *p, *q;
+const uschar *p, *q;
int hlen = Ustrlen(hstring);

/* Ignore any leading newlines */
@@ -1059,14 +1059,24 @@ while (*hstring == '\n') hstring++, hlen--;

 /* An empty string does nothing; ensure exactly one final newline. */
 if (hlen <= 0) return;
-if (hstring[--hlen] != '\n') hstring = string_sprintf("%s\n", hstring);
-else while(hstring[--hlen] == '\n') hstring[hlen+1] = '\0';
+if (hstring[--hlen] != '\n')
+  q = string_sprintf("%s\n", hstring);
+else if (hstring[hlen-1] == '\n')
+  {
+  uschar * s = string_copy(hstring);
+  while(s[--hlen] == '\n')
+    s[hlen+1] = '\0';
+  q = s;
+  }
+else
+  q = hstring;


/* Loop for multiple header lines, taking care about continuations */

-for (p = q = hstring; *p != 0; )
+for (p = q; *p != 0; )
{
- uschar *s;
+ const uschar *s;
+ uschar * hdr;
int newtype = htype_add_bot;
header_line **hptr = &acl_added_headers;

@@ -1114,14 +1124,14 @@ for (p = q = hstring; *p != 0; )
     if (*s == ':' || !isgraph(*s)) break;
     }


- s = string_sprintf("%s%.*s", (*s == ':')? "" : "X-ACL-Warn: ", (int) (q - p), p);
- hlen = Ustrlen(s);
+ hdr = string_sprintf("%s%.*s", (*s == ':')? "" : "X-ACL-Warn: ", (int) (q - p), p);
+ hlen = Ustrlen(hdr);

/* See if this line has already been added */

   while (*hptr != NULL)
     {
-    if (Ustrncmp((*hptr)->text, s, hlen) == 0) break;
+    if (Ustrncmp((*hptr)->text, hdr, hlen) == 0) break;
     hptr = &((*hptr)->next);
     }


@@ -1130,7 +1140,7 @@ for (p = q = hstring; *p != 0; )
   if (*hptr == NULL)
     {
     header_line *h = store_get(sizeof(header_line));
-    h->text = s;
+    h->text = hdr;
     h->next = NULL;
     h->type = newtype;
     h->slen = hlen;
@@ -1197,15 +1207,12 @@ Returns:    nothing
 */


 static void
-setup_remove_header(uschar *hnames)
+setup_remove_header(const uschar *hnames)
 {
 if (*hnames != 0)
-  {
-  if (acl_removed_headers == NULL)
-    acl_removed_headers = hnames;
-  else
-    acl_removed_headers = string_sprintf("%s : %s", acl_removed_headers, hnames);
-  }
+  acl_removed_headers = acl_removed_headers
+    ? string_sprintf("%s : %s", acl_removed_headers, hnames)
+    : string_copy(hnames);
 }



@@ -1444,10 +1451,11 @@ Returns:    CSA_UNKNOWN    no valid CSA record found
 */


static int
-acl_verify_csa(uschar *domain)
+acl_verify_csa(const uschar *domain)
{
tree_node *t;
-uschar *found, *p;
+const uschar *found;
+uschar *p;
int priority, weight, port;
dns_answer dnsa;
dns_scan dnss;
@@ -1470,7 +1478,7 @@ containing a keyword and a colon before the actual IP address. */

 if (domain[0] == '[')
   {
-  uschar *start = Ustrchr(domain, ':');
+  const uschar *start = Ustrchr(domain, ':');
   if (start == NULL) start = domain;
   domain = string_copyn(start + 1, Ustrlen(start) - 2);
   }
@@ -1726,7 +1734,7 @@ Returns:       OK        verification condition succeeded
 */


static int
-acl_verify(int where, address_item *addr, uschar *arg,
+acl_verify(int where, address_item *addr, const uschar *arg,
uschar **user_msgptr, uschar **log_msgptr, int *basic_errno)
{
int sep = '/';
@@ -1750,7 +1758,7 @@ an error if options are given for items that don't expect them.
*/

uschar *slash = Ustrchr(arg, '/');
-uschar *list = arg;
+const uschar *list = arg;
uschar *ss = string_nextinlist(&list, &sep, big_buffer, big_buffer_size);
verify_type_t * vp;

@@ -1915,12 +1923,13 @@ while ((ss = string_nextinlist(&list, &sep, big_buffer, big_buffer_size))
       while (isspace(*ss)) ss++;
       if (*ss++ == '=')
         {
+    const uschar * sublist = ss;
         int optsep = ',';
         uschar *opt;
         uschar buffer[256];
-        while (isspace(*ss)) ss++;
+        while (isspace(*sublist)) sublist++;


-        while ((opt = string_nextinlist(&ss, &optsep, buffer, sizeof(buffer)))
+        while ((opt = string_nextinlist(&sublist, &optsep, buffer, sizeof(buffer)))
               != NULL)
           {
       callout_opt_t * op;
@@ -2243,7 +2252,7 @@ Returns:      CONTROL_xxx value
 */


 static int
-decode_control(uschar *arg, uschar **pptr, int where, uschar **log_msgptr)
+decode_control(const uschar *arg, const uschar **pptr, int where, uschar **log_msgptr)
 {
 int len;
 control_def *d;
@@ -2328,7 +2337,7 @@ Returns:       OK        - Sender's rate is above limit
 */


 static int
-acl_ratelimit(uschar *arg, int where, uschar **log_msgptr)
+acl_ratelimit(const uschar *arg, int where, uschar **log_msgptr)
 {
 double limit, period, count;
 uschar *ss;
@@ -2857,7 +2866,7 @@ Returns:       OK        - Completed.
 */


static int
-acl_udpsend(uschar *arg, uschar **log_msgptr)
+acl_udpsend(const uschar *arg, uschar **log_msgptr)
{
int sep = 0;
uschar *hostname;
@@ -2983,7 +2992,6 @@ uschar *user_message = NULL;
uschar *log_message = NULL;
uschar *debug_tag = NULL;
uschar *debug_opts = NULL;
-uschar *p = NULL;
int rc = OK;
#ifdef WITH_CONTENT_SCAN
int sep = -'/';
@@ -2991,7 +2999,7 @@ int sep = -'/';

for (; cb != NULL; cb = cb->next)
{
- uschar *arg;
+ const uschar *arg;
int control_type;

   /* The message and log_message items set up messages to be used in
@@ -3130,268 +3138,272 @@ for (; cb != NULL; cb = cb->next)
     break;


     case ACLC_CONTROL:
-    control_type = decode_control(arg, &p, where, log_msgptr);
-
-    /* Check if this control makes sense at this time */
-
-    if ((control_forbids[control_type] & (1 << where)) != 0)
       {
-      *log_msgptr = string_sprintf("cannot use \"control=%s\" in %s ACL",
-        controls[control_type], acl_wherenames[where]);
-      return ERROR;
-      }
-
-    switch(control_type)
-      {
-      case CONTROL_AUTH_UNADVERTISED:
-      allow_auth_unadvertised = TRUE;
-      break;
-
-      #ifdef EXPERIMENTAL_BRIGHTMAIL
-      case CONTROL_BMI_RUN:
-      bmi_run = 1;
-      break;
-      #endif
-
-      #ifndef DISABLE_DKIM
-      case CONTROL_DKIM_VERIFY:
-      dkim_disable_verify = TRUE;
-      #ifdef EXPERIMENTAL_DMARC
-      /* Since DKIM was blocked, skip DMARC too */
-      dmarc_disable_verify = TRUE;
-      dmarc_enable_forensic = FALSE;
-      #endif
-      break;
-      #endif
-
-      #ifdef EXPERIMENTAL_DMARC
-      case CONTROL_DMARC_VERIFY:
-      dmarc_disable_verify = TRUE;
-      break;
+      const uschar *p = NULL;
+      control_type = decode_control(arg, &p, where, log_msgptr);


-      case CONTROL_DMARC_FORENSIC:
-      dmarc_enable_forensic = TRUE;
-      break;
-      #endif
+      /* Check if this control makes sense at this time */


-      case CONTROL_DSCP:
-      if (*p == '/')
-        {
-        int fd, af, level, optname, value;
-        /* If we are acting on stdin, the setsockopt may fail if stdin is not
-        a socket; we can accept that, we'll just debug-log failures anyway. */
-        fd = fileno(smtp_in);
-        af = ip_get_address_family(fd);
-        if (af < 0)
-          {
-          HDEBUG(D_acl)
-            debug_printf("smtp input is probably not a socket [%s], not setting DSCP\n",
-                strerror(errno));
-          break;
-          }
-        if (dscp_lookup(p+1, af, &level, &optname, &value))
-          {
-          if (setsockopt(fd, level, optname, &value, sizeof(value)) < 0)
-            {
-            HDEBUG(D_acl) debug_printf("failed to set input DSCP[%s]: %s\n",
-                p+1, strerror(errno));
-            }
-          else
-            {
-            HDEBUG(D_acl) debug_printf("set input DSCP to \"%s\"\n", p+1);
-            }
-          }
-        else
-          {
-          *log_msgptr = string_sprintf("unrecognised DSCP value in \"control=%s\"", arg);
-          return ERROR;
-          }
-        }
-      else
-        {
-        *log_msgptr = string_sprintf("syntax error in \"control=%s\"", arg);
-        return ERROR;
-        }
-      break;
-
-      case CONTROL_ERROR:
-      return ERROR;
-
-      case CONTROL_CASEFUL_LOCAL_PART:
-      deliver_localpart = addr->cc_local_part;
-      break;
-
-      case CONTROL_CASELOWER_LOCAL_PART:
-      deliver_localpart = addr->lc_local_part;
-      break;
-
-      case CONTROL_ENFORCE_SYNC:
-      smtp_enforce_sync = TRUE;
-      break;
-
-      case CONTROL_NO_ENFORCE_SYNC:
-      smtp_enforce_sync = FALSE;
-      break;
-
-      #ifdef WITH_CONTENT_SCAN
-      case CONTROL_NO_MBOX_UNSPOOL:
-      no_mbox_unspool = TRUE;
-      break;
-      #endif
-
-      case CONTROL_NO_MULTILINE:
-      no_multiline_responses = TRUE;
-      break;
-
-      case CONTROL_NO_PIPELINING:
-      pipelining_enable = FALSE;
-      break;
-
-      case CONTROL_NO_DELAY_FLUSH:
-      disable_delay_flush = TRUE;
-      break;
-
-      case CONTROL_NO_CALLOUT_FLUSH:
-      disable_callout_flush = TRUE;
-      break;
-
-      case CONTROL_FAKEREJECT:
-      cancel_cutthrough_connection("fakereject");
-      case CONTROL_FAKEDEFER:
-      fake_response = (control_type == CONTROL_FAKEDEFER) ? DEFER : FAIL;
-      if (*p == '/')
-        {
-        uschar *pp = p + 1;
-        while (*pp != 0) pp++;
-        fake_response_text = expand_string(string_copyn(p+1, pp-p-1));
-        p = pp;
-        }
-       else
-        {
-        /* Explicitly reset to default string */
-        fake_response_text = US"Your message has been rejected but is being kept for evaluation.\nIf it was a legitimate message, it may still be delivered to the target recipient(s).";
-        }
-      break;
-
-      case CONTROL_FREEZE:
-      deliver_freeze = TRUE;
-      deliver_frozen_at = time(NULL);
-      freeze_tell = freeze_tell_config;       /* Reset to configured value */
-      if (Ustrncmp(p, "/no_tell", 8) == 0)
-        {
-        p += 8;
-        freeze_tell = NULL;
-        }
-      if (*p != 0)
-        {
-        *log_msgptr = string_sprintf("syntax error in \"control=%s\"", arg);
-        return ERROR;
-        }
-      cancel_cutthrough_connection("item frozen");
-      break;
-
-      case CONTROL_QUEUE_ONLY:
-      queue_only_policy = TRUE;
-      cancel_cutthrough_connection("queueing forced");
-      break;
-
-      case CONTROL_SUBMISSION:
-      originator_name = US"";
-      submission_mode = TRUE;
-      while (*p == '/')
-        {
-        if (Ustrncmp(p, "/sender_retain", 14) == 0)
-          {
-          p += 14;
-          active_local_sender_retain = TRUE;
-          active_local_from_check = FALSE;
-          }
-        else if (Ustrncmp(p, "/domain=", 8) == 0)
-          {
-          uschar *pp = p + 8;
-          while (*pp != 0 && *pp != '/') pp++;
-          submission_domain = string_copyn(p+8, pp-p-8);
-          p = pp;
-          }
-        /* The name= option must be last, because it swallows the rest of
-        the string. */
-        else if (Ustrncmp(p, "/name=", 6) == 0)
-          {
-          uschar *pp = p + 6;
-          while (*pp != 0) pp++;
-          submission_name = string_copy(parse_fix_phrase(p+6, pp-p-6,
-            big_buffer, big_buffer_size));
-          p = pp;
-          }
-        else break;
-        }
-      if (*p != 0)
-        {
-        *log_msgptr = string_sprintf("syntax error in \"control=%s\"", arg);
-        return ERROR;
-        }
-      break;
+      if ((control_forbids[control_type] & (1 << where)) != 0)
+    {
+    *log_msgptr = string_sprintf("cannot use \"control=%s\" in %s ACL",
+      controls[control_type], acl_wherenames[where]);
+    return ERROR;
+    }


-      case CONTROL_DEBUG:
-      while (*p == '/')
-        {
-        if (Ustrncmp(p, "/tag=", 5) == 0)
-          {
-          uschar *pp = p + 5;
-          while (*pp != '\0' && *pp != '/') pp++;
-          debug_tag = string_copyn(p+5, pp-p-5);
-          p = pp;
-          }
-        else if (Ustrncmp(p, "/opts=", 6) == 0)
-          {
-          uschar *pp = p + 6;
-          while (*pp != '\0' && *pp != '/') pp++;
-          debug_opts = string_copyn(p+6, pp-p-6);
-          p = pp;
-          }
-        }
-        debug_logging_activate(debug_tag, debug_opts);
-      break;
+      switch(control_type)
+    {
+    case CONTROL_AUTH_UNADVERTISED:
+    allow_auth_unadvertised = TRUE;
+    break;
+
+    #ifdef EXPERIMENTAL_BRIGHTMAIL
+    case CONTROL_BMI_RUN:
+    bmi_run = 1;
+    break;
+    #endif
+
+    #ifndef DISABLE_DKIM
+    case CONTROL_DKIM_VERIFY:
+    dkim_disable_verify = TRUE;
+    #ifdef EXPERIMENTAL_DMARC
+    /* Since DKIM was blocked, skip DMARC too */
+    dmarc_disable_verify = TRUE;
+    dmarc_enable_forensic = FALSE;
+    #endif
+    break;
+    #endif
+
+    #ifdef EXPERIMENTAL_DMARC
+    case CONTROL_DMARC_VERIFY:
+    dmarc_disable_verify = TRUE;
+    break;
+
+    case CONTROL_DMARC_FORENSIC:
+    dmarc_enable_forensic = TRUE;
+    break;
+    #endif
+
+    case CONTROL_DSCP:
+    if (*p == '/')
+      {
+      int fd, af, level, optname, value;
+      /* If we are acting on stdin, the setsockopt may fail if stdin is not
+      a socket; we can accept that, we'll just debug-log failures anyway. */
+      fd = fileno(smtp_in);
+      af = ip_get_address_family(fd);
+      if (af < 0)
+        {
+        HDEBUG(D_acl)
+          debug_printf("smtp input is probably not a socket [%s], not setting DSCP\n",
+          strerror(errno));
+        break;
+        }
+      if (dscp_lookup(p+1, af, &level, &optname, &value))
+        {
+        if (setsockopt(fd, level, optname, &value, sizeof(value)) < 0)
+          {
+          HDEBUG(D_acl) debug_printf("failed to set input DSCP[%s]: %s\n",
+          p+1, strerror(errno));
+          }
+        else
+          {
+          HDEBUG(D_acl) debug_printf("set input DSCP to \"%s\"\n", p+1);
+          }
+        }
+      else
+        {
+        *log_msgptr = string_sprintf("unrecognised DSCP value in \"control=%s\"", arg);
+        return ERROR;
+        }
+      }
+    else
+      {
+      *log_msgptr = string_sprintf("syntax error in \"control=%s\"", arg);
+      return ERROR;
+      }
+    break;
+
+    case CONTROL_ERROR:
+    return ERROR;
+
+    case CONTROL_CASEFUL_LOCAL_PART:
+    deliver_localpart = addr->cc_local_part;
+    break;
+
+    case CONTROL_CASELOWER_LOCAL_PART:
+    deliver_localpart = addr->lc_local_part;
+    break;
+
+    case CONTROL_ENFORCE_SYNC:
+    smtp_enforce_sync = TRUE;
+    break;
+
+    case CONTROL_NO_ENFORCE_SYNC:
+    smtp_enforce_sync = FALSE;
+    break;
+
+    #ifdef WITH_CONTENT_SCAN
+    case CONTROL_NO_MBOX_UNSPOOL:
+    no_mbox_unspool = TRUE;
+    break;
+    #endif
+
+    case CONTROL_NO_MULTILINE:
+    no_multiline_responses = TRUE;
+    break;
+
+    case CONTROL_NO_PIPELINING:
+    pipelining_enable = FALSE;
+    break;
+
+    case CONTROL_NO_DELAY_FLUSH:
+    disable_delay_flush = TRUE;
+    break;
+
+    case CONTROL_NO_CALLOUT_FLUSH:
+    disable_callout_flush = TRUE;
+    break;
+
+    case CONTROL_FAKEREJECT:
+    cancel_cutthrough_connection("fakereject");
+    case CONTROL_FAKEDEFER:
+    fake_response = (control_type == CONTROL_FAKEDEFER) ? DEFER : FAIL;
+    if (*p == '/')
+      {
+      const uschar *pp = p + 1;
+      while (*pp != 0) pp++;
+      fake_response_text = expand_string(string_copyn(p+1, pp-p-1));
+      p = pp;
+      }
+     else
+      {
+      /* Explicitly reset to default string */
+      fake_response_text = US"Your message has been rejected but is being kept for evaluation.\nIf it was a legitimate message, it may still be delivered to the target recipient(s).";
+      }
+    break;


-      case CONTROL_SUPPRESS_LOCAL_FIXUPS:
-      suppress_local_fixups = TRUE;
-      break;
+    case CONTROL_FREEZE:
+    deliver_freeze = TRUE;
+    deliver_frozen_at = time(NULL);
+    freeze_tell = freeze_tell_config;       /* Reset to configured value */
+    if (Ustrncmp(p, "/no_tell", 8) == 0)
+      {
+      p += 8;
+      freeze_tell = NULL;
+      }
+    if (*p != 0)
+      {
+      *log_msgptr = string_sprintf("syntax error in \"control=%s\"", arg);
+      return ERROR;
+      }
+    cancel_cutthrough_connection("item frozen");
+    break;
+
+    case CONTROL_QUEUE_ONLY:
+    queue_only_policy = TRUE;
+    cancel_cutthrough_connection("queueing forced");
+    break;
+
+    case CONTROL_SUBMISSION:
+    originator_name = US"";
+    submission_mode = TRUE;
+    while (*p == '/')
+      {
+      if (Ustrncmp(p, "/sender_retain", 14) == 0)
+        {
+        p += 14;
+        active_local_sender_retain = TRUE;
+        active_local_from_check = FALSE;
+        }
+      else if (Ustrncmp(p, "/domain=", 8) == 0)
+        {
+        const uschar *pp = p + 8;
+        while (*pp != 0 && *pp != '/') pp++;
+        submission_domain = string_copyn(p+8, pp-p-8);
+        p = pp;
+        }
+      /* The name= option must be last, because it swallows the rest of
+      the string. */
+      else if (Ustrncmp(p, "/name=", 6) == 0)
+        {
+        const uschar *pp = p + 6;
+        while (*pp != 0) pp++;
+        submission_name = string_copy(parse_fix_phrase(p+6, pp-p-6,
+          big_buffer, big_buffer_size));
+        p = pp;
+        }
+      else break;
+      }
+    if (*p != 0)
+      {
+      *log_msgptr = string_sprintf("syntax error in \"control=%s\"", arg);
+      return ERROR;
+      }
+    break;


-      case CONTROL_CUTTHROUGH_DELIVERY:
-      if (prdr_requested)
-    /* Too hard to think about for now.  We might in future cutthrough
-    the case where both sides handle prdr and this-node prdr acl
-    is "accept" */
-        *log_msgptr = string_sprintf(US"PRDR on %s reception\n", arg);
-      else
-    {
-    if (deliver_freeze)
-      *log_msgptr = US"frozen";
-    else if (queue_only_policy)
-      *log_msgptr = US"queue-only";
-    else if (fake_response == FAIL)
-      *log_msgptr = US"fakereject";
+    case CONTROL_DEBUG:
+    while (*p == '/')
+      {
+      if (Ustrncmp(p, "/tag=", 5) == 0)
+        {
+        const uschar *pp = p + 5;
+        while (*pp != '\0' && *pp != '/') pp++;
+        debug_tag = string_copyn(p+5, pp-p-5);
+        p = pp;
+        }
+      else if (Ustrncmp(p, "/opts=", 6) == 0)
+        {
+        const uschar *pp = p + 6;
+        while (*pp != '\0' && *pp != '/') pp++;
+        debug_opts = string_copyn(p+6, pp-p-6);
+        p = pp;
+        }
+      }
+      debug_logging_activate(debug_tag, debug_opts);
+    break;
+
+    case CONTROL_SUPPRESS_LOCAL_FIXUPS:
+    suppress_local_fixups = TRUE;
+    break;
+
+    case CONTROL_CUTTHROUGH_DELIVERY:
+    if (prdr_requested)
+      /* Too hard to think about for now.  We might in future cutthrough
+      the case where both sides handle prdr and this-node prdr acl
+      is "accept" */
+      *log_msgptr = string_sprintf(US"PRDR on %s reception\n", arg);
     else
       {
-      if (rcpt_count == 1) cutthrough.delivery = TRUE;
-      break;
+      if (deliver_freeze)
+        *log_msgptr = US"frozen";
+      else if (queue_only_policy)
+        *log_msgptr = US"queue-only";
+      else if (fake_response == FAIL)
+        *log_msgptr = US"fakereject";
+      else
+        {
+        if (rcpt_count == 1) cutthrough.delivery = TRUE;
+        break;
+        }
+      *log_msgptr = string_sprintf("\"control=%s\" on %s item",
+                    arg, *log_msgptr);
       }
-    *log_msgptr = string_sprintf("\"control=%s\" on %s item",
-                      arg, *log_msgptr);
+    return ERROR;
     }
-      return ERROR;
+      break;
       }
-    break;


     #ifdef EXPERIMENTAL_DCC
     case ACLC_DCC:
       {
       /* Seperate the regular expression and any optional parameters. */
-      uschar *ss = string_nextinlist(&arg, &sep, big_buffer, big_buffer_size);
+      const uschar * list = arg;
+      uschar *ss = string_nextinlist(&list, &sep, big_buffer, big_buffer_size);
       /* Run the dcc backend. */
       rc = dcc_process(&ss);
       /* Modify return code based upon the existance of options. */
-      while ((ss = string_nextinlist(&arg, &sep, big_buffer, big_buffer_size))
+      while ((ss = string_nextinlist(&list, &sep, big_buffer, big_buffer_size))
             != NULL) {
         if (strcmpic(ss, US"defer_ok") == 0 && rc == DEFER)
           {
@@ -3495,7 +3507,7 @@ for (; cb != NULL; cb = cb->next)


     case ACLC_DOMAINS:
     rc = match_isinlist(addr->domain, &arg, 0, &domainlist_anchor,
-      addr->domain_cache, MCL_DOMAIN, TRUE, &deliver_domain_data);
+      addr->domain_cache, MCL_DOMAIN, TRUE, CUSS &deliver_domain_data);
     break;


     /* The value in tls_cipher is the full cipher name, for example,
@@ -3528,21 +3540,22 @@ for (; cb != NULL; cb = cb->next)


     case ACLC_HOSTS:
     rc = verify_check_this_host(&arg, sender_host_cache, NULL,
-      (sender_host_address == NULL)? US"" : sender_host_address, &host_data);
+      (sender_host_address == NULL)? US"" : sender_host_address,
+      CUSS &host_data);
     if (host_data != NULL) host_data = string_copy_malloc(host_data);
     break;


     case ACLC_LOCAL_PARTS:
     rc = match_isinlist(addr->cc_local_part, &arg, 0,
       &localpartlist_anchor, addr->localpart_cache, MCL_LOCALPART, TRUE,
-      &deliver_localpart_data);
+      CUSS &deliver_localpart_data);
     break;


     case ACLC_LOG_REJECT_TARGET:
       {
       int logbits = 0;
       int sep = 0;
-      uschar *s = arg;
+      const uschar *s = arg;
       uschar *ss;
       while ((ss = string_nextinlist(&s, &sep, big_buffer, big_buffer_size))
               != NULL)
@@ -3564,7 +3577,7 @@ for (; cb != NULL; cb = cb->next)
     case ACLC_LOGWRITE:
       {
       int logbits = 0;
-      uschar *s = arg;
+      const uschar *s = arg;
       if (*s == ':')
         {
         s++;
@@ -3598,12 +3611,13 @@ for (; cb != NULL; cb = cb->next)
     case ACLC_MALWARE:            /* Run the malware backend. */
       {
       /* Separate the regular expression and any optional parameters. */
-      uschar *ss = string_nextinlist(&arg, &sep, big_buffer, big_buffer_size);
+      const uschar * list = arg;
+      uschar *ss = string_nextinlist(&list, &sep, big_buffer, big_buffer_size);
       uschar *opt;
       BOOL defer_ok = FALSE;
       int timeout = 0;


-      while ((opt = string_nextinlist(&arg, &sep, NULL, 0)))
+      while ((opt = string_nextinlist(&list, &sep, NULL, 0)))
         if (strcmpic(opt, US"defer_ok") == 0)
       defer_ok = TRUE;
     else if (  strncmpic(opt, US"tmo=", 4) == 0
@@ -3630,8 +3644,8 @@ for (; cb != NULL; cb = cb->next)
     break;


     case ACLC_RECIPIENTS:
-    rc = match_address_list(addr->address, TRUE, TRUE, &arg, NULL, -1, 0,
-      &recipient_data);
+    rc = match_address_list((const uschar *)addr->address, TRUE, TRUE, &arg, NULL, -1, 0,
+      CUSS &recipient_data);
     break;


     #ifdef WITH_CONTENT_SCAN
@@ -3655,8 +3669,8 @@ for (; cb != NULL; cb = cb->next)
     break;


     case ACLC_SENDERS:
-    rc = match_address_list(sender_address, TRUE, TRUE, &arg,
-      sender_address_cache, -1, 0, &sender_data);
+    rc = match_address_list((const uschar *)sender_address, TRUE, TRUE, &arg,
+      sender_address_cache, -1, 0, CUSS &sender_data);
     break;


     /* Connection variables must persist forever */
@@ -3674,11 +3688,12 @@ for (; cb != NULL; cb = cb->next)
     case ACLC_SPAM:
       {
       /* Seperate the regular expression and any optional parameters. */
-      uschar *ss = string_nextinlist(&arg, &sep, big_buffer, big_buffer_size);
+      const uschar * list = arg;
+      uschar *ss = string_nextinlist(&list, &sep, big_buffer, big_buffer_size);
       /* Run the spam backend. */
-      rc = spam(&ss);
+      rc = spam(CUSS &ss);
       /* Modify return code based upon the existance of options. */
-      while ((ss = string_nextinlist(&arg, &sep, big_buffer, big_buffer_size))
+      while ((ss = string_nextinlist(&list, &sep, big_buffer, big_buffer_size))
             != NULL) {
         if (strcmpic(ss, US"defer_ok") == 0 && rc == DEFER)
           {
@@ -4244,7 +4259,7 @@ return FAIL;
 the name of an ACL followed optionally by up to 9 space-separated arguments.
 The name and args are separately expanded.  Args go into $acl_arg globals. */
 static int
-acl_check_wargs(int where, address_item *addr, uschar *s, int level,
+acl_check_wargs(int where, address_item *addr, const uschar *s, int level,
   uschar **user_msgptr, uschar **log_msgptr)
 {
 uschar * tmp;
diff --git a/src/src/auths/plaintext.c b/src/src/auths/plaintext.c
index ff449e5..3d0ae0f 100644
--- a/src/src/auths/plaintext.c
+++ b/src/src/auths/plaintext.c
@@ -66,7 +66,7 @@ auth_plaintext_server(auth_instance *ablock, uschar *data)
 {
 auth_plaintext_options_block *ob =
   (auth_plaintext_options_block *)(ablock->options_block);
-uschar *prompts = ob->server_prompts;
+const uschar *prompts = ob->server_prompts;
 uschar *clear, *end, *s;
 int number = 1;
 int len, rc;
@@ -76,7 +76,7 @@ int sep = 0;


 if (prompts != NULL)
   {
-  prompts = expand_string(prompts);
+  prompts = expand_cstring(prompts);
   if (prompts == NULL)
     {
     auth_defer_msg = expand_string_message;
@@ -163,7 +163,7 @@ auth_plaintext_client(
 {
 auth_plaintext_options_block *ob =
   (auth_plaintext_options_block *)(ablock->options_block);
-uschar *text = ob->client_send;
+const uschar *text = ob->client_send;
 uschar *s;
 BOOL first = TRUE;
 int sep = 0;
diff --git a/src/src/child.c b/src/src/child.c
index 20083b4..c02264a 100644
--- a/src/src/child.c
+++ b/src/src/child.c
@@ -141,7 +141,7 @@ if (exec_type == CEE_RETURN_ARGV)
 failure. We know that there will always be at least one extra option in the
 call when exec() is done here, so it can be used to add to the panic data. */


-DEBUG(D_exec) debug_print_argv(argv);
+DEBUG(D_exec) debug_print_argv(CUSS argv);
 exim_nullstd();                            /* Make sure std{in,out,err} exist */
 execv(CS argv[0], (char *const *)argv);


@@ -307,8 +307,9 @@ Returns:      the pid of the created process or -1 if anything has gone wrong
 */


pid_t
-child_open_uid(uschar **argv, uschar **envp, int newumask, uid_t *newuid,
- gid_t *newgid, int *infdptr, int *outfdptr, uschar *wd, BOOL make_leader)
+child_open_uid(const uschar **argv, const uschar **envp, int newumask,
+ uid_t *newuid, gid_t *newgid, int *infdptr, int *outfdptr, uschar *wd,
+ BOOL make_leader)
{
int save_errno;
int inpfd[2], outpfd[2];
@@ -387,7 +388,7 @@ if (pid == 0)
/* Now do the exec */

   if (envp == NULL) execv(CS argv[0], (char *const *)argv);
-    else execve(CS argv[0], (char *const *)argv, (char *const *)envp);
+  else execve(CS argv[0], (char *const *)argv, (char *const *)envp);


/* Failed to execv. Signal this failure using EX_EXECFAILED. We are
losing the actual errno we got back, because there is no way to return
@@ -450,8 +451,8 @@ pid_t
child_open(uschar **argv, uschar **envp, int newumask, int *infdptr,
int *outfdptr, BOOL make_leader)
{
-return child_open_uid(argv, envp, newumask, NULL, NULL, infdptr, outfdptr,
- NULL, make_leader);
+return child_open_uid(CUSS argv, CUSS envp, newumask, NULL, NULL,
+ infdptr, outfdptr, NULL, make_leader);
}


diff --git a/src/src/daemon.c b/src/src/daemon.c
index 256cc9c..39da13c 100644
--- a/src/src/daemon.c
+++ b/src/src/daemon.c
@@ -1048,7 +1048,7 @@ if (daemon_listen && !inetd_wait_mode)
int sep;
int pct = 0;
uschar *s;
- uschar *list;
+ const uschar * list;
uschar *local_iface_source = US"local_interfaces";
ip_address_item *ipa;
ip_address_item **pipa;
@@ -1071,8 +1071,7 @@ if (daemon_listen && !inetd_wait_mode)

     list = override_local_interfaces;
     sep = 0;
-    while ((s = string_nextinlist(&list,&sep,big_buffer,big_buffer_size))
-           != NULL)
+    while ((s = string_nextinlist(&list, &sep, big_buffer, big_buffer_size)))
       {
       uschar joinstr[4];
       uschar **ptr;
@@ -1127,13 +1126,13 @@ if (daemon_listen && !inetd_wait_mode)


   list = daemon_smtp_port;
   sep = 0;
-  while ((s = string_nextinlist(&list,&sep,big_buffer,big_buffer_size)))
+  while ((s = string_nextinlist(&list, &sep, big_buffer, big_buffer_size)))
     pct++;
   default_smtp_port = store_get((pct+1) * sizeof(int));
   list = daemon_smtp_port;
   sep = 0;
   for (pct = 0;
-       (s = string_nextinlist(&list,&sep,big_buffer,big_buffer_size));
+       (s = string_nextinlist(&list, &sep, big_buffer, big_buffer_size));
        pct++)
     {
     if (isdigit(*s))
diff --git a/src/src/dbfn.c b/src/src/dbfn.c
index 4a1c20f..cd62094 100644
--- a/src/src/dbfn.c
+++ b/src/src/dbfn.c
@@ -294,17 +294,21 @@ Returns: a pointer to the retrieved record, or
 */


void *
-dbfn_read_with_length(open_db *dbblock, uschar *key, int *length)
+dbfn_read_with_length(open_db *dbblock, const uschar *key, int *length)
{
void *yield;
EXIM_DATUM key_datum, result_datum;
+int klen = Ustrlen(key) + 1;
+uschar * key_copy = store_get(klen);
+
+memcpy(key_copy, key, klen);

DEBUG(D_hints_lookup) debug_printf("dbfn_read: key=%s\n", key);

 EXIM_DATUM_INIT(key_datum);         /* Some DBM libraries require the datum */
 EXIM_DATUM_INIT(result_datum);      /* to be cleared before use. */
-EXIM_DATUM_DATA(key_datum) = CS key;
-EXIM_DATUM_SIZE(key_datum) = Ustrlen(key) + 1;
+EXIM_DATUM_DATA(key_datum) = CS key_copy;
+EXIM_DATUM_SIZE(key_datum) = klen;


if (!EXIM_DBGET(dbblock->dbptr, key_datum, result_datum)) return NULL;

@@ -334,18 +338,22 @@ Returns:    the yield of the underlying dbm or db "write" function. If this
 */


int
-dbfn_write(open_db *dbblock, uschar *key, void *ptr, int length)
+dbfn_write(open_db *dbblock, const uschar *key, void *ptr, int length)
{
EXIM_DATUM key_datum, value_datum;
dbdata_generic *gptr = (dbdata_generic *)ptr;
+int klen = Ustrlen(key) + 1;
+uschar * key_copy = store_get(klen);
+
+memcpy(key_copy, key, klen);
gptr->time_stamp = time(NULL);

DEBUG(D_hints_lookup) debug_printf("dbfn_write: key=%s\n", key);

 EXIM_DATUM_INIT(key_datum);         /* Some DBM libraries require the datum */
 EXIM_DATUM_INIT(value_datum);       /* to be cleared before use. */
-EXIM_DATUM_DATA(key_datum) = CS key;
-EXIM_DATUM_SIZE(key_datum) = Ustrlen(key) + 1;
+EXIM_DATUM_DATA(key_datum) = CS key_copy;
+EXIM_DATUM_SIZE(key_datum) = klen;
 EXIM_DATUM_DATA(value_datum) = CS ptr;
 EXIM_DATUM_SIZE(value_datum) = length;
 return EXIM_DBPUT(dbblock->dbptr, key_datum, value_datum);
@@ -366,12 +374,16 @@ Returns: the yield of the underlying dbm or db "delete" function.
 */


 int
-dbfn_delete(open_db *dbblock, uschar *key)
+dbfn_delete(open_db *dbblock, const uschar *key)
 {
+int klen = Ustrlen(key) + 1;
+uschar * key_copy = store_get(klen);
+
+memcpy(key_copy, key, klen);
 EXIM_DATUM key_datum;
 EXIM_DATUM_INIT(key_datum);         /* Some DBM libraries require clearing */
-EXIM_DATUM_DATA(key_datum) = CS key;
-EXIM_DATUM_SIZE(key_datum) = Ustrlen(key) + 1;
+EXIM_DATUM_DATA(key_datum) = CS key_copy;
+EXIM_DATUM_SIZE(key_datum) = klen;
 return EXIM_DBDEL(dbblock->dbptr, key_datum);
 }


diff --git a/src/src/dbfunctions.h b/src/src/dbfunctions.h
index 1963fa9..e4f78d1 100644
--- a/src/src/dbfunctions.h
+++ b/src/src/dbfunctions.h
@@ -9,11 +9,11 @@
/* Functions for reading/writing exim database files */

 void     dbfn_close(open_db *);
-int      dbfn_delete(open_db *, uschar *);
+int      dbfn_delete(open_db *, const uschar *);
 open_db *dbfn_open(uschar *, int, open_db *, BOOL);
-void    *dbfn_read_with_length(open_db *, uschar *, int *);
+void    *dbfn_read_with_length(open_db *, const uschar *, int *);
 uschar  *dbfn_scan(open_db *, BOOL, EXIM_CURSOR **);
-int      dbfn_write(open_db *, uschar *, void *, int);
+int      dbfn_write(open_db *, const uschar *, void *, int);


/* Macro for the common call to read without wanting to know the length. */

diff --git a/src/src/dcc.c b/src/src/dcc.c
index 44c0c00..6f4c1ab 100644
--- a/src/src/dcc.c
+++ b/src/src/dcc.c
@@ -45,9 +45,11 @@ int flushbuffer (int socket, uschar *buffer)
return retval;
}

-int dcc_process(uschar **listptr) {
+int
+dcc_process(uschar **listptr)
+{
   int sep = 0;
-  uschar *list = *listptr;
+  const uschar *list = *listptr;
   FILE *data_file;
   uschar *dcc_default_ip_option = US"127.0.0.1";
   uschar *dcc_helo_option = US"localhost";
diff --git a/src/src/debug.c b/src/src/debug.c
index ebd932f..10bc2a5 100644
--- a/src/src/debug.c
+++ b/src/src/debug.c
@@ -75,7 +75,7 @@ Returns:     nothing
 */


void
-debug_print_argv(uschar **argv)
+debug_print_argv(const uschar ** argv)
{
debug_printf("exec");
while (*argv != NULL) debug_printf(" %.256s", *argv++);
diff --git a/src/src/deliver.c b/src/src/deliver.c
index afbadca..7ec94ed 100644
--- a/src/src/deliver.c
+++ b/src/src/deliver.c
@@ -127,7 +127,7 @@ deliver_set_expansions(address_item *addr)
{
if (addr == NULL)
{
- uschar ***p = address_expansions;
+ const uschar ***p = address_expansions;
while (*p != NULL) **p++ = NULL;
return;
}
@@ -718,7 +718,7 @@ d_tlslog(uschar * s, int * sizep, int * ptrp, address_item * addr)

#ifdef EXPERIMENTAL_EVENT
uschar *
-event_raise(uschar * action, uschar * event, uschar * ev_data)
+event_raise(uschar * action, const uschar * event, uschar * ev_data)
{
uschar * s;
if (action)
@@ -752,11 +752,11 @@ return NULL;
}

static void
-msg_event_raise(uschar * event, address_item * addr)
+msg_event_raise(const uschar * event, const address_item * addr)
{
-uschar * save_domain = deliver_domain;
+const uschar * save_domain = deliver_domain;
uschar * save_local = deliver_localpart;
-uschar * save_host = deliver_host;
+const uschar * save_host = deliver_host;

if (!addr->transport)
return;
@@ -1018,7 +1018,10 @@ malformed, it won't ever have gone near LDAP.) */

 if (addr->message != NULL)
   {
-  addr->message = string_printing(addr->message);
+  const uschar * s = string_printing(addr->message);
+  if (s != addr->message)
+    addr->message = US s;
+    /* deconst cast ok as string_printing known to have alloc'n'copied */
   if (((Ustrstr(addr->message, "failed to expand") != NULL) || (Ustrstr(addr->message, "expansion of ") != NULL)) &&
       (Ustrstr(addr->message, "mysql") != NULL ||
        Ustrstr(addr->message, "pgsql") != NULL ||
@@ -1075,11 +1078,12 @@ if (addr->return_file >= 0 && addr->return_filename != NULL)
         if (s != NULL)
           {
           uschar *p = big_buffer + Ustrlen(big_buffer);
+      const uschar * sp;
           while (p > big_buffer && isspace(p[-1])) p--;
           *p = 0;
-          s = string_printing(big_buffer);
+          sp = string_printing(big_buffer);
           log_write(0, LOG_MAIN, "<%s>: %s transport output: %s",
-            addr->address, tb->name, s);
+            addr->address, tb->name, sp);
           }
         (void)fclose(f);
         }
@@ -2779,7 +2783,7 @@ sort_remote_deliveries(void)
 {
 int sep = 0;
 address_item **aptr = &addr_remote;
-uschar *listptr = remote_sort_domains;
+const uschar *listptr = remote_sort_domains;
 uschar *pattern;
 uschar patbuf[256];


@@ -2794,7 +2798,7 @@ while (*aptr != NULL &&
     {
     address_item **next;
     deliver_domain = (*aptr)->domain;   /* set $domain */
-    if (match_isinlist(deliver_domain, &pattern, UCHAR_MAX+1,
+    if (match_isinlist(deliver_domain, (const uschar **)&pattern, UCHAR_MAX+1,
           &domainlist_anchor, NULL, MCL_DOMAIN, TRUE, NULL) == OK)
       {
       aptr = &((*aptr)->next);
@@ -2804,7 +2808,7 @@ while (*aptr != NULL &&
     next = &((*aptr)->next);
     while (*next != NULL &&
            (deliver_domain = (*next)->domain,  /* Set $domain */
-            match_isinlist(deliver_domain, &pattern, UCHAR_MAX+1,
+            match_isinlist(deliver_domain, (const uschar **)&pattern, UCHAR_MAX+1,
               &domainlist_anchor, NULL, MCL_DOMAIN, TRUE, NULL)) != OK)
       next = &((*next)->next);


@@ -4580,7 +4584,7 @@ if (percent_hack_domains != NULL)

deliver_domain = addr->domain; /* set $domain */

-  while ((rc = match_isinlist(deliver_domain, &percent_hack_domains, 0,
+  while ((rc = match_isinlist(deliver_domain, (const uschar **)&percent_hack_domains, 0,
            &domainlist_anchor, addr->domain_cache, MCL_DOMAIN, TRUE, NULL))
              == OK &&
          (t = Ustrrchr(local_part, '%')) != NULL)
@@ -5672,7 +5676,7 @@ if (process_recipients != RECIP_IGNORE)
       if (process_recipients != RECIP_ACCEPT)
     {
     uschar * save_local =  deliver_localpart;
-    uschar * save_domain = deliver_domain;
+    const uschar * save_domain = deliver_domain;


     deliver_localpart = expand_string(
               string_sprintf("${local_part:%s}", new->address));
@@ -5937,7 +5941,7 @@ while (addr_new != NULL)           /* Loop until all addresses dealt with */


     deliver_domain = addr->domain;  /* set $domain */
     if (!forced && hold_domains != NULL &&
-         (rc = match_isinlist(addr->domain, &hold_domains, 0,
+         (rc = match_isinlist(addr->domain, (const uschar **)&hold_domains, 0,
            &domainlist_anchor, addr->domain_cache, MCL_DOMAIN, TRUE,
            NULL)) != FAIL)
       {
@@ -6144,7 +6148,7 @@ while (addr_new != NULL)           /* Loop until all addresses dealt with */
       addr_route = addr->next;


       deliver_domain = addr->domain;  /* set $domain */
-      if ((rc = match_isinlist(addr->domain, &queue_domains, 0,
+      if ((rc = match_isinlist(addr->domain, (const uschar **)&queue_domains, 0,
             &domainlist_anchor, addr->domain_cache, MCL_DOMAIN, TRUE, NULL))
               != OK)
         {
@@ -6177,7 +6181,7 @@ while (addr_new != NULL)           /* Loop until all addresses dealt with */
     {
     int rc;
     address_item *addr = addr_route;
-    uschar *old_domain = addr->domain;
+    const uschar *old_domain = addr->domain;
     uschar *old_unique = addr->unique;
     addr_route = addr->next;
     addr->next = NULL;
@@ -7400,7 +7404,8 @@ else if (addr_defer != (address_item *)(+1))


     if (deliver_domain != NULL)
       {
-      uschar *d = (testflag(addr, af_pfr))? addr->parent->domain : addr->domain;
+      const uschar *d = testflag(addr, af_pfr)
+    ? addr->parent->domain : addr->domain;


       /* The domain may be unset for an address that has never been routed
       because the system filter froze the message. */
diff --git a/src/src/dkim.c b/src/src/dkim.c
index 171fccc..0ac4dc3 100644
--- a/src/src/dkim.c
+++ b/src/src/dkim.c
@@ -383,12 +383,11 @@ uschar *dkim_exim_expand_defaults(int what) {
 }



-uschar *dkim_exim_sign(int dkim_fd,
-                       uschar *dkim_private_key,
-                       uschar *dkim_domain,
-                       uschar *dkim_selector,
-                       uschar *dkim_canon,
-                       uschar *dkim_sign_headers) {
+uschar *
+dkim_exim_sign(int dkim_fd, uschar *dkim_private_key,
+       const uschar *dkim_domain, uschar *dkim_selector,
+       uschar *dkim_canon, uschar *dkim_sign_headers)
+{
   int sep = 0;
   uschar *seen_items = NULL;
   int seen_items_size = 0;
@@ -412,7 +411,7 @@ uschar *dkim_exim_sign(int dkim_fd,


store_pool = POOL_MAIN;

-  dkim_domain = expand_string(dkim_domain);
+  dkim_domain = expand_cstring(dkim_domain);
   if (dkim_domain == NULL) {
     /* expansion error, do not send message. */
     log_write(0, LOG_MAIN|LOG_PANIC, "failed to expand "
@@ -429,7 +428,7 @@ uschar *dkim_exim_sign(int dkim_fd,
     /* Only sign once for each domain, no matter how often it
        appears in the expanded list. */
     if (seen_items != NULL) {
-      uschar *seen_items_list = seen_items;
+      const uschar *seen_items_list = seen_items;
       if (match_isinlist(dkim_signing_domain,
                          &seen_items_list,0,NULL,NULL,MCL_STRING,TRUE,NULL) == OK)
         continue;
diff --git a/src/src/dkim.h b/src/src/dkim.h
index 15a7e60..83c47ca 100644
--- a/src/src/dkim.h
+++ b/src/src/dkim.h
@@ -5,7 +5,7 @@
 /* Copyright (c) University of Cambridge, 1995 - 2007 */
 /* See the file NOTICE for conditions of use and distribution. */


-uschar *dkim_exim_sign(int,uschar *,uschar *,uschar *,uschar *,uschar *);
+uschar *dkim_exim_sign(int, uschar *, const uschar *, uschar *, uschar *, uschar *);
 void    dkim_exim_verify_init(void);
 void    dkim_exim_verify_feed(uschar *, int);
 void    dkim_exim_verify_finish(void);
diff --git a/src/src/dns.c b/src/src/dns.c
index 61d2017..79eb936 100644
--- a/src/src/dns.c
+++ b/src/src/dns.c
@@ -257,9 +257,9 @@ Returns:     nothing
 */


void
-dns_build_reverse(uschar *string, uschar *buffer)
+dns_build_reverse(const uschar *string, uschar *buffer)
{
-uschar *p = string + Ustrlen(string);
+const uschar *p = string + Ustrlen(string);
uschar *pp = buffer;

 /* Handle IPv4 address */
@@ -271,7 +271,7 @@ if (Ustrchr(string, ':') == NULL)
   int i;
   for (i = 0; i < 4; i++)
     {
-    uschar *ppp = p;
+    const uschar *ppp = p;
     while (ppp > string && ppp[-1] != '.') ppp--;
     Ustrncpy(pp, ppp, p - ppp);
     pp += p - ppp;
@@ -560,7 +560,7 @@ dns_basic_lookup(dns_answer *dnsa, const uschar *name, int type)
 {
 #ifndef STAND_ALONE
 int rc = -1;
-uschar *save;
+const uschar *save_domain;
 #endif
 res_state resp = os_get_dns_resolver_res();


@@ -677,11 +677,11 @@ if (dnsa->answerlen < 0) switch (h_errno)

   /* Cut this out for various test programs */
 #ifndef STAND_ALONE
-  save = deliver_domain;
+  save_domain = deliver_domain;
   deliver_domain = string_copy(name);  /* set $domain */
-  rc = match_isinlist(name, &dns_again_means_nonexist, 0, NULL, NULL,
+  rc = match_isinlist(name, (const uschar **)&dns_again_means_nonexist, 0, NULL, NULL,
     MCL_DOMAIN, TRUE, NULL);
-  deliver_domain = save;
+  deliver_domain = save_domain;
   if (rc != OK)
     {
     DEBUG(D_dns) debug_printf("returning DNS_AGAIN\n");
@@ -755,7 +755,7 @@ Returns:                DNS_SUCCEED   successful lookup


 int
 dns_lookup(dns_answer *dnsa, const uschar *name, int type,
-  uschar **fully_qualified_name)
+  const uschar **fully_qualified_name)
 {
 int i;
 const uschar *orig_name = name;
@@ -874,7 +874,7 @@ Returns:                DNS_SUCCEED   successful lookup


int
dns_special_lookup(dns_answer *dnsa, const uschar *name, int type,
- uschar **fully_qualified_name)
+ const uschar **fully_qualified_name)
{
if (type >= 0) return dns_lookup(dnsa, name, type, fully_qualified_name);

diff --git a/src/src/exim.c b/src/src/exim.c
index e0c591d..c94bdc1 100644
--- a/src/src/exim.c
+++ b/src/src/exim.c
@@ -2308,7 +2308,7 @@ for (i = 1; i < argc; i++)
               if (nr_configs)
                 {
                 int sep = 0;
-                uschar *list = argrest;
+                const uschar *list = argrest;
                 uschar *filename;
                 while (trusted_config && (filename = string_nextinlist(&list,
                         &sep, big_buffer, big_buffer_size)) != NULL)
@@ -3995,7 +3995,7 @@ if (((debug_selector & D_any) != 0 || (log_extra_selector & LX_arguments) != 0)
   for (i = 0; i < argc; i++)
     {
     int len = Ustrlen(argv[i]);
-    uschar *printing;
+    const uschar *printing;
     uschar *quote;
     if (p + len + 8 >= big_buffer + big_buffer_size)
       {
@@ -4007,7 +4007,7 @@ if (((debug_selector & D_any) != 0 || (log_extra_selector & LX_arguments) != 0)
     printing = string_printing(argv[i]);
     if (printing[0] == 0) quote = US"\""; else
       {
-      uschar *pp = printing;
+      const uschar *pp = printing;
       quote = US"";
       while (*pp != 0) if (isspace(*pp++)) { quote = US"\""; break; }
       }
diff --git a/src/src/exim_dbmbuild.c b/src/src/exim_dbmbuild.c
index ce06f16..729c2eb 100644
--- a/src/src/exim_dbmbuild.c
+++ b/src/src/exim_dbmbuild.c
@@ -88,10 +88,10 @@ Returns:   the value of the character escape
 */


 int
-string_interpret_escape(uschar **pp)
+string_interpret_escape(const uschar **pp)
 {
 int ch;
-uschar *p = *pp;
+const uschar *p = *pp;
 ch = *(++p);
 if (isdigit(ch) && ch != '8' && ch != '9')
   {
@@ -329,7 +329,7 @@ while (Ufgets(line, max_insize, f) != NULL)
       keystart = t;
       while (*s != 0 && *s != '\"')
         {
-        if (*s == '\\') *t++ = string_interpret_escape(&s);
+        if (*s == '\\') *t++ = string_interpret_escape((const uschar **)&s);
           else *t++ = *s;
         s++;
         }
diff --git a/src/src/exim_dbutil.c b/src/src/exim_dbutil.c
index 124303a..4832324 100644
--- a/src/src/exim_dbutil.c
+++ b/src/src/exim_dbutil.c
@@ -356,15 +356,19 @@ Returns: a pointer to the retrieved record, or
 */


void *
-dbfn_read_with_length(open_db *dbblock, uschar *key, int *length)
+dbfn_read_with_length(open_db *dbblock, const uschar *key, int *length)
{
void *yield;
EXIM_DATUM key_datum, result_datum;
+int klen = Ustrlen(key) + 1;
+uschar * key_copy = store_get(klen);
+
+memcpy(key_copy, key, klen);

 EXIM_DATUM_INIT(key_datum);         /* Some DBM libraries require the datum */
 EXIM_DATUM_INIT(result_datum);      /* to be cleared before use. */
-EXIM_DATUM_DATA(key_datum) = CS key;
-EXIM_DATUM_SIZE(key_datum) = Ustrlen(key) + 1;
+EXIM_DATUM_DATA(key_datum) = CS key_copy;
+EXIM_DATUM_SIZE(key_datum) = klen;


if (!EXIM_DBGET(dbblock->dbptr, key_datum, result_datum)) return NULL;

@@ -396,16 +400,20 @@ Returns:    the yield of the underlying dbm or db "write" function. If this
 */


int
-dbfn_write(open_db *dbblock, uschar *key, void *ptr, int length)
+dbfn_write(open_db *dbblock, const uschar *key, void *ptr, int length)
{
EXIM_DATUM key_datum, value_datum;
dbdata_generic *gptr = (dbdata_generic *)ptr;
+int klen = Ustrlen(key) + 1;
+uschar * key_copy = store_get(klen);
+
+memcpy(key_copy, key, klen);
gptr->time_stamp = time(NULL);

 EXIM_DATUM_INIT(key_datum);         /* Some DBM libraries require the datum */
 EXIM_DATUM_INIT(value_datum);       /* to be cleared before use. */
-EXIM_DATUM_DATA(key_datum) = CS key;
-EXIM_DATUM_SIZE(key_datum) = Ustrlen(key) + 1;
+EXIM_DATUM_DATA(key_datum) = CS key_copy;
+EXIM_DATUM_SIZE(key_datum) = klen;
 EXIM_DATUM_DATA(value_datum) = CS ptr;
 EXIM_DATUM_SIZE(value_datum) = length;
 return EXIM_DBPUT(dbblock->dbptr, key_datum, value_datum);
@@ -426,12 +434,16 @@ Returns: the yield of the underlying dbm or db "delete" function.
 */


 int
-dbfn_delete(open_db *dbblock, uschar *key)
+dbfn_delete(open_db *dbblock, const uschar *key)
 {
+int klen = Ustrlen(key) + 1;
+uschar * key_copy = store_get(klen);
+
+memcpy(key_copy, key, klen);
 EXIM_DATUM key_datum;
 EXIM_DATUM_INIT(key_datum);         /* Some DBM libraries require clearing */
-EXIM_DATUM_DATA(key_datum) = CS key;
-EXIM_DATUM_SIZE(key_datum) = Ustrlen(key) + 1;
+EXIM_DATUM_DATA(key_datum) = CS key_copy;
+EXIM_DATUM_SIZE(key_datum) = klen;
 return EXIM_DBDEL(dbblock->dbptr, key_datum);
 }


diff --git a/src/src/expand.c b/src/src/expand.c
index 9f430f8..1f0c5cb 100644
--- a/src/src/expand.c
+++ b/src/src/expand.c
@@ -13,8 +13,8 @@

/* Recursively called function */

-static uschar *expand_string_internal(uschar *, BOOL, uschar **, BOOL, BOOL, BOOL *);
-static int_eximarith_t expanded_string_integer(uschar *, BOOL);
+static uschar *expand_string_internal(const uschar *, BOOL, const uschar **, BOOL, BOOL, BOOL *);
+static int_eximarith_t expanded_string_integer(const uschar *, BOOL);

#ifdef STAND_ALONE
#ifndef SUPPORT_CRYPTEQ
@@ -975,8 +975,8 @@ Note: The test for *s != 0 in the while loop is necessary because
Ustrchr() yields non-NULL if the character is zero (which is not something
I expected). */

-static uschar *
-read_name(uschar *name, int max, uschar *s, uschar *extras)
+static const uschar *
+read_name(uschar *name, int max, const uschar *s, uschar *extras)
 {
 int ptr = 0;
 while (*s != 0 && (isalnum(*s) || Ustrchr(extras, *s) != NULL))
@@ -1009,8 +1009,8 @@ Arguments:
 Returns:    a pointer to the first character after the header name
 */


-static uschar *
-read_header_name(uschar *name, int max, uschar *s)
+static const uschar *
+read_header_name(uschar *name, int max, const uschar *s)
{
int prelen = Ustrchr(name, '_') - name + 1;
int ptr = Ustrlen(name) - prelen;
@@ -1047,6 +1047,14 @@ while (isdigit(*s)) *n = *n * 10 + (*s++ - '0');
return s;
}

+static const uschar *
+read_cnumber(int *n, const uschar *s)
+{
+*n = 0;
+while (isdigit(*s)) *n = *n * 10 + (*s++ - '0');
+return s;
+}
+


 /*************************************************
@@ -1064,7 +1072,7 @@ Returns:    NULL if the subfield was not found, or
 */


static uschar *
-expand_getkeyed(uschar *key, uschar *s)
+expand_getkeyed(uschar *key, const uschar *s)
{
int length = Ustrlen(key);
while (isspace(*s)) s++;
@@ -1075,7 +1083,7 @@ while (*s != 0)
{
int dkeylength;
uschar *data;
- uschar *dkey = s;
+ const uschar *dkey = s;

while (*s != 0 && *s != '=' && !isspace(*s)) s++;
dkeylength = s - dkey;
@@ -1186,9 +1194,9 @@ return fieldtext;


static uschar *
-expand_getlistele(int field, uschar * list)
+expand_getlistele(int field, const uschar * list)
{
-uschar * tlist= list;
+const uschar * tlist= list;
int sep= 0;
uschar dummy;

@@ -1938,11 +1946,11 @@ Returns:     0 OK; string pointer updated
 */


static int
-read_subs(uschar **sub, int n, int m, uschar **sptr, BOOL skipping,
+read_subs(uschar **sub, int n, int m, const uschar **sptr, BOOL skipping,
BOOL check_end, uschar *name, BOOL *resetok)
{
int i;
-uschar *s = *sptr;
+const uschar *s = *sptr;

 while (isspace(*s)) s++;
 for (i = 0; i < n; i++)
@@ -2074,8 +2082,8 @@ Returns:   a pointer to the first character after the condition, or
            NULL after an error
 */


-static uschar *
-eval_condition(uschar *s, BOOL *resetok, BOOL *yield)
+static const uschar *
+eval_condition(const uschar *s, BOOL *resetok, BOOL *yield)
{
BOOL testfor = TRUE;
BOOL tempcond, combined_cond;
@@ -2085,7 +2093,7 @@ int i, rc, cond_type, roffset;
int_eximarith_t num[2];
struct stat statbuf;
uschar name[256];
-uschar *sub[10];
+const uschar *sub[10];

 const pcre *re;
 const uschar *rerror;
@@ -2305,6 +2313,7 @@ switch(cond_type)
   case ECOND_ACL:
     /* ${if acl {{name}{arg1}{arg2}...}  {yes}{no}} */
     {
+    uschar *sub[10];
     uschar *user_msg;
     BOOL cond = FALSE;
     int size = 0;
@@ -2755,6 +2764,7 @@ switch(cond_type)
     case ECOND_INLIST:
     case ECOND_INLISTI:
       {
+      const uschar * list = sub[1];
       int sep = 0;
       uschar *save_iterate_item = iterate_item;
       int (*compare)(const uschar *, const uschar *);
@@ -2762,12 +2772,10 @@ switch(cond_type)
       DEBUG(D_expand) debug_printf("condition: %s\n", name);


       tempcond = FALSE;
-      if (cond_type == ECOND_INLISTI)
-        compare = strcmpic;
-      else
-        compare = (int (*)(const uschar *, const uschar *)) strcmp;
+      compare = cond_type == ECOND_INLISTI
+        ? strcmpic : (int (*)(const uschar *, const uschar *)) strcmp;


-      while ((iterate_item = string_nextinlist(&sub[1], &sep, NULL, 0)) != NULL)
+      while ((iterate_item = string_nextinlist(&list, &sep, NULL, 0)))
         if (compare(sub[0], iterate_item) == 0)
           {
           tempcond = TRUE;
@@ -2845,6 +2853,7 @@ switch(cond_type)
   case ECOND_FORALL:
   case ECOND_FORANY:
     {
+    const uschar * list;
     int sep = 0;
     uschar *save_iterate_item = iterate_item;


@@ -2884,7 +2893,8 @@ switch(cond_type)
       }


     if (yield != NULL) *yield = !testfor;
-    while ((iterate_item = string_nextinlist(&sub[0], &sep, NULL, 0)) != NULL)
+    list = sub[0];
+    while ((iterate_item = string_nextinlist(&list, &sep, NULL, 0)) != NULL)
       {
       DEBUG(D_expand) debug_printf("%s: $item = \"%s\"\n", name, iterate_item);
       if (!eval_condition(sub[1], resetok, &tempcond))
@@ -3102,11 +3112,11 @@ Returns:         0 OK; lookup_value has been reset to save_lookup
 */


 static int
-process_yesno(BOOL skipping, BOOL yes, uschar *save_lookup, uschar **sptr,
+process_yesno(BOOL skipping, BOOL yes, uschar *save_lookup, const uschar **sptr,
   uschar **yieldptr, int *sizeptr, int *ptrptr, uschar *type, BOOL *resetok)
 {
 int rc = 0;
-uschar *s = *sptr;    /* Local value */
+const uschar *s = *sptr;    /* Local value */
 uschar *sub1, *sub2;


 /* If there are no following strings, we substitute the contents of $value for
@@ -3184,7 +3194,8 @@ inside another lookup or if or extract. */
 else if (*s != '}')
   {
   uschar name[256];
-  s = read_name(name, sizeof(name), s, US"_");
+  /* deconst cast ok here as source is s anyway */
+  s = US read_name(name, sizeof(name), s, US"_");
   if (Ustrcmp(name, "fail") == 0)
     {
     if (!yes && !skipping)
@@ -3753,14 +3764,14 @@ Returns:         NULL if expansion fails:
 */


static uschar *
-expand_string_internal(uschar *string, BOOL ket_ends, uschar **left,
+expand_string_internal(const uschar *string, BOOL ket_ends, const uschar **left,
BOOL skipping, BOOL honour_dollar, BOOL *resetok_p)
{
int ptr = 0;
int size = Ustrlen(string)+ 64;
int item_type;
uschar *yield = store_get(size);
-uschar *s = string;
+const uschar *s = string;
uschar *save_expand_nstring[EXPAND_MAXN+1];
int save_expand_nlength[EXPAND_MAXN+1];
BOOL resetok = TRUE;
@@ -3788,7 +3799,7 @@ while (*s != 0)

     if (s[1] == 'N')
       {
-      uschar *t = s + 2;
+      const uschar * t = s + 2;
       for (s = t; *s != 0; s++) if (*s == '\\' && s[1] == 'N') break;
       yield = string_cat(yield, &size, &ptr, t, s - t);
       if (*s != 0) s += 2;
@@ -3904,7 +3915,7 @@ while (*s != 0)
   if (isdigit(*s))
     {
     int n;
-    s = read_number(&n, s);
+    s = read_cnumber(&n, s);
     if (n >= 0 && n <= expand_nmax)
       yield = string_cat(yield, &size, &ptr, expand_nstring[n],
         expand_nlength[n]);
@@ -3925,7 +3936,7 @@ while (*s != 0)
   if (isdigit((*(++s))))
     {
     int n;
-    s = read_number(&n, s);        /*{*/
+    s = read_cnumber(&n, s);        /*{*/
     if (*s++ != '}')
       {                    /*{*/
       expand_string_message = US"} expected after number";
@@ -4002,7 +4013,7 @@ while (*s != 0)
     case EITEM_IF:
       {
       BOOL cond = FALSE;
-      uschar *next_s;
+      const uschar *next_s;
       int save_expand_nmax =
         save_expand_strings(save_expand_nstring, save_expand_nlength);


@@ -4054,7 +4065,8 @@ while (*s != 0)
       int stype, partial, affixlen, starflags;
       int expand_setup = 0;
       int nameptr = 0;
-      uschar *key, *filename, *affix;
+      uschar *key, *filename;
+      const uschar *affix;
       uschar *save_lookup_value = lookup_value;
       int save_expand_nmax =
         save_expand_strings(save_expand_nstring, save_expand_nlength);
@@ -4772,7 +4784,7 @@ while (*s != 0)
       {
       FILE *f;
       uschar *arg;
-      uschar **argv;
+      const uschar **argv;
       pid_t pid;
       int fd_in, fd_out;
       int lsize = 0;
@@ -4810,7 +4822,7 @@ while (*s != 0)


         /* Create the child process, making it a group leader. */


-        pid = child_open(argv, NULL, 0077, &fd_in, &fd_out, TRUE);
+        pid = child_open(USS argv, NULL, 0077, &fd_in, &fd_out, TRUE);


         if (pid < 0)
           {
@@ -5472,7 +5484,7 @@ while (*s != 0)
       int sep = 0;
       int save_ptr = ptr;
       uschar outsep[2] = { '\0', '\0' };
-      uschar *list, *expr, *temp;
+      const uschar *list, *expr, *temp;
       uschar *save_iterate_item = iterate_item;
       uschar *save_lookup_value = lookup_value;


@@ -5485,11 +5497,12 @@ while (*s != 0)

       if (item_type == EITEM_REDUCE)
         {
+    uschar * t;
         while (isspace(*s)) s++;
         if (*s++ != '{') goto EXPAND_FAILED_CURLY;
-        temp = expand_string_internal(s, TRUE, &s, skipping, TRUE, &resetok);
+        t = expand_string_internal(s, TRUE, &s, skipping, TRUE, &resetok);
         if (temp == NULL) goto EXPAND_FAILED;
-        lookup_value = temp;
+        lookup_value = t;
         if (*s++ != '}') goto EXPAND_FAILED_CURLY;
         }


@@ -5510,9 +5523,7 @@ while (*s != 0)
         if (temp != NULL) s = temp;
         }
       else
-        {
         temp = expand_string_internal(s, TRUE, &s, TRUE, TRUE, &resetok);
-        }


       if (temp == NULL)
         {
@@ -5570,7 +5581,8 @@ while (*s != 0)


         else
           {
-          temp = expand_string_internal(expr, TRUE, NULL, skipping, TRUE, &resetok);
+      uschar * t = expand_string_internal(expr, TRUE, NULL, skipping, TRUE, &resetok);
+          temp = t;
           if (temp == NULL)
             {
             iterate_item = save_iterate_item;
@@ -5580,7 +5592,7 @@ while (*s != 0)
             }
           if (item_type == EITEM_REDUCE)
             {
-            lookup_value = temp;      /* Update the value of $value */
+            lookup_value = t;         /* Update the value of $value */
             continue;                 /* and continue the iteration */
             }
           }
@@ -5643,10 +5655,9 @@ while (*s != 0)
     case EITEM_SORT:
       {
       int sep = 0;
-      uschar *srclist, *cmp, *xtract;
+      const uschar *srclist, *cmp, *xtract;
       uschar *srcitem;
-      uschar *dstlist = NULL;
-      uschar *dstkeylist = NULL;
+      const uschar *dstlist = NULL, *dstkeylist = NULL;
       uschar * tmp;
       uschar *save_iterate_item = iterate_item;


@@ -5920,7 +5931,7 @@ while (*s != 0)
       case EOP_SHA256:
     if (s[1] == '$')
       {
-      uschar * s1 = s;
+      const uschar * s1 = s;
       sub = expand_string_internal(s+2, TRUE, &s1, skipping,
           FALSE, &resetok);
       if (!sub)       goto EXPAND_FAILED;        /*{*/
@@ -6151,7 +6162,7 @@ while (*s != 0)
     uschar * cp;
     uschar buffer[256];


-    while (string_nextinlist(&sub, &sep, buffer, sizeof(buffer)) != NULL) cnt++;
+    while (string_nextinlist(CUSS &sub, &sep, buffer, sizeof(buffer)) != NULL) cnt++;
     cp = string_sprintf("%d", cnt);
         yield = string_cat(yield, &size, &ptr, cp, Ustrlen(cp));
         continue;
@@ -6163,7 +6174,7 @@ while (*s != 0)
       case EOP_LISTNAMED:
     {
     tree_node *t = NULL;
-    uschar * list;
+    const uschar * list;
     int sep = 0;
     uschar * item;
     uschar * suffix = US"";
@@ -6482,7 +6493,7 @@ while (*s != 0)
       case EOP_RFC2047:
         {
         uschar buffer[2048];
-        uschar *string = parse_quote_2047(sub, Ustrlen(sub), headers_charset,
+    const uschar *string = parse_quote_2047(sub, Ustrlen(sub), headers_charset,
           buffer, sizeof(buffer), FALSE);
         yield = string_cat(yield, &size, &ptr, string, Ustrlen(string));
         continue;
@@ -6612,7 +6623,7 @@ while (*s != 0)


       case EOP_ESCAPE:
         {
-        uschar *t = string_printing(sub);
+        const uschar *t = string_printing(sub);
         yield = string_cat(yield, &size, &ptr, t, Ustrlen(t));
         continue;
         }
@@ -7000,23 +7011,35 @@ return (Ustrpbrk(string, "$\\") == NULL)? string :




+const uschar *
+expand_cstring(const uschar *string)
+{
+search_find_defer = FALSE;
+malformed_header = FALSE;
+return (Ustrpbrk(string, "$\\") == NULL)? string :
+  expand_string_internal(string, FALSE, NULL, FALSE, TRUE, NULL);
+}
+
+
+
 /*************************************************
 *              Expand and copy                   *
 *************************************************/


/* Now and again we want to expand a string and be sure that the result is in a
new bit of store. This function does that.
+Since we know it has been copied, the de-const cast is safe.

Argument: the string to be expanded
Returns: the expanded string, always in a new bit of store, or NULL
*/

uschar *
-expand_string_copy(uschar *string)
+expand_string_copy(const uschar *string)
{
-uschar *yield = expand_string(string);
+const uschar *yield = expand_cstring(string);
if (yield == string) yield = string_copy(string);
-return yield;
+return US yield;
}


@@ -7063,7 +7086,7 @@ Returns: the integer value, or
*/

 static int_eximarith_t
-expanded_string_integer(uschar *s, BOOL isplus)
+expanded_string_integer(const uschar *s, BOOL isplus)
 {
 int_eximarith_t value;
 uschar *msg = US"invalid integer \"%s\"";
diff --git a/src/src/filter.c b/src/src/filter.c
index 7132d22..9ee7acb 100644
--- a/src/src/filter.c
+++ b/src/src/filter.c
@@ -355,7 +355,7 @@ while (*(++ptr) != 0 && *ptr != '\"' && *ptr != '\n')
         }
       }


-    *bp++ = string_interpret_escape(&ptr);
+    *bp++ = string_interpret_escape(CUSS &ptr);
     }
   }


@@ -2021,7 +2021,7 @@ while (commands != NULL)
         {
         int sep = 0;
         uschar *ss;
-        uschar *list = s;
+        const uschar *list = s;
         uschar buffer[128];
         while ((ss = string_nextinlist(&list, &sep, buffer, sizeof(buffer)))
                != NULL)
@@ -2057,7 +2057,7 @@ while (commands != NULL)
     DEFERFREEZEFAIL:
     fmsg = expargs[0];
     if (Ustrlen(fmsg) > 1024) Ustrcpy(fmsg + 1000, " ... (truncated)");
-    fmsg = string_printing(fmsg);
+    fmsg = US string_printing(fmsg);
     *error_pointer = fmsg;


     if (filter_test != FTEST_NONE)
@@ -2351,7 +2351,7 @@ while (commands != NULL)
     case testprint_command:
     if (filter_test != FTEST_NONE || (debug_selector & D_filter) != 0)
       {
-      uschar *s = string_printing(expargs[0]);
+      const uschar *s = string_printing(expargs[0]);
       if (filter_test == FTEST_NONE)
         debug_printf("Filter: testprint: %s\n", s);
       else
diff --git a/src/src/functions.h b/src/src/functions.h
index 3d8c2b9..95720c0 100644
--- a/src/src/functions.h
+++ b/src/src/functions.h
@@ -66,8 +66,8 @@ extern void    tls_version_report(FILE *);
 # ifndef USE_GNUTLS
 extern BOOL    tls_openssl_options_parse(uschar *, long *);
 # endif
-extern uschar * tls_field_from_dn(uschar *, uschar *);
-extern BOOL    tls_is_name_for_cert(uschar *, void *);
+extern uschar * tls_field_from_dn(uschar *, const uschar *);
+extern BOOL    tls_is_name_for_cert(const uschar *, void *);


 # ifdef EXPERIMENTAL_DANE
 extern int     tlsa_lookup(const host_item *, dns_answer *, BOOL, BOOL *);
@@ -100,10 +100,10 @@ extern uschar *auth_xtextencode(uschar *, int);
 extern int     auth_xtextdecode(uschar *, uschar **);


 extern void    cancel_cutthrough_connection(const char *);
-extern int     check_host(void *, uschar *, uschar **, uschar **);
+extern int     check_host(void *, const uschar *, const uschar **, uschar **);
 extern uschar **child_exec_exim(int, BOOL, int *, BOOL, int, ...);
-extern pid_t   child_open_uid(uschar **, uschar **, int, uid_t *, gid_t *,
-                 int *, int *, uschar *, BOOL);
+extern pid_t   child_open_uid(const uschar **, const uschar **, int,
+         uid_t *, gid_t *, int *, int *, uschar *, BOOL);
 extern uschar *cutthrough_finaldot(void);
 extern BOOL    cutthrough_flush_send(void);
 extern BOOL    cutthrough_headers_send(void);
@@ -118,7 +118,7 @@ extern int     dcc_process(uschar **);
 #endif


 extern void    debug_logging_activate(uschar *, uschar *);
-extern void    debug_print_argv(uschar **);
+extern void    debug_print_argv(const uschar **);
 extern void    debug_print_ids(uschar *);
 extern void    debug_print_string(uschar *);
 extern void    debug_print_tree(tree_node *);
@@ -144,12 +144,12 @@ extern BOOL    dkim_transport_write_message(address_item *, int, int,
 #endif
 extern dns_address *dns_address_from_rr(dns_answer *, dns_record *);
 extern int     dns_basic_lookup(dns_answer *, const uschar *, int);
-extern void    dns_build_reverse(uschar *, uschar *);
+extern void    dns_build_reverse(const uschar *, uschar *);
 extern void    dns_init(BOOL, BOOL, BOOL);
 extern BOOL    dns_is_secure(const dns_answer *);
-extern int     dns_lookup(dns_answer *, const uschar *, int, uschar **);
+extern int     dns_lookup(dns_answer *, const uschar *, int, const uschar **);
 extern void    dns_pattern_init(void);
-extern int     dns_special_lookup(dns_answer *, const uschar *, int, uschar **);
+extern int     dns_special_lookup(dns_answer *, const uschar *, int, const uschar **);
 extern dns_record *dns_next_rr(dns_answer *, dns_scan *, int);
 extern uschar *dns_text_type(int);
 extern void    dscp_list_to_stream(FILE *);
@@ -158,7 +158,7 @@ extern BOOL    dscp_lookup(const uschar *, int, int *, int *, int *);
 extern void    enq_end(uschar *);
 extern BOOL    enq_start(uschar *);
 #ifdef EXPERIMENTAL_EVENT
-extern uschar *event_raise(uschar *, uschar *, uschar *);
+extern uschar *event_raise(uschar *, const uschar *, uschar *);
 #endif
 extern void    exim_exit(int);
 extern void    exim_nullstd(void);
@@ -170,7 +170,8 @@ extern int     exp_bool(address_item *addr,
   uschar *svalue, BOOL *rvalue);
 extern BOOL    expand_check_condition(uschar *, uschar *, uschar *);
 extern uschar *expand_string(uschar *);
-extern uschar *expand_string_copy(uschar *);
+extern const uschar *expand_cstring(const uschar *);
+extern uschar *expand_string_copy(const uschar *);
 extern int_eximarith_t expand_string_integer(uschar *, BOOL);
 extern void    modify_variable(uschar *, void *);


@@ -188,16 +189,16 @@ extern int     header_checkname(header_line *, BOOL);
 extern BOOL    header_match(uschar *, BOOL, BOOL, string_item *, int, ...);
 extern int     host_address_extract_port(uschar *);
 extern uschar *host_and_ident(BOOL);
-extern int     host_aton(uschar *, int *);
-extern void    host_build_hostlist(host_item **, uschar *, BOOL);
-extern ip_address_item *host_build_ifacelist(uschar *, uschar *);
+extern int     host_aton(const uschar *, int *);
+extern void    host_build_hostlist(host_item **, const uschar *, BOOL);
+extern ip_address_item *host_build_ifacelist(const uschar *, uschar *);
 extern void    host_build_log_info(void);
 extern void    host_build_sender_fullhost(void);
-extern BOOL    host_find_byname(host_item *, uschar *, int, uschar **, BOOL);
-extern int     host_find_bydns(host_item *, uschar *, int, uschar *, uschar *,
-                 uschar *, uschar *, uschar *, uschar **, BOOL *);
+extern BOOL    host_find_byname(host_item *, const uschar *, int, const uschar **, BOOL);
+extern int     host_find_bydns(host_item *, const uschar *, int, uschar *, uschar *,
+                 uschar *, uschar *, uschar *, const uschar **, BOOL *);
 extern ip_address_item *host_find_interfaces(void);
-extern BOOL    host_is_in_net(uschar *, uschar *, int);
+extern BOOL    host_is_in_net(const uschar *, const uschar *, int);
 extern BOOL    host_is_tls_on_connect_port(int);
 extern int     host_item_get_port(host_item *);
 extern void    host_mask(int, int *, int);
@@ -212,7 +213,7 @@ extern int     ip_connect(int, int, const uschar *, int, int);
 extern int     ip_connectedsocket(int, const uschar *, int, int,
                  int, host_item *, uschar **);
 extern int     ip_get_address_family(int);
-extern void    ip_keepalive(int, uschar *, BOOL);
+extern void    ip_keepalive(int, const uschar *, BOOL);
 extern int     ip_recv(int, uschar *, int, int);
 extern int     ip_socket(int, int);


@@ -230,15 +231,15 @@ extern int     malware(const uschar *, int);
 extern int     malware_in_file(uschar *);
 extern void    malware_init(void);
 #endif
-extern int     match_address_list(uschar *, BOOL, BOOL, uschar **,
-                 unsigned int *, int, int, uschar **);
-extern int     match_check_list(uschar **, int, tree_node **, unsigned int **,
-                 int(*)(void *, uschar *, uschar **, uschar **), void *, int,
-                 const uschar *, uschar **);
-extern int     match_isinlist(const uschar *, uschar **, int, tree_node **,
-                 unsigned int *, int, BOOL, uschar **);
-extern int     match_check_string(uschar *, uschar *, int, BOOL, BOOL, BOOL,
-                 uschar **);
+extern int     match_address_list(const uschar *, BOOL, BOOL, const uschar **,
+                 unsigned int *, int, int, const uschar **);
+extern int     match_check_list(const uschar **, int, tree_node **, unsigned int **,
+                 int(*)(void *, const uschar *, const uschar **, uschar **), void *, int,
+                 const uschar *, const uschar **);
+extern int     match_isinlist(const uschar *, const uschar **, int, tree_node **,
+                 unsigned int *, int, BOOL, const uschar **);
+extern int     match_check_string(const uschar *, const uschar *, int, BOOL, BOOL, BOOL,
+                 const uschar **);
 extern void    md5_end(md5 *, const uschar *, int, uschar *);
 extern void    md5_mid(md5 *, const uschar *);
 extern void    md5_start(md5 *);
@@ -247,8 +248,8 @@ extern void    millisleep(int);
 struct mime_boundary_context;
 extern int     mime_acl_check(uschar *acl, FILE *f,
                  struct mime_boundary_context *, uschar **, uschar **);
-extern int     mime_decode(uschar **);
-extern int     mime_regex(uschar **);
+extern int     mime_decode(const uschar **);
+extern int     mime_regex(const uschar **);
 #endif
 extern uschar *moan_check_errorcopy(uschar *);
 extern BOOL    moan_skipped_syntax_errors(uschar *, error_block *, uschar *,
@@ -265,12 +266,12 @@ extern void   open_cutthrough_connection( address_item * addr );
 extern uschar *parse_extract_address(uschar *, uschar **, int *, int *, int *,
                  BOOL);
 extern int     parse_forward_list(uschar *, int, address_item **, uschar **,
-                 uschar *, uschar *, error_block **);
+                 const uschar *, uschar *, error_block **);
 extern uschar *parse_find_address_end(uschar *, BOOL);
 extern uschar *parse_find_at(uschar *);
-extern uschar *parse_fix_phrase(uschar *, int, uschar *, int);
+extern const uschar *parse_fix_phrase(const uschar *, int, uschar *, int);
 extern uschar *parse_message_id(uschar *, uschar **, uschar **);
-extern uschar *parse_quote_2047(uschar *, int, uschar *, uschar *, int, BOOL);
+extern const uschar *parse_quote_2047(const uschar *, int, uschar *, uschar *, int, BOOL);
 extern uschar *parse_date_time(uschar *str, time_t *t);
 extern int     vaguely_random_number(int);
 #ifdef SUPPORT_TLS
@@ -298,7 +299,7 @@ extern uschar *readconf_printtime(int);
 extern uschar *readconf_readname(uschar *, int, uschar *);
 extern int     readconf_readtime(const uschar *, int, BOOL);
 extern void    readconf_rest();
-extern uschar *readconf_retry_error(uschar *, uschar *, int *, int *);
+extern uschar *readconf_retry_error(const uschar *, const uschar *, int *, int *);
 extern void    read_message_body(BOOL);
 extern void    receive_bomb_out(uschar *, uschar *);
 extern BOOL    receive_check_fs(int);
@@ -307,20 +308,21 @@ extern BOOL    receive_msg(BOOL);
 extern int     receive_statvfs(BOOL, int *);
 extern void    receive_swallow_smtp(void);
 #ifdef WITH_CONTENT_SCAN
-extern int     regex(uschar **);
+extern int     regex(const uschar **);
 #endif
 extern BOOL    regex_match_and_setup(const pcre *, const uschar *, int, int);
 extern const pcre *regex_must_compile(const uschar *, BOOL, BOOL);
 extern void    retry_add_item(address_item *, uschar *, int);
-extern BOOL    retry_check_address(uschar *, host_item *, uschar *, BOOL,
+extern BOOL    retry_check_address(const uschar *, host_item *, uschar *, BOOL,
                  uschar **, uschar **);
-extern retry_config *retry_find_config(uschar *, uschar *, int, int);
-extern BOOL    retry_ultimate_address_timeout(uschar *, uschar *,
+extern retry_config *retry_find_config(const uschar *, const uschar *, int, int);
+extern BOOL    retry_ultimate_address_timeout(uschar *, const uschar *,
                  dbdata_retry *, time_t);
 extern void    retry_update(address_item **, address_item **, address_item **);
 extern uschar *rewrite_address(uschar *, BOOL, BOOL, rewrite_rule *, int);
 extern uschar *rewrite_address_qualify(uschar *, BOOL);
-extern header_line *rewrite_header(header_line *, uschar *, uschar *,
+extern header_line *rewrite_header(header_line *,
+               const uschar *, const uschar *,
                rewrite_rule *, int, BOOL);
 extern uschar *rewrite_one(uschar *, int, BOOL *, BOOL, uschar *,
                  rewrite_rule *);
@@ -329,10 +331,10 @@ extern uschar *rfc2047_decode2(uschar *, BOOL, uschar *, int, int *, int *,
                  uschar **);
 extern int     route_address(address_item *, address_item **, address_item **,
                  address_item **, address_item **, int);
-extern int     route_check_prefix(uschar *, uschar *);
-extern int     route_check_suffix(uschar *, uschar *);
+extern int     route_check_prefix(const uschar *, const uschar *);
+extern int     route_check_suffix(const uschar *, const uschar *);
 extern BOOL    route_findgroup(uschar *, gid_t *);
-extern BOOL    route_finduser(uschar *, struct passwd **, uid_t *);
+extern BOOL    route_finduser(const uschar *, struct passwd **, uid_t *);
 extern BOOL    route_find_expanded_group(uschar *, uschar *, uschar *, gid_t *,
                  uschar **);
 extern BOOL    route_find_expanded_user(uschar *, uschar *, uschar *,
@@ -340,10 +342,10 @@ extern BOOL    route_find_expanded_user(uschar *, uschar *, uschar *,
 extern void    route_init(void);
 extern void    route_tidyup(void);


-extern uschar *search_find(void *, uschar *, uschar *, int, uschar *, int,
+extern uschar *search_find(void *, uschar *, uschar *, int, const uschar *, int,
                  int, int *);
-extern int     search_findtype(uschar *, int);
-extern int     search_findtype_partial(uschar *, int *, uschar **, int *,
+extern int     search_findtype(const uschar *, int);
+extern int     search_findtype_partial(const uschar *, int *, const uschar **, int *,
                  int *);
 extern void   *search_open(uschar *, int, int, uid_t *, gid_t *);
 extern void    search_tidyup(void);
@@ -381,7 +383,7 @@ extern int     smtp_ungetc(int);
 extern BOOL    smtp_verify_helo(void);
 extern int     smtp_write_command(smtp_outblock *, BOOL, const char *, ...) PRINTF_FUNCTION(3,4);
 #ifdef WITH_CONTENT_SCAN
-extern int     spam(uschar **);
+extern int     spam(const uschar **);
 extern FILE   *spool_mbox(unsigned long *, const uschar *);
 #endif
 extern BOOL    spool_move_message(uschar *, uschar *, uschar *, uschar *);
@@ -399,18 +401,18 @@ extern uschar *string_append_listele_n(uschar *, uschar, const uschar *, unsigne
 extern uschar *string_base62(unsigned long int);
 extern uschar *string_cat(uschar *, int *, int *, const uschar *, int);
 extern uschar *string_copy_dnsdomain(uschar *);
-extern uschar *string_copy_malloc(uschar *);
+extern uschar *string_copy_malloc(const uschar *);
 extern uschar *string_copylc(const uschar *);
 extern uschar *string_copynlc(uschar *, int);
-extern uschar *string_dequote(uschar **);
+extern uschar *string_dequote(const uschar **);
 extern BOOL    string_format(uschar *, int, const char *, ...) ALMOST_PRINTF(3,4);
 extern uschar *string_format_size(int, uschar *);
-extern int     string_interpret_escape(uschar **);
+extern int     string_interpret_escape(const uschar **);
 extern int     string_is_ip_address(const uschar *, int *);
 extern uschar *string_log_address(address_item *, BOOL, BOOL);
-extern uschar *string_nextinlist(uschar **, int *, uschar *, int);
+extern uschar *string_nextinlist(const uschar **, int *, uschar *, int);
 extern uschar *string_open_failed(int, const char *, ...) PRINTF_FUNCTION(2,3);
-extern uschar *string_printing2(uschar *, BOOL);
+extern const uschar *string_printing2(const uschar *, BOOL);
 extern uschar *string_split_message(uschar *);
 extern uschar *string_unprinting(uschar *);
 extern BOOL    string_vformat(uschar *, int, const char *, va_list);
@@ -421,14 +423,14 @@ extern uschar *strstric(uschar *, uschar *, BOOL);
 extern uschar *tod_stamp(int);


 extern void    tls_modify_variables(tls_support *);
-extern BOOL    transport_check_waiting(uschar *, uschar *, int, uschar *,
+extern BOOL    transport_check_waiting(const uschar *, const uschar *, int, uschar *,
                  BOOL *);
 extern void    transport_init(void);
-extern BOOL    transport_pass_socket(uschar *, uschar *, uschar *, uschar *,
+extern BOOL    transport_pass_socket(const uschar *, const uschar *, const uschar *, uschar *,
                  int);
 extern uschar *transport_rcpt_address(address_item *, BOOL);
-extern BOOL    transport_set_up_command(uschar ***, uschar *, BOOL, int,
-                 address_item *, uschar *, uschar **);
+extern BOOL    transport_set_up_command(const uschar ***, uschar *,
+         BOOL, int, address_item *, uschar *, uschar **);
 extern void    transport_update_waiting(host_item *, uschar *);
 extern BOOL    transport_write_block(int, uschar *, int);
 extern BOOL    transport_write_string(int, const char *, ...);
@@ -440,7 +442,7 @@ extern void    tree_add_duplicate(uschar *, address_item *);
 extern void    tree_add_nonrecipient(uschar *);
 extern void    tree_add_unusable(host_item *);
 extern int     tree_insertnode(tree_node **, tree_node *);
-extern tree_node *tree_search(tree_node *, uschar *);
+extern tree_node *tree_search(tree_node *, const uschar *);
 extern void    tree_write(tree_node *, FILE *);
 extern void    tree_walk(tree_node *, void (*)(uschar*, uschar*, void*), void *);


@@ -450,7 +452,7 @@ extern void    unspool_mbox(void);


 extern int     verify_address(address_item *, FILE *, int, int, int, int,
                  uschar *, uschar *, BOOL *);
-extern int     verify_check_dnsbl(uschar **);
+extern int     verify_check_dnsbl(const uschar **);
 extern int     verify_check_header_address(uschar **, uschar **, int, int, int,
                  uschar *, uschar *, int, int *);
 extern int     verify_check_headers(uschar **);
@@ -458,8 +460,8 @@ extern int     verify_check_header_names_ascii(uschar **);
 extern int     verify_check_host(uschar **);
 extern int     verify_check_notblind(void);
 extern int     verify_check_given_host(uschar **, host_item *);
-extern int     verify_check_this_host(uschar **, unsigned int *, uschar*,
-                 uschar *, uschar **);
+extern int     verify_check_this_host(const uschar **, unsigned int *,
+             const uschar*, const uschar *, const uschar **);
 extern address_item *verify_checked_sender(uschar *);
 extern void    verify_get_ident(int);
 extern BOOL    verify_sender(int *, uschar **);
diff --git a/src/src/globals.c b/src/src/globals.c
index 6d7ea33..b68ed7e 100644
--- a/src/src/globals.c
+++ b/src/src/globals.c
@@ -192,24 +192,24 @@ BOOL (*receive_smtp_buffered)(void) = NULL;   /* Only used for SMTP */
 when verifying one address while routing/verifying another. We have to have
 the size explicit, because it is referenced from more than one module. */


-uschar **address_expansions[ADDRESS_EXPANSIONS_COUNT] = {
- &deliver_address_data,
- &deliver_domain,
- &deliver_domain_data,
- &deliver_domain_orig,
- &deliver_domain_parent,
- &deliver_localpart,
- &deliver_localpart_data,
- &deliver_localpart_orig,
- &deliver_localpart_parent,
- &deliver_localpart_prefix,
- &deliver_localpart_suffix,
- (uschar **)(&deliver_recipients),
- &deliver_host,
- &deliver_home,
- &address_file,
- &address_pipe,
- &self_hostname,
+const uschar **address_expansions[ADDRESS_EXPANSIONS_COUNT] = {
+ CUSS &deliver_address_data,
+ CUSS &deliver_domain,
+ CUSS &deliver_domain_data,
+ CUSS &deliver_domain_orig,
+ CUSS &deliver_domain_parent,
+ CUSS &deliver_localpart,
+ CUSS &deliver_localpart_data,
+ CUSS &deliver_localpart_orig,
+ CUSS &deliver_localpart_parent,
+ CUSS &deliver_localpart_prefix,
+ CUSS &deliver_localpart_suffix,
+ CUSS (uschar **)(&deliver_recipients),
+ CUSS &deliver_host,
+ CUSS &deliver_home,
+ CUSS &address_file,
+ CUSS &address_pipe,
+ CUSS &self_hostname,
NULL };

 int address_expansions_count = sizeof(address_expansions)/sizeof(uschar **);
@@ -573,18 +573,18 @@ uschar *delay_warning_condition=
 BOOL    delivery_date_remove   = TRUE;
 uschar *deliver_address_data   = NULL;
 int     deliver_datafile       = -1;
-uschar *deliver_domain         = NULL;
+const uschar *deliver_domain   = NULL;
 uschar *deliver_domain_data    = NULL;
-uschar *deliver_domain_orig    = NULL;
-uschar *deliver_domain_parent  = NULL;
+const uschar *deliver_domain_orig = NULL;
+const uschar *deliver_domain_parent = NULL;
 BOOL    deliver_drop_privilege = FALSE;
 BOOL    deliver_firsttime      = FALSE;
 BOOL    deliver_force          = FALSE;
 BOOL    deliver_freeze         = FALSE;
 time_t  deliver_frozen_at      = 0;
 uschar *deliver_home           = NULL;
-uschar *deliver_host           = NULL;
-uschar *deliver_host_address   = NULL;
+const uschar *deliver_host     = NULL;
+const uschar *deliver_host_address = NULL;
 int     deliver_host_port      = 0;
 uschar *deliver_in_buffer      = NULL;
 ino_t   deliver_inode          = 0;
@@ -672,7 +672,7 @@ int     errors_sender_rc       = EXIT_FAILURE;
 uschar *event_action             = NULL;    /* expansion for delivery events */
 uschar *event_data               = NULL;    /* auxilary data variable for event */
 int     event_defer_errno        = 0;
-uschar *event_name               = NULL;    /* event name variable */
+const uschar *event_name         = NULL;    /* event name variable */
 #endif



@@ -975,7 +975,7 @@ uschar *prvscheck_keynum       = NULL;
 uschar *prvscheck_result       = NULL;



-uschar *qualify_domain_recipient = NULL;
+const uschar *qualify_domain_recipient = NULL;
 uschar *qualify_domain_sender  = NULL;
 BOOL    queue_2stage           = FALSE;
 uschar *queue_domains          = NULL;
@@ -1404,7 +1404,7 @@ transport_instance  transport_defaults = {
 int     transport_count;
 uschar *transport_name          = NULL;
 int     transport_newlines;
-uschar **transport_filter_argv  = NULL;
+const uschar **transport_filter_argv  = NULL;
 int     transport_filter_timeout;
 BOOL    transport_filter_timed_out = FALSE;
 int     transport_write_timeout= 0;
diff --git a/src/src/globals.h b/src/src/globals.h
index 98d589f..5c00220 100644
--- a/src/src/globals.h
+++ b/src/src/globals.h
@@ -150,7 +150,7 @@ extern BOOL (*receive_smtp_buffered)(void);
 the size of this vector set explicitly, because it is referenced from more than
 one module. */


-extern uschar **address_expansions[ADDRESS_EXPANSIONS_COUNT];
+extern const uschar **address_expansions[ADDRESS_EXPANSIONS_COUNT];

/* General global variables */

@@ -326,19 +326,19 @@ extern BOOL    delivery_date_remove;   /* Remove delivery-date headers */


 extern uschar *deliver_address_data;   /* Arbitrary data for an address */
 extern int     deliver_datafile;       /* FD for data part of message */
-extern uschar *deliver_domain;         /* The local domain for delivery */
+extern const uschar *deliver_domain;   /* The local domain for delivery */
 extern uschar *deliver_domain_data;    /* From domain lookup */
-extern uschar *deliver_domain_orig;    /* The original local domain for delivery */
-extern uschar *deliver_domain_parent;  /* The parent domain for delivery */
+extern const uschar *deliver_domain_orig; /* The original local domain for delivery */
+extern const uschar *deliver_domain_parent; /* The parent domain for delivery */
 extern BOOL    deliver_drop_privilege; /* TRUE for unprivileged delivery */
 extern BOOL    deliver_firsttime;      /* True for first delivery attempt */
 extern BOOL    deliver_force;          /* TRUE if delivery was forced */
 extern BOOL    deliver_freeze;         /* TRUE if delivery is frozen */
 extern time_t  deliver_frozen_at;      /* Time of freezing */
 extern uschar *deliver_home;           /* Home directory for pipes */
-extern uschar *deliver_host;           /* (First) host for routed local deliveries */
+extern const uschar *deliver_host;     /* (First) host for routed local deliveries */
                                        /* Remote host for filter */
-extern uschar *deliver_host_address;   /* Address for remote delivery filter */
+extern const uschar *deliver_host_address; /* Address for remote delivery filter */
 extern int     deliver_host_port;      /* Address for remote delivery filter */
 extern uschar *deliver_in_buffer;      /* Buffer for copying file */
 extern ino_t   deliver_inode;          /* Inode for appendfile */
@@ -430,7 +430,7 @@ extern int     errors_sender_rc;       /* Return after message to sender*/
 extern uschar *event_action;           /* expansion for delivery events */
 extern uschar *event_data;           /* event data */
 extern int     event_defer_errno;      /* error number set when a remote delivery is deferred with a host error */
-extern uschar *event_name;           /* event classification */
+extern const uschar *event_name;       /* event classification */
 #endif


 extern gid_t   exim_gid;               /* To be used with exim_uid */
@@ -648,7 +648,7 @@ extern uschar *prvscheck_address;      /* Set during prvscheck expansion item */
 extern uschar *prvscheck_keynum;       /* Set during prvscheck expansion item */
 extern uschar *prvscheck_result;       /* Set during prvscheck expansion item */


-extern uschar *qualify_domain_recipient; /* Domain to qualify recipients with */
+extern const uschar *qualify_domain_recipient; /* Domain to qualify recipients with */
 extern uschar *qualify_domain_sender;  /* Domain to qualify senders with */
 extern BOOL    queue_2stage;           /* Run queue in 2-stage manner */
 extern uschar *queue_domains;          /* Queue these domains */
@@ -896,7 +896,7 @@ extern BOOL    timestamps_utc;         /* Use UTC for all times */
 extern uschar *transport_name;         /* Name of transport last started */
 extern int     transport_count;        /* Count of bytes transported */
 extern int     transport_newlines;     /* Accurate count of number of newline chars transported */
-extern uschar **transport_filter_argv; /* For on-the-fly filtering */
+extern const uschar **transport_filter_argv; /* For on-the-fly filtering */
 extern int     transport_filter_timeout; /* Timeout for same */
 extern BOOL    transport_filter_timed_out; /* True if it did */


diff --git a/src/src/host.c b/src/src/host.c
index 1ef7327..d40925e 100644
--- a/src/src/host.c
+++ b/src/src/host.c
@@ -118,7 +118,7 @@ Returns:        a hostent structure or NULL for an error
 */


static struct hostent *
-host_fake_gethostbyname(uschar *name, int af, int *error_num)
+host_fake_gethostbyname(const uschar *name, int af, int *error_num)
{
#if HAVE_IPV6
int alen = (af == AF_INET)? sizeof(struct in_addr):sizeof(struct in6_addr);
@@ -127,7 +127,7 @@ int alen = sizeof(struct in_addr);
#endif

 int ipa;
-uschar *lname = name;
+const uschar *lname = name;
 uschar *adds;
 uschar **alist;
 struct hostent *yield;
@@ -295,19 +295,18 @@ Returns:      nothing
 */


 void
-host_build_hostlist(host_item **anchor, uschar *list, BOOL randomize)
+host_build_hostlist(host_item **anchor, const uschar *list, BOOL randomize)
 {
 int sep = 0;
 int fake_mx = MX_NONE;          /* This value is actually -1 */
 uschar *name;
-uschar buffer[1024];


 if (list == NULL) return;
 if (randomize) fake_mx--;       /* Start at -2 for randomizing */


*anchor = NULL;

-while ((name = string_nextinlist(&list, &sep, buffer, sizeof(buffer))) != NULL)
+while ((name = string_nextinlist(&list, &sep, NULL, 0)) != NULL)
{
host_item *h;

@@ -318,7 +317,7 @@ while ((name = string_nextinlist(&list, &sep, buffer, sizeof(buffer))) != NULL)
     }


   h = store_get(sizeof(host_item));
-  h->name = string_copy(name);
+  h->name = name;
   h->address = NULL;
   h->port = PORT_NONE;
   h->mx = fake_mx;
@@ -444,7 +443,7 @@ Returns:    a port number or PORT_NONE
 int
 host_item_get_port(host_item *h)
 {
-uschar *p;
+const uschar *p;
 int port, x;
 int len = Ustrlen(h->name);


@@ -718,7 +717,7 @@ Returns:      a chain of ip_address_items, each containing to a textual
 */


 ip_address_item *
-host_build_ifacelist(uschar *list, uschar *name)
+host_build_ifacelist(const uschar *list, uschar *name)
 {
 int sep = 0;
 uschar *s;
@@ -811,9 +810,9 @@ ip_address_item *running_interfaces = NULL;
 if (local_interface_data == NULL)
   {
   void *reset_item = store_get(0);
-  ip_address_item *dlist = host_build_ifacelist(local_interfaces,
+  ip_address_item *dlist = host_build_ifacelist(CUS local_interfaces,
     US"local_interfaces");
-  ip_address_item *xlist = host_build_ifacelist(extra_local_interfaces,
+  ip_address_item *xlist = host_build_ifacelist(CUS extra_local_interfaces,
     US"extra_local_interfaces");
   ip_address_item *ipa;


@@ -972,7 +971,7 @@ Returns:     the number of ints used
 */


int
-host_aton(uschar *address, int *bin)
+host_aton(const uschar *address, int *bin)
{
int x[4];
int v4offset = 0;
@@ -984,8 +983,8 @@ supported. */

if (Ustrchr(address, ':') != NULL)
{
- uschar *p = address;
- uschar *component[8];
+ const uschar *p = address;
+ const uschar *component[8];
BOOL ipv4_ends = FALSE;
int ci = 0;
int nulloffset = 0;
@@ -1179,7 +1178,7 @@ host_is_tls_on_connect_port(int port)
{
int sep = 0;
uschar buffer[32];
-uschar *list = tls_in.on_connect_ports;
+const uschar *list = tls_in.on_connect_ports;
uschar *s;
uschar *end;

@@ -1214,7 +1213,7 @@ Returns:
*/

 BOOL
-host_is_in_net(uschar *host, uschar *net, int maskoffset)
+host_is_in_net(const uschar *host, const uschar *net, int maskoffset)
 {
 int i;
 int address[4];
@@ -1329,9 +1328,9 @@ for (h = host; h != last->next; h = h->next)
   if (hosts_treat_as_local != NULL)
     {
     int rc;
-    uschar *save = deliver_domain;
+    const uschar *save = deliver_domain;
     deliver_domain = h->name;   /* set $domain */
-    rc = match_isinlist(string_copylc(h->name), &hosts_treat_as_local, 0,
+    rc = match_isinlist(string_copylc(h->name), CUSS &hosts_treat_as_local, 0,
       &domainlist_anchor, NULL, MCL_DOMAIN, TRUE, NULL);
     deliver_domain = save;
     if (rc == OK) goto FOUND_LOCAL;
@@ -1590,7 +1589,7 @@ uschar *hname, *save_hostname;
 uschar **aliases;
 uschar buffer[256];
 uschar *ordername;
-uschar *list = host_lookup_order;
+const uschar *list = host_lookup_order;
 dns_record *rr;
 dns_answer dnsa;
 dns_scan dnss;
@@ -1892,8 +1891,8 @@ Returns:                 HOST_FIND_FAILED  Failed to find the host or domain
 */


int
-host_find_byname(host_item *host, uschar *ignore_target_hosts, int flags,
- uschar **fully_qualified_name, BOOL local_host_check)
+host_find_byname(host_item *host, const uschar *ignore_target_hosts, int flags,
+ const uschar **fully_qualified_name, BOOL local_host_check)
{
int i, yield, times;
uschar **addrlist;
@@ -1909,7 +1908,7 @@ dns_again_means_nonexist. */

if (running_in_test_harness)
{
- uschar *endname = host->name + Ustrlen(host->name);
+ const uschar *endname = host->name + Ustrlen(host->name);
if (Ustrcmp(endname - 14, "test.again.dns") == 0) goto RETURN_AGAIN;
}

@@ -1932,8 +1931,8 @@ lookups here (except when testing standalone). */
   #else
   if (disable_ipv6 ||
     (dns_ipv4_lookup != NULL &&
-        match_isinlist(host->name, &dns_ipv4_lookup, 0, NULL, NULL, MCL_DOMAIN,
-          TRUE, NULL) == OK))
+        match_isinlist(host->name, CUSS &dns_ipv4_lookup, 0, NULL, NULL,
+      MCL_DOMAIN, TRUE, NULL) == OK))
   #endif


     { af = AF_INET; times = 1; }
@@ -2116,7 +2115,7 @@ yield = local_host_check?


 HDEBUG(D_host_lookup)
   {
-  host_item *h;
+  const host_item *h;
   if (fully_qualified_name != NULL)
     debug_printf("fully qualified name = %s\n", *fully_qualified_name);
   debug_printf("%s looked up these IP addresses:\n",
@@ -2146,9 +2145,9 @@ RETURN_AGAIN:
   {
   #ifndef STAND_ALONE
   int rc;
-  uschar *save = deliver_domain;
+  const uschar *save = deliver_domain;
   deliver_domain = host->name;  /* set $domain */
-  rc = match_isinlist(host->name, &dns_again_means_nonexist, 0, NULL, NULL,
+  rc = match_isinlist(host->name, CUSS &dns_again_means_nonexist, 0, NULL, NULL,
     MCL_DOMAIN, TRUE, NULL);
   deliver_domain = save;
   if (rc == OK)
@@ -2206,7 +2205,8 @@ Returns:       HOST_FIND_FAILED     couldn't find A record


 static int
 set_address_from_dns(host_item *host, host_item **lastptr,
-  uschar *ignore_target_hosts, BOOL allow_ip, uschar **fully_qualified_name,
+  const uschar *ignore_target_hosts, BOOL allow_ip,
+  const uschar **fully_qualified_name,
   BOOL dnssec_request, BOOL dnssec_require)
 {
 dns_record *rr;
@@ -2241,8 +2241,8 @@ loop once only, looking only for A records. */
 #if HAVE_IPV6
   #ifndef STAND_ALONE
     if (disable_ipv6 || (dns_ipv4_lookup != NULL &&
-        match_isinlist(host->name, &dns_ipv4_lookup, 0, NULL, NULL, MCL_DOMAIN,
-        TRUE, NULL) == OK))
+        match_isinlist(host->name, CUSS &dns_ipv4_lookup, 0, NULL, NULL,
+      MCL_DOMAIN, TRUE, NULL) == OK))
       i = 0;    /* look up A records only */
     else
   #endif        /* STAND_ALONE */
@@ -2481,10 +2481,10 @@ Returns:                HOST_FIND_FAILED  Failed to find the host or domain;
 */


 int
-host_find_bydns(host_item *host, uschar *ignore_target_hosts, int whichrrs,
+host_find_bydns(host_item *host, const uschar *ignore_target_hosts, int whichrrs,
   uschar *srv_service, uschar *srv_fail_domains, uschar *mx_fail_domains,
   uschar *dnssec_request_domains, uschar *dnssec_require_domains,
-  uschar **fully_qualified_name, BOOL *removed)
+  const uschar **fully_qualified_name, BOOL *removed)
 {
 host_item *h, *last;
 dns_record *rr;
@@ -2493,10 +2493,10 @@ int ind_type = 0;
 int yield;
 dns_answer dnsa;
 dns_scan dnss;
-BOOL dnssec_require = match_isinlist(host->name, &dnssec_require_domains,
+BOOL dnssec_require = match_isinlist(host->name, CUSS &dnssec_require_domains,
                     0, NULL, NULL, MCL_DOMAIN, TRUE, NULL) == OK;
 BOOL dnssec_request = dnssec_require
-            || match_isinlist(host->name, &dnssec_request_domains,
+            || match_isinlist(host->name, CUSS &dnssec_request_domains,
                     0, NULL, NULL, MCL_DOMAIN, TRUE, NULL) == OK;
 dnssec_status_t dnssec;


@@ -2531,7 +2531,7 @@ if ((whichrrs & HOST_FIND_BY_SRV) != 0)

dnssec = DS_UNK;
lookup_dnssec_authenticated = NULL;
- rc = dns_lookup(&dnsa, buffer, ind_type, &temp_fully_qualified_name);
+ rc = dns_lookup(&dnsa, buffer, ind_type, CUSS &temp_fully_qualified_name);

   if (dnssec_request)
     {
@@ -2556,8 +2556,8 @@ if ((whichrrs & HOST_FIND_BY_SRV) != 0)
   if (rc == DNS_FAIL || rc == DNS_AGAIN)
     {
     #ifndef STAND_ALONE
-    if (match_isinlist(host->name, &srv_fail_domains, 0, NULL, NULL, MCL_DOMAIN,
-        TRUE, NULL) != OK)
+    if (match_isinlist(host->name, CUSS &srv_fail_domains, 0, NULL, NULL,
+    MCL_DOMAIN, TRUE, NULL) != OK)
     #endif
       { yield = HOST_FIND_AGAIN; goto out; }
     DEBUG(D_host_lookup) debug_printf("DNS_%s treated as DNS_NODATA "
@@ -2608,8 +2608,8 @@ if (rc != DNS_SUCCEED && (whichrrs & HOST_FIND_BY_MX) != 0)
     case DNS_FAIL:
     case DNS_AGAIN:
       #ifndef STAND_ALONE
-      if (match_isinlist(host->name, &mx_fail_domains, 0, NULL, NULL, MCL_DOMAIN,
-      TRUE, NULL) != OK)
+      if (match_isinlist(host->name, CUSS &mx_fail_domains, 0, NULL, NULL,
+      MCL_DOMAIN, TRUE, NULL) != OK)
       #endif
     { yield = HOST_FIND_AGAIN; goto out; }
       DEBUG(D_host_lookup) debug_printf("DNS_%s treated as DNS_NODATA "
diff --git a/src/src/ip.c b/src/src/ip.c
index e594509..e4a43e6 100644
--- a/src/src/ip.c
+++ b/src/src/ip.c
@@ -421,7 +421,7 @@ Returns:     nothing
 */


 void
-ip_keepalive(int sock, uschar *address, BOOL torf)
+ip_keepalive(int sock, const uschar *address, BOOL torf)
 {
 int fodder = 1;
 if (setsockopt(sock, SOL_SOCKET, SO_KEEPALIVE,
diff --git a/src/src/log.c b/src/src/log.c
index c80c347..e8b514b 100644
--- a/src/src/log.c
+++ b/src/src/log.c
@@ -672,9 +672,9 @@ if (!path_inspected)
     {
     int sep = ':';              /* Fixed separator - outside use */
     uschar *s;
-    uschar *ss = log_file_path;
+    const uschar *ss = log_file_path;
     logging_mode = 0;
-    while ((s = string_nextinlist(&ss,&sep,log_buffer,LOG_BUFFER_SIZE)) != NULL)
+    while ((s = string_nextinlist(&ss, &sep, log_buffer, LOG_BUFFER_SIZE)))
       {
       if (Ustrcmp(s, "syslog") == 0)
         logging_mode |= LOG_MODE_SYSLOG;
@@ -698,9 +698,8 @@ if (!path_inspected)
         else
           {
           uschar *t;
-          uschar *tt = US LOG_FILE_PATH;
-          while ((t = string_nextinlist(&tt,&sep,log_buffer,LOG_BUFFER_SIZE))
-                != NULL)
+          const uschar *tt = US LOG_FILE_PATH;
+          while ((t = string_nextinlist(&tt, &sep, log_buffer, LOG_BUFFER_SIZE)))
             {
             if (Ustrcmp(t, "syslog") == 0 || t[0] == 0) continue;
             file_path = string_copy(t);
diff --git a/src/src/lookupapi.h b/src/src/lookupapi.h
index 2a27071..9c646e6 100644
--- a/src/src/lookupapi.h
+++ b/src/src/lookupapi.h
@@ -30,7 +30,7 @@ typedef struct lookup_info {
   int (*find)(                    /* find function */
     void *,                       /* handle */
     uschar *,                     /* file name or NULL */
-    uschar *,                     /* key or query */
+    const uschar *,               /* key or query */
     int,                          /* length of key or query */
     uschar **,                    /* for returning answer */
     uschar **,                    /* for error message */
diff --git a/src/src/lookups/cdb.c b/src/src/lookups/cdb.c
index fda14fb..87e3aa5 100644
--- a/src/src/lookups/cdb.c
+++ b/src/src/lookups/cdb.c
@@ -272,7 +272,7 @@ cdb_check(void *handle,
 static int
 cdb_find(void *handle,
         uschar *filename,
-        uschar *keystring,
+        const uschar *keystring,
         int  key_len,
         uschar **result,
         uschar **errmsg,
diff --git a/src/src/lookups/dbmdb.c b/src/src/lookups/dbmdb.c
index 3dec7a7..4e6ebad 100644
--- a/src/src/lookups/dbmdb.c
+++ b/src/src/lookups/dbmdb.c
@@ -86,7 +86,7 @@ return rc == 0;
 the keylength in order to include the terminating zero. */


static int
-dbmdb_find(void *handle, uschar *filename, uschar *keystring, int length,
+dbmdb_find(void *handle, uschar *filename, const uschar *keystring, int length,
uschar **result, uschar **errmsg, BOOL *do_cache)
{
EXIM_DB *d = (EXIM_DB *)handle;
@@ -119,7 +119,7 @@ return FAIL;
/* See local README for interface description */

int
-static dbmnz_find(void *handle, uschar *filename, uschar *keystring, int length,
+static dbmnz_find(void *handle, uschar *filename, const uschar *keystring, int length,
uschar **result, uschar **errmsg, BOOL *do_cache)
{
return dbmdb_find(handle, filename, keystring, length-1, result, errmsg,
@@ -139,11 +139,11 @@ return dbmdb_find(handle, filename, keystring, length-1, result, errmsg,
*/

static int
-dbmjz_find(void *handle, uschar *filename, uschar *keystring, int length,
+dbmjz_find(void *handle, uschar *filename, const uschar *keystring, int length,
uschar **result, uschar **errmsg, BOOL *do_cache)
{
uschar *key_item, *key_buffer, *key_p;
-uschar *key_elems = keystring;
+const uschar *key_elems = keystring;
int buflen, bufleft, key_item_len, sep = 0;

/* To a first approximation, the size of the lookup key needs to be about,
diff --git a/src/src/lookups/dnsdb.c b/src/src/lookups/dnsdb.c
index 7c2d1a5..ac0bff2 100644
--- a/src/src/lookups/dnsdb.c
+++ b/src/src/lookups/dnsdb.c
@@ -127,7 +127,7 @@ which may start with '<' in order to set a specific separator. The default
separator, as always, is colon. */

static int
-dnsdb_find(void *handle, uschar *filename, uschar *keystring, int length,
+dnsdb_find(void *handle, uschar *filename, const uschar *keystring, int length,
uschar **result, uschar **errmsg, BOOL *do_cache)
{
int rc;
@@ -138,8 +138,8 @@ int defer_mode = PASS;
int dnssec_mode = OK;
int type;
int failrc = FAIL;
-uschar *outsep = US"\n";
-uschar *outsep2 = NULL;
+const uschar *outsep = CUS"\n";
+const uschar *outsep2 = NULL;
uschar *equals, *domain, *found;
uschar buffer[256];

@@ -353,11 +353,11 @@ while ((domain = string_nextinlist(&keystring, &sep, buffer, sizeof(buffer)))
 # endif
       else if (searchtype == T_A6)   searchtype = T_AAAA;
       else if (searchtype == T_AAAA) searchtype = T_A;
-      rc = dns_special_lookup(&dnsa, domain, searchtype, &found);
+      rc = dns_special_lookup(&dnsa, domain, searchtype, CUSS &found);
       }
     else
 #endif
-      rc = dns_special_lookup(&dnsa, domain, type, &found);
+      rc = dns_special_lookup(&dnsa, domain, type, CUSS &found);


     lookup_dnssec_authenticated = dnssec_mode==OK ? NULL
       : dns_is_secure(&dnsa) ? US"yes" : US"no";
diff --git a/src/src/lookups/dsearch.c b/src/src/lookups/dsearch.c
index 990b69c..c041bbb 100644
--- a/src/src/lookups/dsearch.c
+++ b/src/src/lookups/dsearch.c
@@ -66,7 +66,7 @@ scanning the directory, as it is hopefully faster to let the OS do the scanning
 for us. */


 int
-static dsearch_find(void *handle, uschar *dirname, uschar *keystring, int length,
+static dsearch_find(void *handle, uschar *dirname, const uschar *keystring, int length,
   uschar **result, uschar **errmsg, BOOL *do_cache)
 {
 struct stat statbuf;
diff --git a/src/src/lookups/ldap.c b/src/src/lookups/ldap.c
index ef7ed9e..037459c 100644
--- a/src/src/lookups/ldap.c
+++ b/src/src/lookups/ldap.c
@@ -130,9 +130,10 @@ Returns:        OK or FAIL or DEFER
 */


 static int
-perform_ldap_search(uschar *ldap_url, uschar *server, int s_port, int search_type,
-  uschar **res, uschar **errmsg, BOOL *defer_break, uschar *user, uschar *password,
-  int sizelimit, int timelimit, int tcplimit, int dereference, void *referrals)
+perform_ldap_search(const uschar *ldap_url, uschar *server, int s_port,
+  int search_type, uschar **res, uschar **errmsg, BOOL *defer_break,
+  uschar *user, uschar *password, int sizelimit, int timelimit, int tcplimit,
+  int dereference, void *referrals)
 {
 LDAPURLDesc     *ludp = NULL;
 LDAPMessage     *result = NULL;
@@ -1125,7 +1126,7 @@ Returns:        OK or FAIL or DEFER
 */


static int
-control_ldap_search(uschar *ldap_url, int search_type, uschar **res,
+control_ldap_search(const uschar *ldap_url, int search_type, uschar **res,
uschar **errmsg)
{
BOOL defer_break = FALSE;
@@ -1135,12 +1136,13 @@ int tcplimit = 0;
int sep = 0;
int dereference = LDAP_DEREF_NEVER;
void* referrals = LDAP_OPT_ON;
-uschar *url = ldap_url;
-uschar *p;
+const uschar *url = ldap_url;
+const uschar *p;
uschar *user = NULL;
uschar *password = NULL;
uschar *local_servers = NULL;
-uschar *server, *list;
+uschar *server;
+const uschar *list;
uschar buffer[512];

while (isspace(*url)) url++;
@@ -1152,7 +1154,7 @@ NAME has the value "ldap". */

 while (strncmpic(url, US"ldap", 4) != 0)
   {
-  uschar *name = url;
+  const uschar *name = url;
   while (*url != 0 && *url != '=') url++;
   if (*url == '=')
     {
@@ -1336,7 +1338,7 @@ are handled by a common function, with a flag to differentiate between them.
 The handle and filename arguments are not used. */


static int
-eldap_find(void *handle, uschar *filename, uschar *ldap_url, int length,
+eldap_find(void *handle, uschar *filename, const uschar *ldap_url, int length,
uschar **result, uschar **errmsg, BOOL *do_cache)
{
/* Keep picky compilers happy */
@@ -1345,7 +1347,7 @@ return(control_ldap_search(ldap_url, SEARCH_LDAP_SINGLE, result, errmsg));
}

static int
-eldapm_find(void *handle, uschar *filename, uschar *ldap_url, int length,
+eldapm_find(void *handle, uschar *filename, const uschar *ldap_url, int length,
uschar **result, uschar **errmsg, BOOL *do_cache)
{
/* Keep picky compilers happy */
@@ -1354,7 +1356,7 @@ return(control_ldap_search(ldap_url, SEARCH_LDAP_MULTIPLE, result, errmsg));
}

static int
-eldapdn_find(void *handle, uschar *filename, uschar *ldap_url, int length,
+eldapdn_find(void *handle, uschar *filename, const uschar *ldap_url, int length,
uschar **result, uschar **errmsg, BOOL *do_cache)
{
/* Keep picky compilers happy */
@@ -1363,7 +1365,7 @@ return(control_ldap_search(ldap_url, SEARCH_LDAP_DN, result, errmsg));
}

int
-eldapauth_find(void *handle, uschar *filename, uschar *ldap_url, int length,
+eldapauth_find(void *handle, uschar *filename, const uschar *ldap_url, int length,
uschar **result, uschar **errmsg, BOOL *do_cache)
{
/* Keep picky compilers happy */
diff --git a/src/src/lookups/ldap.h b/src/src/lookups/ldap.h
index 5ce756d..817b72e 100644
--- a/src/src/lookups/ldap.h
+++ b/src/src/lookups/ldap.h
@@ -7,7 +7,7 @@

/* Header for eldapauth_find */

-extern int     eldapauth_find(void *, uschar *, uschar *, int, uschar **,
+extern int     eldapauth_find(void *, uschar *, const uschar *, int, uschar **,
                  uschar **, BOOL *);


 /* End of lookups/ldap.h */
diff --git a/src/src/lookups/lf_functions.h b/src/src/lookups/lf_functions.h
index 9f7c7a2..a75fbcc 100644
--- a/src/src/lookups/lf_functions.h
+++ b/src/src/lookups/lf_functions.h
@@ -10,8 +10,9 @@
 extern int     lf_check_file(int, uschar *, int, int, uid_t *, gid_t *,
                  const char *, uschar **);
 extern uschar *lf_quote(uschar *, uschar *, int, uschar *, int *, int *);
-extern int     lf_sqlperform(uschar *, uschar *, uschar *, uschar *, uschar **,
-                 uschar **, BOOL *, int(*)(uschar *, uschar *, uschar **,
+extern int     lf_sqlperform(const uschar *, const uschar *, const uschar *,
+         const uschar *, uschar **,
+                 uschar **, BOOL *, int(*)(const uschar *, uschar *, uschar **,
                  uschar **, BOOL *, BOOL *));


 /* End of lf_functions.h */
diff --git a/src/src/lookups/lf_sqlperform.c b/src/src/lookups/lf_sqlperform.c
index d430cd4..a58e192 100644
--- a/src/src/lookups/lf_sqlperform.c
+++ b/src/src/lookups/lf_sqlperform.c
@@ -34,13 +34,14 @@ Returns:         the return from the lookup function, or DEFER
 */


int
-lf_sqlperform(uschar *name, uschar *optionname, uschar *optserverlist,
- uschar *query, uschar **result, uschar **errmsg, BOOL *do_cache,
- int(*fn)(uschar *, uschar *, uschar **, uschar **, BOOL *, BOOL *))
+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 *))
{
int sep, rc;
uschar *server;
-uschar *serverlist;
+const uschar *serverlist;
uschar buffer[512];
BOOL defer_break = FALSE;

@@ -68,8 +69,8 @@ if (Ustrncmp(query, "servers", 7) != 0)
else
{
int qsep;
- uschar *s, *ss;
- uschar *qserverlist;
+ const uschar *s, *ss;
+ const uschar *qserverlist;
uschar *qserver;
uschar qbuffer[512];

diff --git a/src/src/lookups/lsearch.c b/src/src/lookups/lsearch.c
index 537cac7..8ea1330 100644
--- a/src/src/lookups/lsearch.c
+++ b/src/src/lookups/lsearch.c
@@ -71,7 +71,7 @@ fit into the fixed sized buffer. Most of the time this will never be exercised,
but people do occasionally do weird things. */

 static int
-internal_lsearch_find(void *handle, uschar *filename, uschar *keystring,
+internal_lsearch_find(void *handle, uschar *filename, const uschar *keystring,
   int length, uschar **result, uschar **errmsg, int type)
 {
 FILE *f = (FILE *)handle;
@@ -146,7 +146,7 @@ for (last_was_eol = TRUE;
     uschar *t = s++;
     while (*s != 0 && *s != '\"')
       {
-      if (*s == '\\') *t++ = string_interpret_escape(&s);
+      if (*s == '\\') *t++ = string_interpret_escape(CUSS &s);
         else *t++ = *s;
       s++;
       }
@@ -181,7 +181,7 @@ for (last_was_eol = TRUE;
       {
       int rc;
       int save = buffer[linekeylength];
-      uschar *list = buffer;
+      const uschar *list = buffer;
       buffer[linekeylength] = 0;
       rc = match_isinlist(keystring,
         &list,
@@ -322,7 +322,7 @@ return FAIL;
 /* See local README for interface description */


static int
-lsearch_find(void *handle, uschar *filename, uschar *keystring, int length,
+lsearch_find(void *handle, uschar *filename, const uschar *keystring, int length,
uschar **result, uschar **errmsg, BOOL *do_cache)
{
do_cache = do_cache; /* Keep picky compilers happy */
@@ -339,7 +339,7 @@ return internal_lsearch_find(handle, filename, keystring, length, result,
/* See local README for interface description */

static int
-wildlsearch_find(void *handle, uschar *filename, uschar *keystring, int length,
+wildlsearch_find(void *handle, uschar *filename, const uschar *keystring, int length,
uschar **result, uschar **errmsg, BOOL *do_cache)
{
do_cache = do_cache; /* Keep picky compilers happy */
@@ -356,7 +356,7 @@ return internal_lsearch_find(handle, filename, keystring, length, result,
/* See local README for interface description */

static int
-nwildlsearch_find(void *handle, uschar *filename, uschar *keystring, int length,
+nwildlsearch_find(void *handle, uschar *filename, const uschar *keystring, int length,
uschar **result, uschar **errmsg, BOOL *do_cache)
{
do_cache = do_cache; /* Keep picky compilers happy */
@@ -374,7 +374,7 @@ return internal_lsearch_find(handle, filename, keystring, length, result,
/* See local README for interface description */

 static int
-iplsearch_find(void *handle, uschar *filename, uschar *keystring, int length,
+iplsearch_find(void *handle, uschar *filename, const uschar *keystring, int length,
   uschar **result, uschar **errmsg, BOOL *do_cache)
 {
 do_cache = do_cache;  /* Keep picky compilers happy */
diff --git a/src/src/lookups/mysql.c b/src/src/lookups/mysql.c
index 9511d2a..7f3ed92 100644
--- a/src/src/lookups/mysql.c
+++ b/src/src/lookups/mysql.c
@@ -84,7 +84,7 @@ Returns:       OK, FAIL, or DEFER
 */


 static int
-perform_mysql_search(uschar *query, uschar *server, uschar **resultptr,
+perform_mysql_search(const uschar *query, uschar *server, uschar **resultptr,
   uschar **errmsg, BOOL *defer_break, BOOL *do_cache)
 {
 MYSQL *mysql_handle = NULL;        /* Keep compilers happy */
@@ -340,7 +340,7 @@ query is deferred with a retryable error is now in a separate function that is
 shared with other SQL lookups. */


 static int
-mysql_find(void *handle, uschar *filename, uschar *query, int length,
+mysql_find(void *handle, uschar *filename, const uschar *query, int length,
   uschar **result, uschar **errmsg, BOOL *do_cache)
 {
 return lf_sqlperform(US"MySQL", US"mysql_servers", mysql_servers, query,
diff --git a/src/src/lookups/passwd.c b/src/src/lookups/passwd.c
index 4690cbf..c9986da 100644
--- a/src/src/lookups/passwd.c
+++ b/src/src/lookups/passwd.c
@@ -33,7 +33,7 @@ return (void *)(-1);     /* Just return something non-null */
 /* See local README for interface description */


 static int
-passwd_find(void *handle, uschar *filename, uschar *keystring, int length,
+passwd_find(void *handle, uschar *filename, const uschar *keystring, int length,
   uschar **result, uschar **errmsg, BOOL *do_cache)
 {
 struct passwd *pw;
diff --git a/src/src/lookups/pgsql.c b/src/src/lookups/pgsql.c
index 95b1b8c..a902edd 100644
--- a/src/src/lookups/pgsql.c
+++ b/src/src/lookups/pgsql.c
@@ -118,7 +118,7 @@ Returns:       OK, FAIL, or DEFER
 */


static int
-perform_pgsql_search(uschar *query, uschar *server, uschar **resultptr,
+perform_pgsql_search(const uschar *query, uschar *server, uschar **resultptr,
uschar **errmsg, BOOL *defer_break, BOOL *do_cache)
{
PGconn *pg_conn = NULL;
@@ -398,7 +398,7 @@ query is deferred with a retryable error is now in a separate function that is
shared with other SQL lookups. */

static int
-pgsql_find(void *handle, uschar *filename, uschar *query, int length,
+pgsql_find(void *handle, uschar *filename, const uschar *query, int length,
uschar **result, uschar **errmsg, BOOL *do_cache)
{
return lf_sqlperform(US"PostgreSQL", US"pgsql_servers", pgsql_servers, query,
diff --git a/src/src/lookups/sqlite.c b/src/src/lookups/sqlite.c
index c0fc891..b412cb4 100644
--- a/src/src/lookups/sqlite.c
+++ b/src/src/lookups/sqlite.c
@@ -80,7 +80,7 @@ return 0;


 static int
-sqlite_find(void *handle, uschar *filename, uschar *query, int length,
+sqlite_find(void *handle, uschar *filename, const uschar *query, int length,
   uschar **result, uschar **errmsg, BOOL *do_cache)
 {
 int ret;
diff --git a/src/src/lookups/testdb.c b/src/src/lookups/testdb.c
index 7a81795..c74c496 100644
--- a/src/src/lookups/testdb.c
+++ b/src/src/lookups/testdb.c
@@ -37,7 +37,7 @@ return (void *)(1);    /* Just return something non-null */
 /* See local README for interface description. */


 static int
-testdb_find(void *handle, uschar *filename, uschar *query, int length,
+testdb_find(void *handle, uschar *filename, const uschar *query, int length,
   uschar **result, uschar **errmsg, BOOL *do_cache)
 {
 handle = handle;          /* Keep picky compilers happy */
diff --git a/src/src/lss.c b/src/src/lss.c
index ab358d9..ca27bd4 100644
--- a/src/src/lss.c
+++ b/src/src/lss.c
@@ -27,7 +27,7 @@ Returns:         OK/FAIL/DEFER
 int
 lss_match_domain(uschar *domain, uschar *list)
 {
-return match_isinlist(domain, &list, 0, &domainlist_anchor, NULL, MCL_DOMAIN,
+return match_isinlist(CUS domain, CUSS &list, 0, &domainlist_anchor, NULL, MCL_DOMAIN,
   TRUE, NULL);
 }


@@ -49,7 +49,7 @@ Returns:         OK/FAIL/DEFER
 int
 lss_match_local_part(uschar *local_part, uschar *list, BOOL caseless)
 {
-return match_isinlist(local_part, &list, 0, &localpartlist_anchor, NULL,
+return match_isinlist(CUS local_part, CUSS &list, 0, &localpartlist_anchor, NULL,
   MCL_LOCALPART, caseless, NULL);
 }


@@ -71,7 +71,7 @@ Returns:         OK/FAIL/DEFER
 int
 lss_match_address(uschar *address, uschar *list, BOOL caseless)
 {
-return match_address_list(address, caseless, TRUE, &list, NULL, -1, 0, NULL);
+return match_address_list(CUS address, caseless, TRUE, CUSS &list, NULL, -1, 0, NULL);
 }



@@ -95,7 +95,7 @@ Returns:         OK/FAIL/DEFER
 int
 lss_match_host(uschar *host_name, uschar *host_address, uschar *list)
 {
-return verify_check_this_host(&list, NULL, host_name, host_address, NULL);
+return verify_check_this_host(CUSS &list, NULL, host_name, host_address, NULL);
 }



diff --git a/src/src/macros.h b/src/src/macros.h
index 43179a5..4db2bda 100644
--- a/src/src/macros.h
+++ b/src/src/macros.h
@@ -106,6 +106,13 @@ don't make the file descriptors two-way. */
 #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)
+
 /* The default From: text for DSNs */


#define DEFAULT_DSN_FROM "Mail Delivery System <Mailer-Daemon@$qualify_domain>"
diff --git a/src/src/malware.c b/src/src/malware.c
index 3ef1498..2e49751 100644
--- a/src/src/malware.c
+++ b/src/src/malware.c
@@ -184,7 +184,8 @@ m_pcre_exec(const pcre * cre, uschar * text)
}

static const pcre *
-m_pcre_nextinlist(uschar ** list, int * sep, char * listerr, uschar ** errstr)
+m_pcre_nextinlist(const uschar ** list, int * sep,
+ char * listerr, uschar ** errstr)
{
const uschar * list_ele;
const pcre * cre = NULL;
@@ -395,7 +396,7 @@ malware_internal(const uschar * malware_re, const uschar * eml_filename,
int timeout, BOOL faking)
{
int sep = 0;
-uschar *av_scanner_work = av_scanner;
+const uschar *av_scanner_work = av_scanner;
uschar *scanner_name;
unsigned long mbox_size;
FILE *mbox_file;
diff --git a/src/src/match.c b/src/src/match.c
index 97c4ea0..5bf4ef5 100644
--- a/src/src/match.c
+++ b/src/src/match.c
@@ -28,7 +28,7 @@ typedef struct check_string_block {
addresses. */

 typedef struct check_address_block {
-  uschar *origaddress;               /* caseful; keep these two first, in */
+  const uschar *origaddress;         /* caseful; keep these two first, in */
   uschar *address;                   /* step with the block above */
   int    expand_setup;
   BOOL   caseless;
@@ -92,12 +92,12 @@ Returns:       OK    if matched
 */


 static int
-check_string(void *arg, uschar *pattern, uschar **valueptr, uschar **error)
+check_string(void *arg, const uschar *pattern, const uschar **valueptr, uschar **error)
 {
 const check_string_block *cb = arg;
 int search_type, partial, affixlen, starflags;
 int expand_setup = cb->expand_setup;
-uschar *affix;
+const uschar *affix;
 uschar *s;
 uschar *filename = NULL;
 uschar *keyquery, *result, *semicolon;
@@ -192,8 +192,8 @@ if (cb->at_is_special && pattern[0] == '@')
     BOOL prim = FALSE;
     BOOL secy = FALSE;
     BOOL removed = FALSE;
-    uschar *ss = pattern + 4;
-    uschar *ignore_target_hosts = NULL;
+    const uschar *ss = pattern + 4;
+    const uschar *ignore_target_hosts = NULL;


     if (strncmpic(ss, US"any", 3) == 0) ss += 3;
     else if (strncmpic(ss, US"primary", 7) == 0)
@@ -337,8 +337,8 @@ Returns:       OK    if matched
 */


 int
-match_check_string(uschar *s, uschar *pattern, int expand_setup,
-  BOOL use_partial, BOOL caseless, BOOL at_is_special, uschar **valueptr)
+match_check_string(const uschar *s, const uschar *pattern, int expand_setup,
+  BOOL use_partial, BOOL caseless, BOOL at_is_special, const uschar **valueptr)
 {
 check_string_block cb;
 cb.origsubject = s;
@@ -436,9 +436,9 @@ Returns:       OK    if matched a non-negated item
 */


 int
-match_check_list(uschar **listptr, int sep, tree_node **anchorptr,
-  unsigned int **cache_ptr, int (*func)(void *,uschar *,uschar **,uschar **),
-  void *arg, int type, const uschar *name, uschar **valueptr)
+match_check_list(const uschar **listptr, int sep, tree_node **anchorptr,
+  unsigned int **cache_ptr, int (*func)(void *,const uschar *,const uschar **,uschar **),
+  void *arg, int type, const uschar *name, const uschar **valueptr)
 {
 int yield = OK;
 unsigned int *original_cache_bits = *cache_ptr;
@@ -446,7 +446,7 @@ BOOL include_unknown = FALSE;
 BOOL ignore_unknown = FALSE;
 BOOL include_defer = FALSE;
 BOOL ignore_defer = FALSE;
-uschar *list;
+const uschar *list;
 uschar *sss;
 uschar *ot = NULL;
 uschar buffer[1024];
@@ -490,11 +490,11 @@ else
     {
     check_string_block *cb = (check_string_block *)arg;
     deliver_domain = string_copy(cb->subject);
-    list = expand_string(*listptr);
+    list = expand_cstring(*listptr);
     deliver_domain = NULL;
     }


- else list = expand_string(*listptr);
+ else list = expand_cstring(*listptr);

   if (list == NULL)
     {
@@ -952,9 +952,9 @@ Returns:         OK    if matched a non-negated item
 */


 int
-match_isinlist(const uschar *s, uschar **listptr, int sep,
+match_isinlist(const uschar *s, const uschar **listptr, int sep,
    tree_node **anchorptr,
-  unsigned int *cache_bits, int type, BOOL caseless, uschar **valueptr)
+  unsigned int *cache_bits, int type, BOOL caseless, const uschar **valueptr)
 {
 unsigned int *local_cache_bits = cache_bits;
 check_string_block cb;
@@ -1000,16 +1000,17 @@ Returns:         OK     for a match
 */


static int
-check_address(void *arg, uschar *pattern, uschar **valueptr, uschar **error)
+check_address(void *arg, const uschar *pattern, const uschar **valueptr, uschar **error)
{
check_address_block *cb = (check_address_block *)arg;
check_string_block csb;
int rc;
int expand_inc = 0;
unsigned int *null = NULL;
-uschar *listptr;
+const uschar *listptr;
uschar *subject = cb->address;
-uschar *s, *pdomain, *sdomain;
+const uschar *s;
+uschar *pdomain, *sdomain;

error = error; /* Keep clever compilers from complaining */

@@ -1071,7 +1072,8 @@ looked up to obtain a list of local parts. If the subject's local part is just
if (pattern[0] == '@' && pattern[1] == '@')
{
int watchdog = 50;
- uschar *list, *key, *ss;
+ const uschar *key;
+ uschar *list, *ss;
uschar buffer[1024];

   if (sdomain == subject + 1 && *subject == '*') return FAIL;
@@ -1084,7 +1086,7 @@ if (pattern[0] == '@' && pattern[1] == '@')
     int sep = 0;


     if ((rc = match_check_string(key, pattern + 2, -1, TRUE, FALSE, FALSE,
-      &list)) != OK) return rc;
+      CUSS &list)) != OK) return rc;


     /* Check for chaining from the last item; set up the next key if one
     is found. */
@@ -1103,8 +1105,7 @@ if (pattern[0] == '@' && pattern[1] == '@')
     /* Look up the local parts provided by the list; negation is permitted.
     If a local part has to begin with !, a regex can be used. */


-    while ((ss = string_nextinlist(&list, &sep, buffer, sizeof(buffer)))
-           != NULL)
+    while ((ss = string_nextinlist(CUSS &list, &sep, buffer, sizeof(buffer))))
       {
       int local_yield;


@@ -1279,9 +1280,9 @@ Returns:          OK    for a positive match, or end list after a negation;
 */


int
-match_address_list(uschar *address, BOOL caseless, BOOL expand,
- uschar **listptr, unsigned int *cache_bits, int expand_setup, int sep,
- uschar **valueptr)
+match_address_list(const uschar *address, BOOL caseless, BOOL expand,
+ const uschar **listptr, unsigned int *cache_bits, int expand_setup, int sep,
+ const uschar **valueptr)
{
uschar *p;
check_address_block ab;
diff --git a/src/src/mime.c b/src/src/mime.c
index 948dd78..51f00d3 100644
--- a/src/src/mime.c
+++ b/src/src/mime.c
@@ -283,10 +283,10 @@ return f;


 int
-mime_decode(uschar **listptr)
+mime_decode(const uschar **listptr)
 {
 int sep = 0;
-uschar *list = *listptr;
+const uschar *list = *listptr;
 uschar *option;
 uschar option_buffer[1024];
 uschar decode_path[1024];
@@ -696,7 +696,7 @@ NEXT_PARAM_SEARCH:
   else if ( (mime_content_type != NULL) &&
       (Ustrncmp(mime_content_type,"message/rfc822",14) == 0) )
     {
-    uschar *rfc822name = NULL;
+    const uschar *rfc822name = NULL;
     uschar filename[2048];
     int file_nr = 0;
     int result = 0;
diff --git a/src/src/moan.c b/src/src/moan.c
index 4d7b51b..a369989 100644
--- a/src/src/moan.c
+++ b/src/src/moan.c
@@ -598,7 +598,7 @@ uschar *
 moan_check_errorcopy(uschar *recipient)
 {
 uschar *item, *localpart, *domain;
-uschar *listptr = errors_copy;
+const uschar *listptr = errors_copy;
 uschar *yield = NULL;
 uschar buffer[256];
 int sep = 0;
@@ -619,8 +619,8 @@ llen = domain++ - recipient;
 while ((item = string_nextinlist(&listptr, &sep, buffer, sizeof(buffer)))
        != NULL)
   {
-  uschar *newaddress = item;
-  uschar *pattern = string_dequote(&newaddress);
+  const uschar *newaddress = item;
+  const uschar *pattern = string_dequote(&newaddress);


/* If no new address found, just skip this item. */

diff --git a/src/src/mytypes.h b/src/src/mytypes.h
index 964abf8..b9aef70 100644
--- a/src/src/mytypes.h
+++ b/src/src/mytypes.h
@@ -66,6 +66,7 @@ almost always literal strings. */
#define US (unsigned char *)
#define CUS (const unsigned char *)
#define USS (unsigned char **)
+#define CUSS (const unsigned char **)

 /* The C library string functions expect "char *" arguments. Use macros to
 avoid having to write a cast each time. We do this for string and file
diff --git a/src/src/parse.c b/src/src/parse.c
index 94e42c1..ff814e7 100644
--- a/src/src/parse.c
+++ b/src/src/parse.c
@@ -866,11 +866,11 @@ Returns:       pointer to the original string, if no quoting needed, or
                the introduction
 */


-uschar *
-parse_quote_2047(uschar *string, int len, uschar *charset, uschar *buffer,
+const uschar *
+parse_quote_2047(const uschar *string, int len, uschar *charset, uschar *buffer,
   int buffer_size, BOOL fold)
 {
-uschar *s = string;
+const uschar *s = string;
 uschar *p, *t;
 int hlen;
 BOOL coded = FALSE;
@@ -985,12 +985,13 @@ Arguments:
 Returns:       the fixed RFC822 phrase
 */


-uschar *
-parse_fix_phrase(uschar *phrase, int len, uschar *buffer, int buffer_size)
+const uschar *
+parse_fix_phrase(const uschar *phrase, int len, uschar *buffer, int buffer_size)
{
int ch, i;
BOOL quoted = FALSE;
-uschar *s, *t, *end, *yield;
+const uschar *s, *end;
+uschar *t, *yield;

while (len > 0 && isspace(*phrase)) { phrase++; len--; }
if (len > buffer_size/4) return US"Name too long";
@@ -1119,7 +1120,7 @@ while (s < end)

         else if (ch == '(')
           {
-          uschar *ss = s;     /* uschar after '(' */
+          const uschar *ss = s;     /* uschar after '(' */
           int level = 1;
           while(ss < end)
             {
@@ -1245,7 +1246,7 @@ Returns:      FF_DELIVERED      addresses extracted


int
parse_forward_list(uschar *s, int options, address_item **anchor,
- uschar **error, uschar *incoming_domain, uschar *directory,
+ uschar **error, const uschar *incoming_domain, uschar *directory,
error_block **syntax_errors)
{
int count = 0;
diff --git a/src/src/queue.c b/src/src/queue.c
index 8876e09..ca6c47f 100644
--- a/src/src/queue.c
+++ b/src/src/queue.c
@@ -1345,7 +1345,8 @@ queue_check_only(void)
BOOL *set;
int sep = 0;
struct stat statbuf;
-uschar *s, *ss, *name;
+const uschar *s;
+uschar *ss, *name;
uschar buffer[1024];

 if (queue_only_file == NULL) return;
diff --git a/src/src/rda.c b/src/src/rda.c
index f915ce7..99c5513 100644
--- a/src/src/rda.c
+++ b/src/src/rda.c
@@ -444,7 +444,7 @@ Returns:     -1 on error, else 0
 */


 static int
-rda_write_string(int fd, uschar *s)
+rda_write_string(int fd, const uschar *s)
 {
 int len = (s == NULL)? 0 : Ustrlen(s) + 1;
 return (  write(fd, &len, sizeof(int)) != sizeof(int)
diff --git a/src/src/readconf.c b/src/src/readconf.c
index 31a4f2d..debe319 100644
--- a/src/src/readconf.c
+++ b/src/src/readconf.c
@@ -1085,7 +1085,7 @@ Returns:      the value, or -1 on error
 */


 static int
-readconf_readfixed(uschar *s, int terminator)
+readconf_readfixed(const uschar *s, int terminator)
 {
 int yield = 0;
 int value, count;
@@ -1191,7 +1191,7 @@ Returns:     doesn't return; dies
 */


 static void
-extra_chars_error(uschar *s, uschar *t1, uschar *t2, uschar *t3)
+extra_chars_error(const uschar *s, const uschar *t1, const uschar *t2, const uschar *t3)
 {
 uschar *comment = US"";
 if (*s == '#') comment = US" (# is comment only at line start)";
@@ -1227,7 +1227,7 @@ Returns:      the control block for the parsed rule.
 */


static rewrite_rule *
-readconf_one_rewrite(uschar *p, int *existflags, BOOL isglobal)
+readconf_one_rewrite(const uschar *p, int *existflags, BOOL isglobal)
{
rewrite_rule *next = store_get(sizeof(rewrite_rule));

@@ -1333,10 +1333,10 @@ Returns:    pointer to the string
 */


static uschar *
-read_string(uschar *s, uschar *name)
+read_string(const uschar *s, const uschar *name)
{
uschar *yield;
-uschar *ss;
+const uschar *ss;

if (*s != '\"') return string_copy(s);

@@ -1599,7 +1599,7 @@ switch (type)
       {
       uschar sep_o = Ustrncmp(name, "headers_add", 11)==0 ? '\n' : ':';
       int    sep_i = -(int)sep_o;
-      uschar * list = sptr;
+      const uschar * list = sptr;
       uschar * s;
       uschar * list_o = *str_target;


@@ -1649,8 +1649,7 @@ switch (type)
         flagptr = (int *)((uschar *)data_block + (long int)(ol3->value));
         }


-      while ((p = string_nextinlist(&sptr, &sep, big_buffer, BIG_BUFFER_SIZE))
-              != NULL)
+      while ((p = string_nextinlist(CUSS &sptr, &sep, big_buffer, BIG_BUFFER_SIZE)))
         {
         rewrite_rule *next = readconf_one_rewrite(p, flagptr, FALSE);
         *chain = next;
@@ -1774,8 +1773,8 @@ switch (type)
       int count = 1;
       uid_t *list;
       int ptr = 0;
-      uschar *p;
-      uschar *op = expand_string (sptr);
+      const uschar *p;
+      const uschar *op = expand_string (sptr);


       if (op == NULL)
         log_write(0, LOG_PANIC_DIE|LOG_CONFIG_IN, "failed to expand %s: %s",
@@ -1815,8 +1814,8 @@ switch (type)
       int count = 1;
       gid_t *list;
       int ptr = 0;
-      uschar *p;
-      uschar *op = expand_string (sptr);
+      const uschar *p;
+      const uschar *op = expand_string (sptr);


       if (op == NULL)
         log_write(0, LOG_PANIC_DIE|LOG_CONFIG_IN, "failed to expand %s: %s",
@@ -2966,7 +2965,7 @@ readconf_main(void)
 int sep = 0;
 struct stat statbuf;
 uschar *s, *filename;
-uschar *list = config_main_filelist;
+const uschar *list = config_main_filelist;


/* Loop through the possible file names */

@@ -3138,7 +3137,7 @@ don't force the case. */

 if (primary_hostname == NULL)
   {
-  uschar *hostname;
+  const uschar *hostname;
   struct utsname uts;
   if (uname(&uts) < 0)
     log_write(0, LOG_MAIN|LOG_PANIC_DIE, "uname() failed to yield host name");
@@ -3151,8 +3150,8 @@ if (primary_hostname == NULL)


     #if HAVE_IPV6
     if (!disable_ipv6 && (dns_ipv4_lookup == NULL ||
-         match_isinlist(hostname, &dns_ipv4_lookup, 0, NULL, NULL, MCL_DOMAIN,
-           TRUE, NULL) != OK))
+         match_isinlist(hostname, CUSS &dns_ipv4_lookup, 0, NULL, NULL,
+        MCL_DOMAIN, TRUE, NULL) != OK))
       af = AF_INET6;
     #else
     af = AF_INET;
@@ -3212,7 +3211,7 @@ or %M. However, it must NOT contain % followed by anything else. */


 if (*log_file_path != 0)
   {
-  uschar *ss, *sss;
+  const uschar *ss, *sss;
   int sep = ':';                       /* Fixed for log file path */
   s = expand_string(log_file_path);
   if (s == NULL)
@@ -3699,10 +3698,10 @@ Returns:       NULL if decoded correctly; else points to error text
 */


uschar *
-readconf_retry_error(uschar *pp, uschar *p, int *basic_errno, int *more_errno)
+readconf_retry_error(const uschar *pp, const uschar *p, int *basic_errno, int *more_errno)
{
int len;
-uschar *q = pp;
+const uschar *q = pp;
while (q < p && *q != '_') q++;
len = q - pp;

@@ -3731,7 +3730,7 @@ else if (len == 7 && strncmpic(pp, US"timeout", len) == 0)
     {
     int i;
     int xlen = p - q - 1;
-    uschar *x = q + 1;
+    const uschar *x = q + 1;


     static uschar *extras[] =
       { US"A", US"MX", US"connect", US"connect_A",  US"connect_MX" };
@@ -3835,10 +3834,10 @@ Returns:    time in seconds or fixed point number * 1000
 */


static int
-retry_arg(uschar **paddr, int type)
+retry_arg(const uschar **paddr, int type)
{
-uschar *p = *paddr;
-uschar *pp;
+const uschar *p = *paddr;
+const uschar *pp;

if (*p++ != ',') log_write(0, LOG_PANIC_DIE|LOG_CONFIG_IN, "comma expected");

@@ -3867,12 +3866,13 @@ readconf_retries(void)
{
retry_config **chain = &retries;
retry_config *next;
-uschar *p;
+const uschar *p;

while ((p = get_config_line()) != NULL)
{
retry_rule **rchain;
- uschar *pp, *error;
+ const uschar *pp;
+ uschar *error;

   next = store_get(sizeof(retry_config));
   next->next = NULL;
diff --git a/src/src/receive.c b/src/src/receive.c
index 977150c..0b35463 100644
--- a/src/src/receive.c
+++ b/src/src/receive.c
@@ -87,7 +87,7 @@ if (newsender == NULL || untrusted_set_sender == NULL) return FALSE;
 qnewsender = (Ustrchr(newsender, '@') != NULL)?
   newsender : string_sprintf("%s@%s", newsender, qualify_domain_sender);
 return
-  match_address_list(qnewsender, TRUE, TRUE, &untrusted_set_sender, NULL, -1,
+  match_address_list(qnewsender, TRUE, TRUE, CUSS &untrusted_set_sender, NULL, -1,
     0, NULL) == OK;
 }


@@ -142,17 +142,16 @@ appearance of "syslog" in it. */
 else
   {
   int sep = ':';              /* Not variable - outside scripts use */
-  uschar *p = log_file_path;
+  const uschar *p = log_file_path;
   name = US"log";


/* An empty log_file_path means "use the default". This is the same as an
empty item in a list. */

   if (*p == 0) p = US":";
-  while ((path = string_nextinlist(&p, &sep, buffer, sizeof(buffer))) != NULL)
-    {
-    if (Ustrcmp(path, "syslog") != 0) break;
-    }
+  while ((path = string_nextinlist(&p, &sep, buffer, sizeof(buffer))))
+    if (Ustrcmp(path, "syslog") != 0)
+      break;


   if (path == NULL)  /* No log files */
     {
@@ -1011,7 +1010,7 @@ if (acl_removed_headers != NULL)


   for (h = header_list; h != NULL; h = h->next) if (h->type != htype_old)
     {
-    uschar * list = acl_removed_headers;
+    const uschar * list = acl_removed_headers;
     int sep = ':';         /* This is specified as a colon-separated list */
     uschar *s;
     uschar buffer[128];
@@ -3173,7 +3172,7 @@ else
         else
           {
           int sep = 0;
-          uschar *ptr = dkim_verify_signers_expanded;
+          const uschar *ptr = dkim_verify_signers_expanded;
           uschar *item = NULL;
           uschar *seen_items = NULL;
           int     seen_items_size = 0;
@@ -3194,7 +3193,7 @@ else
               {
               uschar *seen_item = NULL;
               uschar seen_item_buf[256];
-              uschar *seen_items_list = seen_items;
+              const uschar *seen_items_list = seen_items;
               BOOL seen_this_item = FALSE;


               while ((seen_item = string_nextinlist(&seen_items_list, &sep,
@@ -4125,9 +4124,9 @@ starting. */


 if (blackholed_by != NULL)
   {
-  uschar *detail = (local_scan_data != NULL)?
-    string_printing(local_scan_data) :
-    string_sprintf("(%s discarded recipients)", blackholed_by);
+  const uschar *detail = local_scan_data
+    ? string_printing(local_scan_data)
+    : string_sprintf("(%s discarded recipients)", blackholed_by);
   log_write(0, LOG_MAIN, "=> blackhole %s%s", detail, blackhole_log_msg);
   log_write(0, LOG_MAIN, "Completed");
   message_id[0] = 0;
diff --git a/src/src/regex.c b/src/src/regex.c
index 94a867c..37e7960 100644
--- a/src/src/regex.c
+++ b/src/src/regex.c
@@ -25,9 +25,11 @@ uschar regex_match_string_buffer[1024];
 extern FILE *mime_stream;
 extern uschar *mime_current_boundary;


-int regex(uschar **listptr) {
+int
+regex(const uschar **listptr)
+{
int sep = 0;
- uschar *list = *listptr;
+ const uschar *list = *listptr;
uschar *regex_string;
uschar regex_string_buffer[1024];
unsigned long mbox_size;
@@ -138,9 +140,11 @@ int regex(uschar **listptr) {
}


-int mime_regex(uschar **listptr) {
+int
+mime_regex(const uschar **listptr)
+{
int sep = 0;
- uschar *list = *listptr;
+ const uschar *list = *listptr;
uschar *regex_string;
uschar regex_string_buffer[1024];
pcre *re;
@@ -195,7 +199,7 @@ int mime_regex(uschar **listptr) {

   /* check if the file is already decoded */
   if (mime_decoded_filename == NULL) {
-    uschar *empty = US"";
+    const uschar *empty = US"";
     /* no, decode it first */
     mime_decode(&empty);
     if (mime_decoded_filename == NULL) {
diff --git a/src/src/retry.c b/src/src/retry.c
index 55ffd5c..0b3ed59 100644
--- a/src/src/retry.c
+++ b/src/src/retry.c
@@ -29,7 +29,7 @@ Returns:        TRUE if the ultimate timeout has been reached
 */


 BOOL
-retry_ultimate_address_timeout(uschar *retry_key, uschar *domain,
+retry_ultimate_address_timeout(uschar *retry_key, const uschar *domain,
   dbdata_retry *retry_record, time_t now)
 {
 BOOL address_timeout;
@@ -122,7 +122,7 @@ Returns:    TRUE if the host has expired but is usable because
 */


 BOOL
-retry_check_address(uschar *domain, host_item *host, uschar *portstring,
+retry_check_address(const uschar *domain, host_item *host, uschar *portstring,
   BOOL include_ip_address, uschar **retry_host_key, uschar **retry_message_key)
 {
 BOOL yield = FALSE;
@@ -343,12 +343,11 @@ Returns:       pointer to retry rule, or NULL
 */


retry_config *
-retry_find_config(uschar *key, uschar *alternate, int basic_errno,
+retry_find_config(const uschar *key, const uschar *alternate, int basic_errno,
int more_errno)
{
int replace = 0;
-uschar *use_key, *use_alternate;
-uschar *colon = Ustrchr(key, ':');
+const uschar *colon = Ustrchr(key, ':');
retry_config *yield;

/* If there's a colon in the key, there are two possibilities:
@@ -357,8 +356,7 @@ retry_config *yield;

       hostname:ip+port


-    In this case, we temporarily replace the colon with a zero, to terminate
-    the string after the host name.
+    In this case, we copy the host name.


(2) This is a key for a pipe, file, or autoreply delivery, in the format

@@ -369,28 +367,22 @@ retry_config *yield;
     with a letter or a digit. In this case we want to use the original address
     to search for a retry rule. */


-if (colon != NULL)
-  {
-  if (isalnum(*key))
-    replace = ':';
-  else
-    key = Ustrrchr(key, ':') + 1;   /* Take from the last colon */
-  }
-
-if (replace == 0) colon = key + Ustrlen(key);
-*colon = 0;
+if (colon)
+  key = isalnum(*key)
+    ? string_copyn(key, colon-key)    /* the hostname */
+    : Ustrrchr(key, ':') + 1;        /* Take from the last colon */


/* Sort out the keys */

-use_key = (Ustrchr(key, '@') != NULL)? key : string_sprintf("*@%s", key);
-use_alternate = (alternate == NULL)? NULL : string_sprintf("*@%s", alternate);
+if (!Ustrchr(key, '@')) key = string_sprintf("*@%s", key);
+if (alternate)    alternate = string_sprintf("*@%s", alternate);


/* Scan the configured retry items. */

for (yield = retries; yield != NULL; yield = yield->next)
{
- uschar *plist = yield->pattern;
- uschar *slist = yield->senders;
+ const uschar *plist = yield->pattern;
+ const uschar *slist = yield->senders;

/* If a specific error is set for this item, check that we are handling that
specific error, and if so, check any additional error information if
@@ -489,15 +481,14 @@ for (yield = retries; yield != NULL; yield = yield->next)
/* Check for a match between the address list item at the start of this retry
rule and either the main or alternate keys. */

-  if (match_address_list(use_key, TRUE, TRUE, &plist, NULL, -1, UCHAR_MAX+1,
+  if (match_address_list(key, TRUE, TRUE, &plist, NULL, -1, UCHAR_MAX+1,
         NULL) == OK ||
-     (use_alternate != NULL &&
-      match_address_list(use_alternate, TRUE, TRUE, &plist, NULL, -1,
+     (alternate != NULL &&
+      match_address_list(alternate, TRUE, TRUE, &plist, NULL, -1,
         UCHAR_MAX+1, NULL) == OK))
     break;
   }


-*colon = replace;
return yield;
}

@@ -665,7 +656,7 @@ for (i = 0; i < 3; i++)

         message = (rti->basic_errno > 0)? US strerror(rti->basic_errno) :
           (rti->message == NULL)?
-          US"unknown error" : string_printing(rti->message);
+          US"unknown error" : US string_printing(rti->message);
         message_length = Ustrlen(message);
         if (message_length > 150) message_length = 150;


diff --git a/src/src/rewrite.c b/src/src/rewrite.c
index f9d29c0..9ce2785 100644
--- a/src/src/rewrite.c
+++ b/src/src/rewrite.c
@@ -118,7 +118,8 @@ for (rule = rewrite_rules;
{
int start, end, pdomain;
int count = 0;
- uschar *save_localpart, *save_domain;
+ uschar *save_localpart;
+ const uschar *save_domain;
uschar *error, *new, *newparsed;

   /* Ensure that the flag matches the flags in the rule. */
@@ -162,7 +163,7 @@ for (rule = rewrite_rules;
     /* Use the general function for matching an address against a list (here
     just one item, so use the "impossible value" separator UCHAR_MAX+1). */


-    if (match_address_list(subject, FALSE, TRUE, &(rule->key), NULL, 0,
+    if (match_address_list(subject, FALSE, TRUE, CUSS &(rule->key), NULL, 0,
         UCHAR_MAX + 1, NULL) != OK)
       continue;


@@ -292,7 +293,7 @@ for (rule = rewrite_rules;
         {
         uschar *p1 = new + start - 1;
         uschar *p2 = new + end + 1;
-        uschar *pf1, *pf2;
+        const uschar *pf1, *pf2;
         uschar buff1[256], buff2[256];


         while (p1 > new && p1[-1] == ' ') p1--;
@@ -449,8 +450,9 @@ Returns:         NULL if header unchanged; otherwise the rewritten header
 */


 static header_line *
-rewrite_one_header(header_line *h, int flag, uschar *routed_old,
-  uschar *routed_new, rewrite_rule *rewrite_rules, int existflags, BOOL replace)
+rewrite_one_header(header_line *h, int flag,
+  const uschar *routed_old, const uschar *routed_new,
+  rewrite_rule *rewrite_rules, int existflags, BOOL replace)
 {
 int lastnewline = 0;
 header_line *newh = NULL;
@@ -717,7 +719,8 @@ Returns:         NULL if header unchanged; otherwise the rewritten header
 */


 header_line *
-rewrite_header(header_line *h, uschar *routed_old, uschar *routed_new,
+rewrite_header(header_line *h,
+  const uschar *routed_old, const uschar *routed_new,
   rewrite_rule *rewrite_rules, int existflags, BOOL replace)
 {
 switch (h->type)
diff --git a/src/src/route.c b/src/src/route.c
index 0950304..764f0a1 100644
--- a/src/src/route.c
+++ b/src/src/route.c
@@ -319,11 +319,11 @@ Returns:        length of matching prefix or zero
 */


int
-route_check_prefix(uschar *local_part, uschar *prefixes)
+route_check_prefix(const uschar *local_part, const uschar *prefixes)
{
int sep = 0;
uschar *prefix;
-uschar *listptr = prefixes;
+const uschar *listptr = prefixes;
uschar prebuf[64];

 while ((prefix = string_nextinlist(&listptr, &sep, prebuf, sizeof(prebuf)))
@@ -332,7 +332,7 @@ while ((prefix = string_nextinlist(&listptr, &sep, prebuf, sizeof(prebuf)))
   int plen = Ustrlen(prefix);
   if (prefix[0] == '*')
     {
-    uschar *p;
+    const uschar *p;
     prefix++;
     for (p = local_part + Ustrlen(local_part) - (--plen);
          p >= local_part; p--)
@@ -363,12 +363,12 @@ Returns:        length of matching suffix or zero
 */


int
-route_check_suffix(uschar *local_part, uschar *suffixes)
+route_check_suffix(const uschar *local_part, const uschar *suffixes)
{
int sep = 0;
int alen = Ustrlen(local_part);
uschar *suffix;
-uschar *listptr = suffixes;
+const uschar *listptr = suffixes;
uschar sufbuf[64];

 while ((suffix = string_nextinlist(&listptr, &sep, sufbuf, sizeof(sufbuf)))
@@ -377,7 +377,7 @@ while ((suffix = string_nextinlist(&listptr, &sep, sufbuf, sizeof(sufbuf)))
   int slen = Ustrlen(suffix);
   if (suffix[slen-1] == '*')
     {
-    uschar *p, *pend;
+    const uschar *p, *pend;
     pend = local_part + alen - (--slen) + 1;
     for (p = local_part; p < pend; p++)
       if (strncmpic(suffix, p, slen) == 0) return alen - (p - local_part);
@@ -420,9 +420,9 @@ Returns:         OK     item is in list
 */


static int
-route_check_dls(uschar *rname, uschar *type, uschar *list, tree_node
- **anchorptr, unsigned int *cache_bits, int listtype, uschar *domloc,
- uschar **ldata, BOOL caseless, uschar **perror)
+route_check_dls(uschar *rname, uschar *type, const uschar *list,
+ tree_node **anchorptr, unsigned int *cache_bits, int listtype,
+ const uschar *domloc, const uschar **ldata, BOOL caseless, uschar **perror)
{
int rc;

@@ -442,7 +442,7 @@ else
   {
   uschar *address = (sender_address == NULL)? US"" : sender_address;
   rc = match_address_list(address, TRUE, TRUE, &list, cache_bits, -1, 0,
-    &sender_data);
+    CUSS &sender_data);
   }


 switch(rc)
@@ -570,14 +570,15 @@ Returns:   OK if s == NULL or all tests are as required
            SKIP otherwise
 */


-int
-check_files(uschar *s, uschar **perror)
+static int
+check_files(const uschar *s, uschar **perror)
 {
 int sep = 0;              /* List has default separators */
 uid_t uid = 0;            /* For picky compilers */
 gid_t gid = 0;            /* For picky compilers */
 BOOL ugid_set = FALSE;
-uschar *check, *listptr;
+const uschar *listptr;
+uschar *check;
 uschar buffer[1024];


if (s == NULL) return OK;
@@ -585,8 +586,7 @@ if (s == NULL) return OK;
DEBUG(D_route) debug_printf("checking require_files\n");

 listptr = s;
-while ((check = string_nextinlist(&listptr, &sep, buffer, sizeof(buffer)))
-        != NULL)
+while ((check = string_nextinlist(&listptr, &sep, buffer, sizeof(buffer))))
   {
   int rc;
   int eacces_code = 0;
@@ -885,8 +885,8 @@ if (verify == v_expn && !r->expn)
 /* Skip this router if there's a domain mismatch. */


 if ((rc = route_check_dls(r->name, US"domains", r->domains, &domainlist_anchor,
-     addr->domain_cache, TRUE, addr->domain, &deliver_domain_data, MCL_DOMAIN,
-     perror)) != OK)
+     addr->domain_cache, TRUE, addr->domain, CUSS &deliver_domain_data,
+     MCL_DOMAIN, perror)) != OK)
   return rc;


/* Skip this router if there's a local part mismatch. We want to pass over the
@@ -913,8 +913,8 @@ else

 if ((rc = route_check_dls(r->name, US"local_parts", r->local_parts,
        &localpartlist_anchor, localpart_cache, MCL_LOCALPART,
-       check_local_part, &deliver_localpart_data, !r->caseful_local_part,
-       perror)) != OK)
+       check_local_part, CUSS &deliver_localpart_data,
+       !r->caseful_local_part, perror)) != OK)
   return rc;


/* If the check_local_user option is set, check that the local_part is the
@@ -1088,7 +1088,7 @@ static uschar lastgecos[128];
static uschar lastshell[128];

BOOL
-route_finduser(uschar *s, struct passwd **pw, uid_t *return_uid)
+route_finduser(const uschar *s, struct passwd **pw, uid_t *return_uid)
{
BOOL cache_set = (Ustrcmp(lastname, s) == 0);

@@ -1437,7 +1437,7 @@ route_address(address_item *addr, address_item **paddr_local,
int yield = OK;
BOOL unseen;
router_instance *r, *nextr;
-uschar *old_domain = addr->domain;
+const uschar *old_domain = addr->domain;

HDEBUG(D_route)
{
diff --git a/src/src/routers/dnslookup.c b/src/src/routers/dnslookup.c
index c8fd3f9..aa5b924 100644
--- a/src/src/routers/dnslookup.c
+++ b/src/src/routers/dnslookup.c
@@ -146,10 +146,10 @@ dnslookup_router_options_block *ob =
(dnslookup_router_options_block *)(rblock->options_block);
uschar *srv_service = NULL;
uschar *widen = NULL;
-uschar *pre_widen = addr->domain;
-uschar *post_widen = NULL;
-uschar *fully_qualified_name;
-uschar *listptr;
+const uschar *pre_widen = addr->domain;
+const uschar *post_widen = NULL;
+const uschar *fully_qualified_name;
+const uschar *listptr;
uschar widen_buffer[256];

 addr_new = addr_new;          /* Keep picky compilers happy */
@@ -266,7 +266,7 @@ for (;;)
     if (ob->search_parents) flags |= HOST_FIND_SEARCH_PARENTS;
     }


-  rc = host_find_bydns(&h, rblock->ignore_target_hosts, flags, srv_service,
+  rc = host_find_bydns(&h, CUS rblock->ignore_target_hosts, flags, srv_service,
     ob->srv_fail_domains, ob->mx_fail_domains,
     ob->dnssec_request_domains, ob->dnssec_require_domains,
     &fully_qualified_name, &removed);
@@ -279,7 +279,8 @@ for (;;)
   if ((rc == HOST_FOUND || rc == HOST_FOUND_LOCAL) && h.mx < 0 &&
        ob->mx_domains != NULL)
     {
-    switch(match_isinlist(fully_qualified_name, &(ob->mx_domains), 0,
+    switch(match_isinlist(fully_qualified_name,
+          (const uschar **)&(ob->mx_domains), 0,
           &domainlist_anchor, addr->domain_cache, MCL_DOMAIN, TRUE, NULL))
       {
       case DEFER:
diff --git a/src/src/routers/ipliteral.c b/src/src/routers/ipliteral.c
index 7be96e5..e9c1865 100644
--- a/src/src/routers/ipliteral.c
+++ b/src/src/routers/ipliteral.c
@@ -99,8 +99,8 @@ ipliteral_router_options_block *ob =
   (ipliteral_router_options_block *)(rblock->options_block);
 */
 host_item *h;
-uschar *domain = addr->domain;
-uschar *ip;
+const uschar *domain = addr->domain;
+const uschar *ip;
 int len = Ustrlen(domain);
 int rc, ipv;


@@ -116,29 +116,23 @@ declines. Otherwise route to the single IP address, setting the host name to
"(unnamed)". */

if (domain[0] != '[' || domain[len-1] != ']') return DECLINE;
-domain[len-1] = 0; /* temporarily */
-
-ip = domain + 1;
+ip = string_copyn(domain+1, len-2);
if (strncmpic(ip, US"IPV6:", 5) == 0 || strncmpic(ip, US"IPV4:", 5) == 0)
ip += 5;

ipv = string_is_ip_address(ip, NULL);
if (ipv == 0 || (disable_ipv6 && ipv == 6))
- {
- domain[len-1] = ']';
return DECLINE;
- }

/* It seems unlikely that ignore_target_hosts will be used with this router,
but if it is set, it should probably work. */

-if (verify_check_this_host(&(rblock->ignore_target_hosts), NULL, domain,
-      ip, NULL) == OK)
+if (verify_check_this_host(CUSS&rblock->ignore_target_hosts,
+           NULL, domain, ip, NULL) == OK)
   {
   DEBUG(D_route)
       debug_printf("%s is in ignore_target_hosts\n", ip);
   addr->message = US"IP literal host explicitly ignored";
-  domain[len-1] = ']';
   return DECLINE;
   }


@@ -149,8 +143,7 @@ h = store_get(sizeof(host_item));
 h->next = NULL;
 h->address = string_copy(ip);
 h->port = PORT_NONE;
-domain[len-1] = ']';   /* restore */
-h->name = string_copy(domain);
+h->name = domain;
 h->mx = MX_NONE;
 h->status = hstatus_unknown;
 h->why = hwhy_unknown;
diff --git a/src/src/routers/iplookup.c b/src/src/routers/iplookup.c
index 3728007..d48cfb9 100644
--- a/src/src/routers/iplookup.c
+++ b/src/src/routers/iplookup.c
@@ -143,7 +143,8 @@ iplookup_router_entry(
 {
 uschar *query = NULL;
 uschar *reply;
-uschar *hostname, *reroute, *domain, *listptr;
+uschar *hostname, *reroute, *domain;
+const uschar *listptr;
 uschar host_buffer[256];
 host_item *host = store_get(sizeof(host_item));
 address_item *new_addr;
diff --git a/src/src/routers/manualroute.c b/src/src/routers/manualroute.c
index cb047e2..7cbe5db 100644
--- a/src/src/routers/manualroute.c
+++ b/src/src/routers/manualroute.c
@@ -139,8 +139,8 @@ Returns:    FALSE if domain expected and string is empty;
 */


static BOOL
-parse_route_item(uschar *s, uschar **domain, uschar **hostlist,
- uschar **options)
+parse_route_item(const uschar *s, const uschar **domain, const uschar **hostlist,
+ const uschar **options)
{
while (*s != 0 && isspace(*s)) s++;

@@ -226,9 +226,11 @@ manualroute_router_entry(
 {
 int rc, lookup_type;
 uschar *route_item = NULL;
-uschar *options = NULL;
-uschar *hostlist = NULL;
-uschar *domain, *newhostlist, *listptr;
+const uschar *options = NULL;
+const uschar *hostlist = NULL;
+const uschar *domain;
+uschar *newhostlist;
+const uschar *listptr;
 manualroute_router_options_block *ob =
   (manualroute_router_options_block *)(rblock->options_block);
 transport_instance *transport = NULL;
@@ -260,7 +262,7 @@ if (ob->route_list != NULL)
     /* Check the current domain; if it matches, break the loop */


     if ((rc = match_isinlist(addr->domain, &domain, UCHAR_MAX+1,
-           &domainlist_anchor, NULL, MCL_DOMAIN, TRUE, &lookup_value)) == OK)
+           &domainlist_anchor, NULL, MCL_DOMAIN, TRUE, CUSS &lookup_value)) == OK)
       break;


     /* If there was a problem doing the check, defer */
@@ -318,28 +320,26 @@ lookup_type = lk_default;


while (*options != 0)
{
- int term;
- uschar *s = options;
+ unsigned n;
+ const uschar *s = options;
while (*options != 0 && !isspace(*options)) options++;
- term = *options;
- *options = 0;
+ n = options-s;

-  if (Ustrcmp(s, "randomize") == 0) randomize = TRUE;
-  else if (Ustrcmp(s, "no_randomize") == 0) randomize = FALSE;
-  else if (Ustrcmp(s, "byname") == 0) lookup_type = lk_byname;
-  else if (Ustrcmp(s, "bydns") == 0) lookup_type = lk_bydns;
+  if (Ustrncmp(s, "randomize", n) == 0) randomize = TRUE;
+  else if (Ustrncmp(s, "no_randomize", n) == 0) randomize = FALSE;
+  else if (Ustrncmp(s, "byname", n) == 0) lookup_type = lk_byname;
+  else if (Ustrncmp(s, "bydns", n) == 0) lookup_type = lk_bydns;
   else
     {
     transport_instance *t;
     for (t = transports; t != NULL; t = t->next)
-      {
       if (Ustrcmp(t->name, s) == 0)
         {
         transport = t;
         individual_transport_set = TRUE;
         break;
         }
-      }
+
     if (t == NULL)
       {
       s = string_sprintf("unknown routing option or transport name \"%s\"", s);
@@ -349,7 +349,7 @@ while (*options != 0)
       }
     }


-  if (term != 0)
+  if (*options)
     {
     options++;
     while (*options != 0 && isspace(*options)) options++;
diff --git a/src/src/routers/queryprogram.c b/src/src/routers/queryprogram.c
index 11e1fdc..bf0f4c4 100644
--- a/src/src/routers/queryprogram.c
+++ b/src/src/routers/queryprogram.c
@@ -192,7 +192,7 @@ int fd_in, fd_out, len, rc;
 pid_t pid;
 struct passwd *upw = NULL;
 uschar buffer[1024];
-uschar **argvptr;
+const uschar **argvptr;
 uschar *rword, *rdata, *s;
 address_item_propagated addr_prop;
 queryprogram_router_options_block *ob =
diff --git a/src/src/routers/redirect.c b/src/src/routers/redirect.c
index c6705e5..0189d23 100644
--- a/src/src/routers/redirect.c
+++ b/src/src/routers/redirect.c
@@ -517,7 +517,7 @@ int redirect_router_entry(
 redirect_router_options_block *ob =
   (redirect_router_options_block *)(rblock->options_block);
 address_item *generated = NULL;
-uschar *save_qualify_domain_recipient = qualify_domain_recipient;
+const uschar *save_qualify_domain_recipient = qualify_domain_recipient;
 uschar *discarded = US"discarded";
 address_item_propagated addr_prop;
 error_block *eblock = NULL;
diff --git a/src/src/routers/rf_change_domain.c b/src/src/routers/rf_change_domain.c
index 2343e3e..e891b84 100644
--- a/src/src/routers/rf_change_domain.c
+++ b/src/src/routers/rf_change_domain.c
@@ -32,7 +32,7 @@ Returns:      nothing
 */


 void
-rf_change_domain(address_item *addr, uschar *domain, BOOL rewrite,
+rf_change_domain(address_item *addr, const uschar *domain, BOOL rewrite,
   address_item **addr_new)
 {
 address_item *parent = store_get(sizeof(address_item));
diff --git a/src/src/routers/rf_functions.h b/src/src/routers/rf_functions.h
index 29f37cf..b6ce0f6 100644
--- a/src/src/routers/rf_functions.h
+++ b/src/src/routers/rf_functions.h
@@ -11,7 +11,7 @@
 extern void rf_add_generated(router_instance *, address_item **,
               address_item *, address_item *, uschar *, header_line *,
               uschar *, ugid_block *, struct passwd *);
-extern void rf_change_domain(address_item *, uschar *, BOOL, address_item **);
+extern void rf_change_domain(address_item *, const uschar *, BOOL, address_item **);
 extern uschar *rf_expand_data(address_item *, uschar *, int *);
 extern int  rf_get_errors_address(address_item *, router_instance *,
               BOOL, uschar **);
diff --git a/src/src/routers/rf_get_errors_address.c b/src/src/routers/rf_get_errors_address.c
index 457397a..a0ea9f2 100644
--- a/src/src/routers/rf_get_errors_address.c
+++ b/src/src/routers/rf_get_errors_address.c
@@ -84,8 +84,8 @@ else
   BOOL save_address_test_mode = address_test_mode;
   int save1 = 0;
   int i;
-  uschar ***p;
-  uschar *address_expansions_save[ADDRESS_EXPANSIONS_COUNT];
+  const uschar ***p;
+  const uschar *address_expansions_save[ADDRESS_EXPANSIONS_COUNT];
   address_item *snew = deliver_make_addr(s, FALSE);


if (sender_address != NULL)
diff --git a/src/src/routers/rf_get_munge_headers.c b/src/src/routers/rf_get_munge_headers.c
index 3125f31..a6c039e 100644
--- a/src/src/routers/rf_get_munge_headers.c
+++ b/src/src/routers/rf_get_munge_headers.c
@@ -36,7 +36,7 @@ rf_get_munge_headers(address_item *addr, router_instance *rblock,

if (rblock->extra_headers)
{
- uschar * list = rblock->extra_headers;
+ const uschar * list = rblock->extra_headers;
int sep = '\n';
uschar * s;
int slen;
@@ -87,7 +87,7 @@ if (rblock->extra_headers)
/* Expand items from colon-sep list separately, then build new list */
if (rblock->remove_headers)
{
- uschar * list = rblock->remove_headers;
+ const uschar * list = rblock->remove_headers;
int sep = ':';
uschar * s;

diff --git a/src/src/routers/rf_lookup_hostlist.c b/src/src/routers/rf_lookup_hostlist.c
index 0eae31e..28d4fc4 100644
--- a/src/src/routers/rf_lookup_hostlist.c
+++ b/src/src/routers/rf_lookup_hostlist.c
@@ -64,7 +64,7 @@ list of MX hosts. If the first host is the local host, act according to the
prev = NULL;
for (h = addr->host_list; h != NULL; h = next_h)
{
- uschar *canonical_name;
+ const uschar *canonical_name;
int rc, len, port;

   next_h = h->next;
diff --git a/src/src/search.c b/src/src/search.c
index 15db52a..8a3f928 100644
--- a/src/src/search.c
+++ b/src/src/search.c
@@ -62,7 +62,7 @@ Returns:     +ve => valid lookup name; value is offset in lookup_list
 */


 int
-search_findtype(uschar *name, int len)
+search_findtype(const uschar *name, int len)
 {
 int bot = 0;
 int top = lookup_list_count;
@@ -121,12 +121,12 @@ Returns:     +ve => valid lookup name; value is offset in lookup_list
 */


int
-search_findtype_partial(uschar *name, int *ptypeptr, uschar **ptypeaff,
+search_findtype_partial(const uschar *name, int *ptypeptr, const uschar **ptypeaff,
int *afflen, int *starflags)
{
int len, stype;
int pv = -1;
-uschar *ss = name;
+const uschar *ss = name;

 *starflags = 0;
 *ptypeaff = NULL;
@@ -601,7 +601,7 @@ Returns:         a pointer to a dynamic string containing the answer,


 uschar *
 search_find(void *handle, uschar *filename, uschar *keystring, int partial,
-  uschar *affix, int affixlen, int starflags, int *expand_setup)
+  const uschar *affix, int affixlen, int starflags, int *expand_setup)
 {
 tree_node *t = (tree_node *)handle;
 BOOL set_null_wild = FALSE;
diff --git a/src/src/sieve.c b/src/src/sieve.c
index 9261b46..262367e 100644
--- a/src/src/sieve.c
+++ b/src/src/sieve.c
@@ -2737,8 +2737,8 @@ Returns:      2                success by stop
               1                other success
               -1               syntax or execution error
 */
-static int parse_commands(struct Sieve *filter, int exec,
-  address_item **generated)
+static int
+parse_commands(struct Sieve *filter, int exec, address_item **generated)
 {
 while (*filter->pc)
   {
@@ -3360,7 +3360,8 @@ while (*filter->pc)
           /* Allocation is larger than neccessary, but enough even for split MIME words */
           buffer_capacity=32+4*subject.length;
           buffer=store_get(buffer_capacity);
-          addr->reply->subject=parse_quote_2047(subject.character, subject.length, US"utf-8", buffer, buffer_capacity, TRUE);
+      /* deconst cast safe as we pass in a non-const item */
+          addr->reply->subject = US parse_quote_2047(subject.character, subject.length, US"utf-8", buffer, buffer_capacity, TRUE);
           addr->reply->oncelog=once;
           addr->reply->once_repeat=days*86400;


diff --git a/src/src/smtp_in.c b/src/src/smtp_in.c
index 4e4cdb8..58ca02d 100644
--- a/src/src/smtp_in.c
+++ b/src/src/smtp_in.c
@@ -3132,7 +3132,7 @@ value. The values are 2 larger than the required yield of the function. */

while (done <= 0)
{
- uschar **argv;
+ const uschar **argv;
uschar *etrn_command;
uschar *etrn_serialize_key;
uschar *errmess;
@@ -3140,7 +3140,7 @@ while (done <= 0)
uschar *user_msg = NULL;
uschar *recipient = NULL;
uschar *hello = NULL;
- uschar *set_id = NULL;
+ const uschar *set_id = NULL;
uschar *s, *ss;
BOOL was_rej_mail = FALSE;
BOOL was_rcpt = FALSE;
@@ -3424,7 +3424,7 @@ while (done <= 0)

       if (sender_host_name == NULL &&
            (deliver_domain = sender_helo_name,  /* set $domain */
-            match_isinlist(sender_helo_name, &helo_lookup_domains, 0,
+            match_isinlist(sender_helo_name, CUSS &helo_lookup_domains, 0,
               &domainlist_anchor, NULL, MCL_DOMAIN, TRUE, NULL)) == OK)
         (void)host_name_lookup();


@@ -4850,7 +4850,7 @@ while (done <= 0)
         break;
         }
       etrn_command = US"exim -R";
-      argv = child_exec_exim(CEE_RETURN_ARGV, TRUE, NULL, TRUE, 2, US"-R",
+      argv = CUSS child_exec_exim(CEE_RETURN_ARGV, TRUE, NULL, TRUE, 2, US"-R",
         smtp_cmd_data);
       }


diff --git a/src/src/smtp_out.c b/src/src/smtp_out.c
index 530fcfe..8147b61 100644
--- a/src/src/smtp_out.c
+++ b/src/src/smtp_out.c
@@ -37,7 +37,7 @@ BOOL
smtp_get_interface(uschar *istring, int host_af, address_item *addr,
BOOL *changed, uschar **interface, uschar *msg)
{
-uschar *expint;
+const uschar * expint;
uschar *iface;
int sep = 0;

diff --git a/src/src/spam.c b/src/src/spam.c
index 8817af0..99e524d 100644
--- a/src/src/spam.c
+++ b/src/src/spam.c
@@ -177,10 +177,10 @@ return -1;


int
-spam(uschar **listptr)
+spam(const uschar **listptr)
{
int sep = 0;
-uschar *list = *listptr;
+const uschar *list = *listptr;
uschar *user_name;
uschar user_name_buffer[128];
unsigned long mbox_size;
@@ -276,7 +276,7 @@ start = time(NULL);
int num_servers = 0;
int current_server;
uschar *address;
- uschar *spamd_address_list_ptr = spamd_address_work;
+ const uschar *spamd_address_list_ptr = spamd_address_work;
spamd_address_container * spamd_address_vector[32];
spamd_address_container * sd;

@@ -285,7 +285,7 @@ start = time(NULL);
   while ((address = string_nextinlist(&spamd_address_list_ptr, &sep,
                       NULL, 0)) != NULL)
     {
-    uschar * sublist;
+    const uschar * sublist;
     int sublist_sep = -(int)' ';    /* default space-sep */
     unsigned args;
     uschar * s;
diff --git a/src/src/string.c b/src/src/string.c
index f4e44ca..76e47f4 100644
--- a/src/src/string.c
+++ b/src/src/string.c
@@ -224,13 +224,13 @@ Returns:   the value of the character escape
 */


 int
-string_interpret_escape(uschar **pp)
+string_interpret_escape(const uschar **pp)
 {
 #ifdef COMPILE_UTILITY
 const uschar *hex_digits= CUS"0123456789abcdef";
 #endif
 int ch;
-uschar *p = *pp;
+const uschar *p = *pp;
 ch = *(++p);
 if (isdigit(ch) && ch != '8' && ch != '9')
   {
@@ -284,12 +284,12 @@ Arguments:
 Returns:        string with non-printers encoded as printing sequences
 */


-uschar *
-string_printing2(uschar *s, BOOL allow_tab)
+const uschar *
+string_printing2(const uschar *s, BOOL allow_tab)
{
int nonprintcount = 0;
int length = 0;
-uschar *t = s;
+const uschar *t = s;
uschar *ss, *tt;

 while (*t != 0)
@@ -374,7 +374,7 @@ while (*p)
   {
   if (*p == '\\')
     {
-    *q++ = string_interpret_escape(&p);
+    *q++ = string_interpret_escape((const uschar **)&p);
     p++;
     }
   else
@@ -437,7 +437,7 @@ Returns:  copy of string in new store
 */


uschar *
-string_copy_malloc(uschar *s)
+string_copy_malloc(const uschar *s)
{
int len = Ustrlen(s) + 1;
uschar *ss = store_malloc(len);
@@ -639,9 +639,9 @@ Returns: the new string
*/

uschar *
-string_dequote(uschar **sptr)
+string_dequote(const uschar **sptr)
{
-uschar *s = *sptr;
+const uschar *s = *sptr;
uschar *t, *yield;

 /* First find the end of the string */
@@ -868,10 +868,10 @@ Returns:     pointer to buffer, containing the next substring,
 */


uschar *
-string_nextinlist(uschar **listptr, int *separator, uschar *buffer, int buflen)
+string_nextinlist(const uschar **listptr, int *separator, uschar *buffer, int buflen)
{
-register int sep = *separator;
-register uschar *s = *listptr;
+int sep = *separator;
+const uschar *s = *listptr;
BOOL sep_is_special;

if (s == NULL) return NULL;
@@ -928,7 +928,7 @@ else
{
int size = 0;
int ptr = 0;
- uschar *ss;
+ const uschar *ss;

/* We know that *s != 0 at this point. However, it might be pointing to a
separator, which could indicate an empty string, or (if an ispunct()
diff --git a/src/src/structs.h b/src/src/structs.h
index 3cdf12a..85207b5 100644
--- a/src/src/structs.h
+++ b/src/src/structs.h
@@ -59,8 +59,8 @@ typedef enum {DS_UNK=-1, DS_NO, DS_YES} dnssec_status_t;

 typedef struct host_item {
   struct host_item *next;
-  uschar *name;                   /* Host name */
-  uschar *address;                /* IP address in text form */
+  const uschar *name;             /* Host name */
+  const uschar *address;          /* IP address in text form */
   int     port;                   /* port value in host order (if SRV lookup) */
   int     mx;                     /* MX value if found via MX records */
   int     sort_key;               /* MX*1000 plus random "fraction" */
@@ -530,7 +530,7 @@ typedef struct address_item {
   uschar *local_part;             /* points to cc or lc version */
   uschar *prefix;                 /* stripped prefix of local part */
   uschar *suffix;                 /* stripped suffix of local part */
-  uschar *domain;                 /* working domain (lower cased) */
+  const uschar *domain;           /* working domain (lower cased) */


   uschar *address_retry_key;      /* retry key including full address */
   uschar *domain_retry_key;       /* retry key for domain only */
@@ -597,7 +597,7 @@ typedef struct {


typedef struct error_block {
struct error_block *next;
- uschar *text1;
+ const uschar *text1;
uschar *text2;
} error_block;

@@ -750,9 +750,9 @@ typedef struct redirect_block {
/* Structure for passing arguments to check_host() */

typedef struct check_host_block {
- uschar *host_name;
- uschar *host_address;
- uschar *host_ipv4;
+ const uschar *host_name;
+ const uschar *host_address;
+ const uschar *host_ipv4;
BOOL negative;
} check_host_block;

@@ -768,7 +768,7 @@ typedef struct namedlist_cacheblock {
/* Structure for holding data for an entry in a named list */

 typedef struct namedlist_block {
-  uschar *string;                    /* the list string */
+  const uschar *string;              /* the list string */
   namedlist_cacheblock *cache_data;  /* cached domain_data or localpart_data */
   int number;                        /* the number of the list for caching */
 } namedlist_block;
diff --git a/src/src/tls-gnu.c b/src/src/tls-gnu.c
index 8b28d55..6162cfa 100644
--- a/src/src/tls-gnu.c
+++ b/src/src/tls-gnu.c
@@ -120,7 +120,7 @@ typedef struct exim_gnutls_state {
   uschar *exp_tls_crl;
   uschar *exp_tls_require_ciphers;
   uschar *exp_tls_ocsp_file;
-  uschar *exp_tls_verify_cert_hostnames;
+  const uschar *exp_tls_verify_cert_hostnames;
 #ifdef EXPERIMENTAL_EVENT
   uschar *event_action;
 #endif
@@ -1398,7 +1398,7 @@ else
   if (state->exp_tls_verify_cert_hostnames)
     {
     int sep = 0;
-    uschar * list = state->exp_tls_verify_cert_hostnames;
+    const uschar * list = state->exp_tls_verify_cert_hostnames;
     uschar * name;
     while (name = string_nextinlist(&list, &sep, NULL, 0))
       if (gnutls_x509_crt_check_hostname(state->tlsp->peercert, CS name))
diff --git a/src/src/tls-openssl.c b/src/src/tls-openssl.c
index 24ae3ea..f28b2fb 100644
--- a/src/src/tls-openssl.c
+++ b/src/src/tls-openssl.c
@@ -123,7 +123,7 @@ typedef struct tls_ext_ctx_cb {
   uschar *server_cipher_list;
   /* only passed down to tls_error: */
   host_item *host;
-  uschar * verify_cert_hostnames;
+  const uschar * verify_cert_hostnames;
 #ifdef EXPERIMENTAL_EVENT
   uschar * event_action;
 #endif
@@ -351,7 +351,7 @@ else if (depth != 0)
   }
 else
   {
-  uschar * verify_cert_hostnames;
+  const uschar * verify_cert_hostnames;


   tlsp->peerdn = txt;
   tlsp->peercert = X509_dup(cert);
@@ -369,7 +369,7 @@ else
 #  endif
     {
     int sep = 0;
-    uschar * list = verify_cert_hostnames;
+    const uschar * list = verify_cert_hostnames;
     uschar * name;
     int rc;
     while ((name = string_nextinlist(&list, &sep, NULL, 0)))
diff --git a/src/src/tls.c b/src/src/tls.c
index 1182379..f1371f0 100644
--- a/src/src/tls.c
+++ b/src/src/tls.c
@@ -254,7 +254,7 @@ Return:
 */


 uschar *
-tls_field_from_dn(uschar * dn, uschar * mod)
+tls_field_from_dn(uschar * dn, const uschar * mod)
 {
 int insep = ',';
 uschar outsep = '\n';
@@ -272,7 +272,7 @@ while ((ele = string_nextinlist(&mod, &insep, NULL, 0)))
 dn_to_list(dn);
 insep = ',';
 len = match ? Ustrlen(match) : -1;
-while ((ele = string_nextinlist(&dn, &insep, NULL, 0)))
+while ((ele = string_nextinlist(CUSS &dn, &insep, NULL, 0)))
   if (  !match
      || Ustrncmp(ele, match, len) == 0 && ele[len] == '='
      )
@@ -313,7 +313,7 @@ Returns:
 */


 BOOL
-tls_is_name_for_cert(uschar * namelist, void * cert)
+tls_is_name_for_cert(const uschar * namelist, void * cert)
 {
 uschar * altnames = tls_cert_subject_altname(cert, US"dns");
 uschar * subjdn;
@@ -326,7 +326,7 @@ if ((altnames = tls_cert_subject_altname(cert, US"dns")))
   int alt_sep = '\n';
   while ((cmpname = string_nextinlist(&namelist, &cmp_sep, NULL, 0)))
     {
-    uschar * an = altnames;
+    const uschar * an = altnames;
     while ((certname = string_nextinlist(&an, &alt_sep, NULL, 0)))
       if (is_name_match(cmpname, certname))
     return TRUE;
@@ -340,7 +340,7 @@ else if ((subjdn = tls_cert_subject(cert, NULL)))
   dn_to_list(subjdn);
   while ((cmpname = string_nextinlist(&namelist, &cmp_sep, NULL, 0)))
     {
-    uschar * sn = subjdn;
+    const uschar * sn = subjdn;
     while ((certname = string_nextinlist(&sn, &sn_sep, NULL, 0)))
       if (  *certname++ == 'C'
      && *certname++ == 'N'
diff --git a/src/src/tlscert-gnu.c b/src/src/tlscert-gnu.c
index ffe9588..dd48d6f 100644
--- a/src/src/tlscert-gnu.c
+++ b/src/src/tlscert-gnu.c
@@ -27,7 +27,7 @@ tls_export_cert(uschar * buf, size_t buflen, void * cert)
 size_t sz = buflen;
 void * reset_point = store_get(0);
 int fail;
-uschar * cp;
+const uschar * cp;


 if ((fail = gnutls_x509_crt_export((gnutls_x509_crt_t)cert,
     GNUTLS_X509_FMT_PEM, buf, &sz)))
diff --git a/src/src/transport.c b/src/src/transport.c
index 58fc4ec..fea9146 100644
--- a/src/src/transport.c
+++ b/src/src/transport.c
@@ -633,7 +633,7 @@ Then check addr->p.remove_headers too, provided that addr is not NULL. */
 for (h = header_list; h != NULL; h = h->next) if (h->type != htype_old)
   {
   int i;
-  uschar *list = remove_headers;
+  const uschar *list = remove_headers;


BOOL include_header = TRUE;

@@ -740,7 +740,7 @@ if (add_headers)
int sep = '\n';
uschar * s;

-  while ((s = string_nextinlist(&add_headers, &sep, NULL, 0)))
+  while ((s = string_nextinlist(CUSS &add_headers, &sep, NULL, 0)))
     if (!(s = expand_string(s)))
       {
       if (!expand_string_forcedfail)
@@ -1245,8 +1245,8 @@ yield = FALSE;
 write_pid = (pid_t)(-1);


 (void)fcntl(fd, F_SETFD, fcntl(fd, F_GETFD) | FD_CLOEXEC);
-filter_pid = child_open(transport_filter_argv, NULL, 077, &fd_write, &fd_read,
-  FALSE);
+filter_pid = child_open(USS transport_filter_argv, NULL, 077,
+ &fd_write, &fd_read, FALSE);
 (void)fcntl(fd, F_SETFD, fcntl(fd, F_GETFD) & ~FD_CLOEXEC);
 if (filter_pid < 0) goto TIDY_UP;      /* errno set */


@@ -1484,7 +1484,7 @@ void
 transport_update_waiting(host_item *hostlist, uschar *tpname)
 {
 uschar buffer[256];
-uschar *prevname = US"";
+const uschar *prevname = US"";
 host_item *host;
 open_db dbblock;
 open_db *dbm_file;
@@ -1630,7 +1630,7 @@ Returns:             TRUE if new_message_id set; FALSE otherwise
 */


 BOOL
-transport_check_waiting(uschar *transport_name, uschar *hostname,
+transport_check_waiting(const uschar *transport_name, const uschar *hostname,
   int local_message_max, uschar *new_message_id, BOOL *more)
 {
 dbdata_wait *host_record;
@@ -1816,8 +1816,8 @@ Returns:          FALSE if fork fails; TRUE otherwise
 */


BOOL
-transport_pass_socket(uschar *transport_name, uschar *hostname,
- uschar *hostaddress, uschar *id, int socket_fd)
+transport_pass_socket(const uschar *transport_name, const uschar *hostname,
+ const uschar *hostaddress, uschar *id, int socket_fd)
{
pid_t pid;
int status;
@@ -1827,7 +1827,7 @@ DEBUG(D_transport) debug_printf("transport_pass_socket entered\n");
if ((pid = fork()) == 0)
{
int i = 16;
- uschar **argv;
+ const uschar **argv;

/* Disconnect entirely from the parent process. If we are running in the
test harness, wait for a bit to allow the previous process time to finish,
@@ -1840,7 +1840,7 @@ if ((pid = fork()) == 0)
/* Set up the calling arguments; use the standard function for the basics,
but we have a number of extras that may be added. */

- argv = child_exec_exim(CEE_RETURN_ARGV, TRUE, &i, FALSE, 0);
+ argv = CUSS child_exec_exim(CEE_RETURN_ARGV, TRUE, &i, FALSE, 0);

   /* Call with the dsn flag */
   if (smtp_use_dsn) argv[i++] = US"-MCD";
@@ -1862,9 +1862,9 @@ if ((pid = fork()) == 0)
     }


argv[i++] = US"-MC";
- argv[i++] = transport_name;
- argv[i++] = hostname;
- argv[i++] = hostaddress;
+ argv[i++] = US transport_name;
+ argv[i++] = US hostname;
+ argv[i++] = US hostaddress;
argv[i++] = string_sprintf("%d", continue_sequence + 1);
argv[i++] = id;
argv[i++] = NULL;
@@ -1918,7 +1918,7 @@ case, no addresses are passed.

 Arguments:
   argvptr            pointer to anchor for argv vector
-  cmd                points to the command string
+  cmd                points to the command string (modified IN PLACE)
   expand_arguments   true if expansion is to occur
   expand_failed      error value to set if expansion fails; not relevant if
                      addr == NULL
@@ -1932,11 +1932,12 @@ Returns:             TRUE if all went well; otherwise an error will be
 */


 BOOL
-transport_set_up_command(uschar ***argvptr, uschar *cmd, BOOL expand_arguments,
-  int expand_failed, address_item *addr, uschar *etext, uschar **errptr)
+transport_set_up_command(const uschar ***argvptr, uschar *cmd,
+  BOOL expand_arguments, int expand_failed, address_item *addr,
+  uschar *etext, uschar **errptr)
 {
 address_item *ad;
-uschar **argv;
+const uschar **argv;
 uschar *s, *ss;
 int address_count = 0;
 int argcount = 0;
@@ -1970,7 +1971,7 @@ while (*s != 0 && argcount < max_args)
     if (*s != 0) s++;
     *ss++ = 0;
     }
-  else argv[argcount++] = string_dequote(&s);
+  else argv[argcount++] = string_copy(string_dequote(CUSS &s));
   while (isspace(*s)) s++;
   }


@@ -2099,7 +2100,8 @@ if (expand_arguments)
           if (*s != 0) s++;
           *ss++ = 0;
           }
-        else address_pipe_argv[address_pipe_argcount++] = string_dequote(&s);
+        else address_pipe_argv[address_pipe_argcount++] =
+          string_copy(string_dequote(CUSS &s));
         while (isspace(*s)) s++; /* strip space after arg */
         }


@@ -2167,9 +2169,9 @@ if (expand_arguments)

     else
       {
-      uschar *expanded_arg;
+      const uschar *expanded_arg;
       enable_dollar_recipients = allow_dollar_recipients;
-      expanded_arg = expand_string(argv[i]);
+      expanded_arg = expand_cstring(argv[i]);
       enable_dollar_recipients = FALSE;


       if (expanded_arg == NULL)
diff --git a/src/src/transports/appendfile.c b/src/src/transports/appendfile.c
index d8664be..7fd62b9 100644
--- a/src/src/transports/appendfile.c
+++ b/src/src/transports/appendfile.c
@@ -664,7 +664,7 @@ Returns:       pointer to the required transport, or NULL
 transport_instance *
 check_file_format(int cfd, transport_instance *tblock, address_item *addr)
 {
-uschar *format =
+const uschar *format =
   ((appendfile_transport_options_block *)(tblock->options_block))->file_format;
 uschar data[256];
 int len = read(cfd, data, sizeof(data));
diff --git a/src/src/transports/autoreply.c b/src/src/transports/autoreply.c
index a90a685..a719e90 100644
--- a/src/src/transports/autoreply.c
+++ b/src/src/transports/autoreply.c
@@ -157,12 +157,13 @@ if (ss == NULL)
 if (type != cke_text) for (t = ss; *t != 0; t++)
   {
   int c = *t;
+  const uschar * sp;
   if (mac_isprint(c)) continue;
   if (type == cke_hdr && c == '\n' && (t[1] == ' ' || t[1] == '\t')) continue;
-  s = string_printing(s);
+  sp = string_printing(s);
   addr->transport_return = FAIL;
   addr->message = string_sprintf("Expansion of \"%s\" in %s transport "
-    "contains non-printing character %d", s, name, c);
+    "contains non-printing character %d", sp, name, c);
   return NULL;
   }


@@ -187,7 +188,7 @@ Returns:      nothing
 */


static void
-check_never_mail(uschar **listptr, uschar *never_mail)
+check_never_mail(uschar **listptr, const uschar *never_mail)
{
uschar *s = *listptr;

@@ -379,7 +380,7 @@ remove those that match. */

if (ob->never_mail != NULL)
{
- uschar *never_mail = expand_string(ob->never_mail);
+ const uschar *never_mail = expand_string(ob->never_mail);

   if (never_mail == NULL)
     {
diff --git a/src/src/transports/lmtp.c b/src/src/transports/lmtp.c
index 84bbeb9..3bdbaa8 100644
--- a/src/src/transports/lmtp.c
+++ b/src/src/transports/lmtp.c
@@ -171,7 +171,7 @@ if (*errno_value == ERRNO_WRITEINCOMPLETE)


if (buffer[0] != 0)
{
- uschar *s = string_printing(buffer);
+ const uschar *s = string_printing(buffer);
*message = string_sprintf("LMTP error after %s: %s", big_buffer, s);
*yield = buffer[0];
return TRUE;
@@ -460,7 +460,7 @@ BOOL yield = FALSE;
address_item *addr;
uschar *igquotstr = US"";
uschar *sockname = NULL;
-uschar **argv;
+const uschar **argv;
uschar buffer[256];

DEBUG(D_transport) debug_printf("%s transport entered\n", tblock->name);
@@ -469,13 +469,29 @@ DEBUG(D_transport) debug_printf("%s transport entered\n", tblock->name);
not both. When a command is specified, call the common function for creating an
argument list and expanding the items. */

-if (ob->cmd != NULL)
+if (ob->cmd)
   {
   DEBUG(D_transport) debug_printf("using command %s\n", ob->cmd);
   sprintf(CS buffer, "%.50s transport", tblock->name);
   if (!transport_set_up_command(&argv, ob->cmd, TRUE, PANIC, addrlist, buffer,
        NULL))
     return FALSE;
+
+  /* If the -N option is set, can't do any more. Presume all has gone well. */
+  if (dont_deliver)
+    goto MINUS_N;
+
+/* As this is a local transport, we are already running with the required
+uid/gid and current directory. Request that the new process be a process group
+leader, so we can kill it and all its children on an error. */
+
+  if ((pid = child_open(USS argv, NULL, 0, &fd_in, &fd_out, TRUE)) < 0)
+    {
+    addrlist->message = string_sprintf(
+      "Failed to create child process for %s transport: %s", tblock->name,
+        strerror(errno));
+    return FALSE;
+    }
   }


 /* When a socket is specified, expand the string and create a socket. */
@@ -498,38 +514,11 @@ else
         ob->skt, tblock->name, strerror(errno));
     return FALSE;
     }
-  }


-/* If the -N option is set, can't do any more. Presume all has gone well. */
+  /* If the -N option is set, can't do any more. Presume all has gone well. */
+  if (dont_deliver)
+    goto MINUS_N;


-if (dont_deliver)
-  {
-  DEBUG(D_transport)
-    debug_printf("*** delivery by %s transport bypassed by -N option",
-      tblock->name);
-  addrlist->transport_return = OK;
-  return FALSE;
-  }
-
-/* As this is a local transport, we are already running with the required
-uid/gid and current directory. Request that the new process be a process group
-leader, so we can kill it and all its children on an error. */
-
-if (ob->cmd != NULL)
-  {
-  if ((pid = child_open(argv, NULL, 0, &fd_in, &fd_out, TRUE)) < 0)
-    {
-    addrlist->message = string_sprintf(
-      "Failed to create child process for %s transport: %s", tblock->name,
-        strerror(errno));
-    return FALSE;
-    }
-  }
-
-/* For a socket, try to make the connection */
-
-else
-  {
   sockun.sun_family = AF_UNIX;
   sprintf(sockun.sun_path, "%.*s", (int)(sizeof(sockun.sun_path)-1), sockname);
   if(connect(fd_out, (struct sockaddr *)(&sockun), sizeof(sockun)) == -1)
@@ -541,6 +530,7 @@ else
     }
   }


+
/* Make the output we are going to read into a file. */

 out = fdopen(fd_out, "rb");
@@ -666,8 +656,9 @@ if (send_data)
       addr->transport_return = OK;
       if ((log_extra_selector & LX_smtp_confirmation) != 0)
         {
-        uschar *s = string_printing(buffer);
-        addr->message = (s == buffer)? (uschar *)string_copy(s) : s;
+        const uschar *s = string_printing(buffer);
+    /* de-const safe here as string_printing known to have alloc'n'copied */
+        addr->message = (s == buffer)? (uschar *)string_copy(s) : US s;
         }
       }
     /* If the response has failed badly, use it for all the remaining pending
@@ -784,6 +775,14 @@ DEBUG(D_transport)
   debug_printf("%s transport yields %d\n", tblock->name, yield);


 return yield;
+
+
+MINUS_N:
+  DEBUG(D_transport)
+    debug_printf("*** delivery by %s transport bypassed by -N option",
+      tblock->name);
+  addrlist->transport_return = OK;
+  return FALSE;
 }


 /* End of transport/lmtp.c */
diff --git a/src/src/transports/pipe.c b/src/src/transports/pipe.c
index 3366a6d..9d933fb 100644
--- a/src/src/transports/pipe.c
+++ b/src/src/transports/pipe.c
@@ -326,12 +326,12 @@ Returns:             TRUE if all went well; otherwise an error will be
 */


static BOOL
-set_up_direct_command(uschar ***argvptr, uschar *cmd, BOOL expand_arguments,
- int expand_fail, address_item *addr, uschar *tname,
+set_up_direct_command(const uschar ***argvptr, uschar *cmd,
+ BOOL expand_arguments, int expand_fail, address_item *addr, uschar *tname,
pipe_transport_options_block *ob)
{
BOOL permitted = FALSE;
-uschar **argv;
+const uschar **argv;
uschar buffer[64];

/* Set up "transport <name>" to be put in any error messages, and then
@@ -353,11 +353,11 @@ argv = *argvptr;
if (ob->allow_commands != NULL)
{
int sep = 0;
- uschar *s, *p;
+ const uschar *s;
+ uschar *p;
uschar buffer[256];

-  s = expand_string(ob->allow_commands);
-  if (s == NULL)
+  if (!(s = expand_string(ob->allow_commands)))
     {
     addr->transport_return = DEFER;
     addr->message = string_sprintf("failed to expand string \"%s\" "
@@ -365,10 +365,8 @@ if (ob->allow_commands != NULL)
     return FALSE;
     }


-  while ((p = string_nextinlist(&s, &sep, buffer, sizeof(buffer))) != NULL)
-    {
+  while ((p = string_nextinlist(&s, &sep, buffer, sizeof(buffer))))
     if (Ustrcmp(p, argv[0]) == 0) { permitted = TRUE; break; }
-    }
   }


/* If permitted is TRUE it means the command was found in the allowed list, and
@@ -407,7 +405,7 @@ if (argv[0][0] != '/')
{
int sep = 0;
uschar *p;
- uschar *listptr = ob->path;
+ const uschar *listptr = ob->path;
uschar buffer[1024];

   while ((p = string_nextinlist(&listptr, &sep, buffer, sizeof(buffer))) != NULL)
@@ -453,10 +451,10 @@ Returns:             TRUE if all went well; otherwise an error will be
 */


static BOOL
-set_up_shell_command(uschar ***argvptr, uschar *cmd, BOOL expand_arguments,
- int expand_fail, address_item *addr, uschar *tname)
+set_up_shell_command(const uschar ***argvptr, uschar *cmd,
+ BOOL expand_arguments, int expand_fail, address_item *addr, uschar *tname)
{
-uschar **argv;
+const uschar **argv;

*argvptr = argv = store_get((4)*sizeof(uschar *));

@@ -551,9 +549,9 @@ pipe_transport_options_block *ob =
int timeout = ob->timeout;
BOOL written_ok = FALSE;
BOOL expand_arguments;
-uschar **argv;
+const uschar **argv;
uschar *envp[50];
-uschar *envlist = ob->environment;
+const uschar *envlist = ob->environment;
uschar *cmd, *ss;
uschar *eol = (ob->use_crlf)? US"\r\n" : US"\n";

@@ -669,9 +667,9 @@ else if (timezone_string != NULL && timezone_string[0] != 0)

/* Add any requested items */

-if (envlist != NULL)
+if (envlist)
   {
-  envlist = expand_string(envlist);
+  envlist = expand_cstring(envlist);
   if (envlist == NULL)
     {
     addr->transport_return = DEFER;
@@ -729,7 +727,7 @@ reading of the output pipe. */
 uid/gid and current directory. Request that the new process be a process group
 leader, so we can kill it and all its children on a timeout. */


-if ((pid = child_open(argv, envp, ob->umask, &fd_in, &fd_out, TRUE)) < 0)
+if ((pid = child_open(USS argv, envp, ob->umask, &fd_in, &fd_out, TRUE)) < 0)
{
addr->transport_return = DEFER;
addr->message = string_sprintf(
@@ -1073,16 +1071,14 @@ if ((rc = child_close(pid, timeout)) != 0)

       else
         {
-        uschar *s = ob->temp_errors;
+        const uschar *s = ob->temp_errors;
         uschar *p;
         uschar buffer[64];
         int sep = 0;


         addr->transport_return = FAIL;
-        while ((p = string_nextinlist(&s,&sep,buffer,sizeof(buffer))) != NULL)
-          {
+        while ((p = string_nextinlist(&s,&sep,buffer,sizeof(buffer))))
           if (rc == Uatoi(p)) { addr->transport_return = DEFER; break; }
-          }
         }


       /* Ensure the message contains the expanded command and arguments. This
diff --git a/src/src/transports/smtp.c b/src/src/transports/smtp.c
index 087b10c..5662ffb 100644
--- a/src/src/transports/smtp.c
+++ b/src/src/transports/smtp.c
@@ -523,7 +523,7 @@ if (*errno_value == ETIMEDOUT)


 if (*errno_value == ERRNO_SMTPFORMAT)
   {
-  uschar *malfresp = string_printing(buffer);
+  const uschar *malfresp = string_printing(buffer);
   while (isspace(*malfresp)) malfresp++;
   *message = *malfresp == 0
     ? string_sprintf("Malformed SMTP reply (an empty line) "
@@ -567,7 +567,7 @@ if (*errno_value == ERRNO_WRITEINCOMPLETE)


 if (buffer[0] != 0)
   {
-  uschar *s = string_printing(buffer);
+  const uschar *s = string_printing(buffer);
   *message = US string_sprintf("SMTP error from remote mail server after %s%s: "
     "%s", pl, smtp_command, s);
   *pass_message = TRUE;
@@ -659,7 +659,7 @@ static void
 deferred_event_raise(address_item *addr, host_item *host)
 {
 uschar * action = addr->transport->event_action;
-uschar * save_domain;
+const uschar * save_domain;
 uschar * save_local;


if (!action)
@@ -1170,7 +1170,7 @@ tlsa_lookup(const host_item * host, dns_answer * dnsa,
{
/* move this out to host.c given the similarity to dns_lookup() ? */
uschar buffer[300];
-uschar * fullname = buffer;
+const uschar * fullname = buffer;

 /* TLSA lookup string */
 (void)sprintf(CS buffer, "_%d._tcp.%.256s", host->port, host->name);
@@ -2200,8 +2200,9 @@ if (!ok) ok = TRUE; else
           !lmtp
        )
       {
-      uschar *s = string_printing(buffer);
-      conf = (s == buffer)? (uschar *)string_copy(s) : s;
+      const uschar *s = string_printing(buffer);
+      /* deconst cast ok here as string_printing was checked to have alloc'n'copied */
+      conf = (s == buffer)? (uschar *)string_copy(s) : US s;
       }


     /* Process all transported addresses - for LMTP or PRDR, read a status for
@@ -2251,8 +2252,9 @@ if (!ok) ok = TRUE; else
         completed_address = TRUE;   /* NOW we can set this flag */
         if ((log_extra_selector & LX_smtp_confirmation) != 0)
           {
-          uschar *s = string_printing(buffer);
-          conf = (s == buffer)? (uschar *)string_copy(s) : s;
+          const uschar *s = string_printing(buffer);
+      /* deconst cast ok here as string_printing was checked to have alloc'n'copied */
+          conf = (s == buffer)? (uschar *)string_copy(s) : US s;
           }
         }


@@ -2857,7 +2859,8 @@ if (hostlist == NULL || (ob->hosts_override && ob->hosts != NULL))
/* This is not the first time this transport has been run in this delivery;
the host list was built previously. */

-  else hostlist = ob->hostlist;
+  else
+    hostlist = ob->hostlist;
   }


/* The host list was supplied with the address. If hosts_randomize is set, we
@@ -2901,12 +2904,10 @@ else if (ob->hosts_randomize && hostlist->mx == MX_NONE && !continuing)
hostlist = addrlist->host_list = newlist;
}

-
/* Sort out the default port. */

if (!smtp_get_port(ob->port, addrlist, &port, tid)) return FALSE;

-
/* For each host-plus-IP-address on the list:

 .  If this is a continued delivery and the host isn't the one with the
@@ -3003,7 +3004,6 @@ for (cutoff_retry = 0; expired &&
       {
       int new_port, flags;
       host_item *hh;
-      uschar *canonical_name;


       if (host->status >= hstatus_unusable)
         {
@@ -3031,11 +3031,11 @@ for (cutoff_retry = 0; expired &&
       if (ob->dns_search_parents) flags |= HOST_FIND_SEARCH_PARENTS;


       if (ob->gethostbyname || string_is_ip_address(host->name, NULL) != 0)
-        rc = host_find_byname(host, NULL, flags, &canonical_name, TRUE);
+        rc = host_find_byname(host, NULL, flags, NULL, TRUE);
       else
         rc = host_find_bydns(host, NULL, flags, NULL, NULL, NULL,
       ob->dnssec_request_domains, ob->dnssec_require_domains,
-          &canonical_name, NULL);
+          NULL, NULL);


       /* Update the host (and any additional blocks, resulting from
       multihoming) with a host-specific port, if any. */
@@ -3111,7 +3111,8 @@ for (cutoff_retry = 0; expired &&
     doing a two-stage queue run, don't do this if forcing. */


     if ((!deliver_force || queue_2stage) && (queue_smtp ||
-        match_isinlist(addrlist->domain, &queue_smtp_domains, 0,
+        match_isinlist(addrlist->domain,
+      (const uschar **)&queue_smtp_domains, 0,
           &domainlist_anchor, NULL, MCL_DOMAIN, TRUE, NULL) == OK))
       {
       expired = FALSE;
diff --git a/src/src/tree.c b/src/src/tree.c
index 2a9d90a..d1cbc94 100644
--- a/src/src/tree.c
+++ b/src/src/tree.c
@@ -328,7 +328,7 @@ Returns:    pointer to node, or NULL if not found
 */


 tree_node *
-tree_search(tree_node *p, uschar *name)
+tree_search(tree_node *p, const uschar *name)
 {
 while (p != NULL)
   {
diff --git a/src/src/verify.c b/src/src/verify.c
index a22bb7d..d39e103 100644
--- a/src/src/verify.c
+++ b/src/src/verify.c
@@ -58,7 +58,7 @@ Returns:            the cache record if a non-expired one exists, else NULL
 */


 static dbdata_callout_cache *
-get_callout_cache_record(open_db *dbm_file, uschar *key, uschar *type,
+get_callout_cache_record(open_db *dbm_file, const uschar *key, uschar *type,
   int positive_expire, int negative_expire)
 {
 BOOL negative;
@@ -164,7 +164,7 @@ BOOL done = FALSE;
 uschar *address_key;
 uschar *from_address;
 uschar *random_local_part = NULL;
-uschar *save_deliver_domain = deliver_domain;
+const uschar *save_deliver_domain = deliver_domain;
 uschar **failure_ptr = is_recipient?
   &recipient_verify_failure : &sender_verify_failure;
 open_db dbblock;
@@ -704,7 +704,7 @@ can do it there for the non-rcpt-verify case.  For this we keep an addresscount.
       }


     /* Not worth checking greeting line for ESMTP support */
-    if (!(esmtp = verify_check_given_host(&(ob->hosts_avoid_esmtp), host) != OK))
+    if (!(esmtp = verify_check_given_host(&ob->hosts_avoid_esmtp, host) != OK))
       DEBUG(D_transport)
         debug_printf("not sending EHLO (host matches hosts_avoid_esmtp)\n");


@@ -1922,7 +1922,7 @@ while (addr_new != NULL)
         if (tf.hosts != NULL && (host_list == NULL || tf.hosts_override))
           {
           uschar *s;
-          uschar *save_deliver_domain = deliver_domain;
+          const uschar *save_deliver_domain = deliver_domain;
           uschar *save_deliver_localpart = deliver_localpart;


           host_list = NULL;    /* Ignore the router's hosts */
@@ -1942,7 +1942,6 @@ while (addr_new != NULL)
           else
             {
             int flags;
-            uschar *canonical_name;
             host_item *host, *nexthost;
             host_build_hostlist(&host_list, s, tf.hosts_randomize);


@@ -1961,7 +1960,7 @@ while (addr_new != NULL)
               nexthost = host->next;
               if (tf.gethostbyname ||
                   string_is_ip_address(host->name, NULL) != 0)
-                (void)host_find_byname(host, NULL, flags, &canonical_name, TRUE);
+                (void)host_find_byname(host, NULL, flags, NULL, TRUE);
               else
         {
         uschar * d_request = NULL, * d_require = NULL;
@@ -1975,7 +1974,7 @@ while (addr_new != NULL)
           }


                 (void)host_find_bydns(host, NULL, flags, NULL, NULL, NULL,
-          d_request, d_require, &canonical_name, NULL);
+          d_request, d_require, NULL, NULL);
         }
               }
             }
@@ -2371,7 +2370,8 @@ for (h = header_list; h != NULL && yield == OK; h = h->next)
         verb = US"begins";
         }


-      *msgptr = string_printing(
+      /* deconst cast ok as we're passing a non-const to string_printing() */
+      *msgptr = US string_printing(
         string_sprintf("%s: failing address in \"%.*s:\" header %s: %.*s",
           errmess, tt - h->text, h->text, verb, len, s));


@@ -2892,9 +2892,9 @@ if (*p == 0) goto END_OFF;
/* The rest of the line is the data we want. We turn it into printing
characters when we save it, so that it cannot mess up the format of any logging
or Received: lines into which it gets inserted. We keep a maximum of 127
-characters. */
+characters. The deconst cast is ok as we fed a nonconst to string_printing() */

-sender_ident = string_printing(string_copyn(p, 127));
+sender_ident = US string_printing(string_copyn(p, 127));
DEBUG(D_ident) debug_printf("sender_ident = %s\n", sender_ident);

 END_OFF:
@@ -2939,7 +2939,7 @@ Returns:         OK      matched
 */


int
-check_host(void *arg, uschar *ss, uschar **valueptr, uschar **error)
+check_host(void *arg, const uschar *ss, const uschar **valueptr, uschar **error)
{
check_host_block *cb = (check_host_block *)arg;
int mlen = -1;
@@ -2947,7 +2947,7 @@ int maskoffset;
BOOL iplookup = FALSE;
BOOL isquery = FALSE;
BOOL isiponly = cb->host_name != NULL && cb->host_name[0] == 0;
-uschar *t;
+const uschar *t;
uschar *semicolon;
uschar **aliases;

@@ -3160,7 +3160,7 @@ on spec. */

if ((semicolon = Ustrchr(ss, ';')) != NULL)
{
- uschar *affix;
+ const uschar *affix;
int partial, affixlen, starflags, id;

*semicolon = 0;
@@ -3261,12 +3261,12 @@ determined from the IP address, the result is FAIL unless the item
"+allow_unknown" was met earlier in the list, in which case OK is returned. */

int
-verify_check_this_host(uschar **listptr, unsigned int *cache_bits,
- uschar *host_name, uschar *host_address, uschar **valueptr)
+verify_check_this_host(const uschar **listptr, unsigned int *cache_bits,
+ const uschar *host_name, const uschar *host_address, const uschar **valueptr)
{
int rc;
unsigned int *local_cache_bits = cache_bits;
-uschar *save_host_address = deliver_host_address;
+const uschar *save_host_address = deliver_host_address;
check_host_block cb;
cb.host_name = host_name;
cb.host_address = host_address;
@@ -3311,7 +3311,7 @@ return rc;
int
verify_check_given_host(uschar **listptr, host_item *host)
{
-return verify_check_this_host(listptr, NULL, host->name, host->address, NULL);
+return verify_check_this_host(CUSS listptr, NULL, host->name, host->address, NULL);
}

 /*************************************************
@@ -3333,7 +3333,7 @@ Returns:               the yield of verify_check_this_host(),
 int
 verify_check_host(uschar **listptr)
 {
-return verify_check_this_host(listptr, sender_host_cache, NULL,
+return verify_check_this_host(CUSS listptr, sender_host_cache, NULL,
   (sender_host_address == NULL)? US"" : sender_host_address, NULL);
 }


@@ -3564,7 +3564,7 @@ if (cb->rc == DNS_SUCCEED)
       {
       int ipsep = ',';
       uschar ip[46];
-      uschar *ptr = iplist;
+      const uschar *ptr = iplist;
       uschar *res;


       /* Handle exact matching */
@@ -3767,11 +3767,11 @@ Returns:    OK      successful lookup (i.e. the address is on the list), or
 */


 int
-verify_check_dnsbl(uschar **listptr)
+verify_check_dnsbl(const uschar **listptr)
 {
 int sep = 0;
 int defer_return = FAIL;
-uschar *list = *listptr;
+const uschar *list = *listptr;
 uschar *domain;
 uschar *s;
 uschar buffer[1024];
@@ -3917,7 +3917,7 @@ while ((domain = string_nextinlist(&list, &sep, buffer, sizeof(buffer))) != NULL
     uschar keybuffer[256];
     uschar keyrevadd[128];


-    while ((keydomain = string_nextinlist(&key, &keysep, keybuffer,
+    while ((keydomain = string_nextinlist(CUSS &key, &keysep, keybuffer,
             sizeof(keybuffer))) != NULL)
       {
       uschar *prepend = keydomain;
diff --git a/test/stderr/0432 b/test/stderr/0432
index 00dfde2..918363e 100644
--- a/test/stderr/0432
+++ b/test/stderr/0432
@@ -14,7 +14,6 @@

>>> calling r1 router
>>> routed by r1 router
>>> local host found for non-MX address

->>> fully qualified name = 127.0.0.1
MUNGED: ::1 will be omitted in what follows
>>> get[host|ipnode]byname[2] looked up these IP addresses:
>>> name=127.0.0.1 address=127.0.0.1

@@ -74,7 +73,6 @@ routed by r1 router
transport: t1
using host_fake_gethostbyname for 127.0.0.1 (IPv4)
local host found for non-MX address
-fully qualified name = 127.0.0.1
MUNGED: ::1 will be omitted in what follows
get[host|ipnode]byname[2] looked up these IP addresses:
name=127.0.0.1 address=127.0.0.1
@@ -171,7 +169,6 @@ routed by r1 router
transport: t1
using host_fake_gethostbyname for 127.0.0.1 (IPv4)
local host found for non-MX address
-fully qualified name = 127.0.0.1
MUNGED: ::1 will be omitted in what follows
get[host|ipnode]byname[2] looked up these IP addresses:
name=127.0.0.1 address=127.0.0.1
@@ -213,7 +210,6 @@ search_tidyup called
>>> calling r1 router
>>> routed by r1 router
>>> local host found for non-MX address

->>> fully qualified name = 127.0.0.1
MUNGED: ::1 will be omitted in what follows
>>> get[host|ipnode]byname[2] looked up these IP addresses:
>>> name=127.0.0.1 address=127.0.0.1

@@ -240,7 +236,6 @@ MUNGED: ::1 will be omitted in what follows
>>> calling r1 router
>>> routed by r1 router
>>> local host found for non-MX address

->>> fully qualified name = 127.0.0.1
MUNGED: ::1 will be omitted in what follows
>>> get[host|ipnode]byname[2] looked up these IP addresses:
>>> name=127.0.0.1 address=127.0.0.1

@@ -281,7 +276,6 @@ MUNGED: ::1 will be omitted in what follows
>>> calling r1 router
>>> routed by r1 router
>>> local host found for non-MX address

->>> fully qualified name = 127.0.0.1
MUNGED: ::1 will be omitted in what follows
>>> get[host|ipnode]byname[2] looked up these IP addresses:
>>> name=127.0.0.1 address=127.0.0.1