Authenticators: refactor SASL support code
[users/heiko/exim.git] / src / src / host.c
index fbc46575d6288e61e0c4fb616ef6713c92a0ec27..eda56d76377e8de28be22986fe8064a26088e8d5 100644 (file)
@@ -84,7 +84,7 @@ if (limit < 1)
   return 0;
 if (random_seed == 0)
   {
-  if (running_in_test_harness) random_seed = 42; else
+  if (f.running_in_test_harness) random_seed = 42; else
     {
     int p = (int)getpid();
     random_seed = (int)time(NULL) ^ ((p << 16) | p);
@@ -179,7 +179,6 @@ uschar **alist;
 struct hostent *yield;
 dns_answer dnsa;
 dns_scan dnss;
-dns_record *rr;
 
 DEBUG(D_host_lookup)
   debug_printf("using host_fake_gethostbyname for %s (%s)\n", name,
@@ -192,13 +191,11 @@ if (Ustrcmp(name, "localhost") == 0)
 
 /* Handle a literal IP address */
 
-ipa = string_is_ip_address(lname, NULL);
-if (ipa != 0)
+if ((ipa = string_is_ip_address(lname, NULL)) != 0)
   {
   if ((ipa == 4 && af == AF_INET) ||
       (ipa == 6 && af == AF_INET6))
     {
-    int i, n;
     int x[4];
     yield = store_get(sizeof(struct hostent));
     alist = store_get(2 * sizeof(char *));
@@ -209,8 +206,7 @@ if (ipa != 0)
     yield->h_length = alen;
     yield->h_addr_list = CSS alist;
     *alist++ = adds;
-    n = host_aton(lname, x);
-    for (i = 0; i < n; i++)
+    for (int n = host_aton(lname, x), i = 0; i < n; i++)
       {
       int y = x[i];
       *adds++ = (y >> 24) & 255;
@@ -250,11 +246,10 @@ else
     case DNS_FAIL:    *error_num = NO_RECOVERY; return NULL;
     }
 
-  for (rr = dns_next_rr(&dnsa, &dnss, RESET_ANSWERS);
+  for (dns_record * rr = dns_next_rr(&dnsa, &dnss, RESET_ANSWERS);
        rr;
-       rr = dns_next_rr(&dnsa, &dnss, RESET_NEXT))
-    if (rr->type == type)
-      count++;
+       rr = dns_next_rr(&dnsa, &dnss, RESET_NEXT)) if (rr->type == type)
+    count++;
 
   yield = store_get(sizeof(struct hostent));
   alist = store_get((count + 1) * sizeof(char *));
@@ -266,18 +261,15 @@ else
   yield->h_length = alen;
   yield->h_addr_list = CSS alist;
 
-  for (rr = dns_next_rr(&dnsa, &dnss, RESET_ANSWERS);
+  for (dns_record * rr = dns_next_rr(&dnsa, &dnss, RESET_ANSWERS);
        rr;
-       rr = dns_next_rr(&dnsa, &dnss, RESET_NEXT))
+       rr = dns_next_rr(&dnsa, &dnss, RESET_NEXT)) if (rr->type == type)
     {
-    int i, n;
     int x[4];
     dns_address *da;
-    if (rr->type != type) continue;
     if (!(da = dns_address_from_rr(&dnsa, rr))) break;
     *alist++ = adds;
-    n = host_aton(da->address, x);
-    for (i = 0; i < n; i++)
+    for (int n = host_aton(da->address, x), i = 0; i < n; i++)
       {
       int y = x[i];
       *adds++ = (y >> 24) & 255;
@@ -318,12 +310,12 @@ int sep = 0;
 int fake_mx = MX_NONE;          /* This value is actually -1 */
 uschar *name;
 
-if (list == NULL) return;
+if (!list) return;
 if (randomize) fake_mx--;       /* Start at -2 for randomizing */
 
 *anchor = NULL;
 
-while ((name = string_nextinlist(&list, &sep, NULL, 0)) != NULL)
+while ((name = string_nextinlist(&list, &sep, NULL, 0)))
   {
   host_item *h;
 
@@ -343,7 +335,7 @@ while ((name = string_nextinlist(&list, &sep, NULL, 0)) != NULL)
   h->why = hwhy_unknown;
   h->last_try = 0;
 
-  if (*anchor == NULL)
+  if (!*anchor)
     {
     h->next = NULL;
     *anchor = h;
@@ -358,7 +350,7 @@ while ((name = string_nextinlist(&list, &sep, NULL, 0)) != NULL)
       }
     else
       {
-      while (hh->next != NULL && h->sort_key >= (hh->next)->sort_key)
+      while (hh->next && h->sort_key >= hh->next->sort_key)
         hh = hh->next;
       h->next = hh->next;
       hh->next = h;
@@ -520,7 +512,9 @@ There wouldn't be two different variables if I had got all this right in the
 first place.
 
 Because this data may survive over more than one incoming SMTP message, it has
-to be in permanent store.
+to be in permanent store.  However, STARTTLS has to be forgotten and redone
+on a multi-message conn, so this will be called once per message then.  Hence
+we use malloc, so we can free.
 
 Arguments:  none
 Returns:    nothing
@@ -530,13 +524,12 @@ void
 host_build_sender_fullhost(void)
 {
 BOOL show_helo = TRUE;
-uschar *address;
+uschar * address, * fullhost, * rcvhost, * reset_point;
 int len;
-int old_pool = store_pool;
 
 if (!sender_host_address) return;
 
-store_pool = POOL_PERM;
+reset_point = store_get(0);
 
 /* Set up address, with or without the port. After discussion, it seems that
 the only format that doesn't cause trouble is [aaaa]:pppp. However, we can't
@@ -593,7 +586,7 @@ if (!sender_host_name)
   int adlen;    /* Sun compiler doesn't like ++ in initializers */
 
   adlen = portptr ? (++portptr - address) : Ustrlen(address);
-  sender_fullhost = sender_helo_name
+  fullhost = sender_helo_name
     ? string_sprintf("(%s) %s", sender_helo_name, address)
     : address;
 
@@ -619,12 +612,7 @@ if (!sender_host_name)
     g = string_catn(g, US")", 1);
     }
 
-  sender_rcvhost = string_from_gstring(g);
-
-  /* Release store, because string_cat allocated a minimum of 100 bytes that
-  are rarely completely used. */
-
-  store_reset(sender_rcvhost + g->ptr + 1);
+  rcvhost = string_from_gstring(g);
   }
 
 /* Host name is known and verified. Unless we've already found that the HELO
@@ -637,25 +625,30 @@ else
 
   if (show_helo)
     {
-    sender_fullhost = string_sprintf("%s (%s) %s", sender_host_name,
+    fullhost = string_sprintf("%s (%s) %s", sender_host_name,
       sender_helo_name, address);
-    sender_rcvhost = (sender_ident == NULL)?
-      string_sprintf("%s (%s helo=%s)", sender_host_name,
-        address, sender_helo_name) :
-      string_sprintf("%s\n\t(%s helo=%s ident=%s)", sender_host_name,
-        address, sender_helo_name, sender_ident);
+    rcvhost = sender_ident
+      ?  string_sprintf("%s\n\t(%s helo=%s ident=%s)", sender_host_name,
+        address, sender_helo_name, sender_ident)
+      : string_sprintf("%s (%s helo=%s)", sender_host_name,
+        address, sender_helo_name);
     }
   else
     {
-    sender_fullhost = string_sprintf("%s %s", sender_host_name, address);
-    sender_rcvhost = (sender_ident == NULL)?
-      string_sprintf("%s (%s)", sender_host_name, address) :
-      string_sprintf("%s (%s ident=%s)", sender_host_name, address,
-        sender_ident);
+    fullhost = string_sprintf("%s %s", sender_host_name, address);
+    rcvhost = sender_ident
+      ?  string_sprintf("%s (%s ident=%s)", sender_host_name, address,
+        sender_ident)
+      : string_sprintf("%s (%s)", sender_host_name, address);
     }
   }
 
-store_pool = old_pool;
+if (sender_fullhost) store_free(sender_fullhost);
+sender_fullhost = string_copy_malloc(fullhost);
+if (sender_rcvhost) store_free(sender_rcvhost);
+sender_rcvhost = string_copy_malloc(rcvhost);
+
+store_reset(reset_point);
 
 DEBUG(D_host_lookup) debug_printf("sender_fullhost = %s\n", sender_fullhost);
 DEBUG(D_host_lookup) debug_printf("sender_rcvhost = %s\n", sender_rcvhost);
@@ -685,23 +678,21 @@ Returns:    pointer to a string in big_buffer
 uschar *
 host_and_ident(BOOL useflag)
 {
-if (sender_fullhost == NULL)
-  {
-  (void)string_format(big_buffer, big_buffer_size, "%s%s", useflag? "U=" : "",
-     (sender_ident == NULL)? US"unknown" : sender_ident);
-  }
+if (!sender_fullhost)
+  (void)string_format(big_buffer, big_buffer_size, "%s%s", useflag ? "U=" : "",
+     sender_ident ? sender_ident : US"unknown");
 else
   {
-  uschar *flag = useflag? US"H=" : US"";
-  uschar *iface = US"";
-  if (LOGGING(incoming_interface) && interface_address != NULL)
+  uschar * flag = useflag ? US"H=" : US"";
+  uschar * iface = US"";
+  if (LOGGING(incoming_interface) && interface_address)
     iface = string_sprintf(" I=[%s]:%d", interface_address, interface_port);
-  if (sender_ident == NULL)
-    (void)string_format(big_buffer, big_buffer_size, "%s%s%s",
-      flag, sender_fullhost, iface);
-  else
+  if (sender_ident)
     (void)string_format(big_buffer, big_buffer_size, "%s%s%s U=%s",
       flag, sender_fullhost, iface, sender_ident);
+  else
+    (void)string_format(big_buffer, big_buffer_size, "%s%s%s",
+      flag, sender_fullhost, iface);
   }
 return big_buffer;
 }
@@ -806,7 +797,7 @@ static ip_address_item *
 add_unique_interface(ip_address_item *list, ip_address_item *ipa)
 {
 ip_address_item *ipa2;
-for (ipa2 = list; ipa2 != NULL; ipa2 = ipa2->next)
+for (ipa2 = list; ipa2; ipa2 = ipa2->next)
   if (Ustrcmp(ipa2->address, ipa->address) == 0) return list;
 ipa2 = store_get_perm(sizeof(ip_address_item));
 *ipa2 = *ipa;
@@ -831,27 +822,25 @@ if (local_interface_data == NULL)
     US"extra_local_interfaces");
   ip_address_item *ipa;
 
-  if (dlist == NULL) dlist = xlist; else
+  if (!dlist) dlist = xlist;
+  else
     {
-    for (ipa = dlist; ipa->next != NULL; ipa = ipa->next);
+    for (ipa = dlist; ipa->next; ipa = ipa->next) ;
     ipa->next = xlist;
     }
 
-  for (ipa = dlist; ipa != NULL; ipa = ipa->next)
+  for (ipa = dlist; ipa; ipa = ipa->next)
     {
     if (Ustrcmp(ipa->address, "0.0.0.0") == 0 ||
         Ustrcmp(ipa->address, "::0") == 0)
       {
-      ip_address_item *ipa2;
       BOOL ipv6 = ipa->address[0] == ':';
-      if (running_interfaces == NULL)
+      if (!running_interfaces)
         running_interfaces = os_find_running_interfaces();
-      for (ipa2 = running_interfaces; ipa2 != NULL; ipa2 = ipa2->next)
-        {
+      for (ip_address_item * ipa2 = running_interfaces; ipa2; ipa2 = ipa2->next)
         if ((Ustrchr(ipa2->address, ':') != NULL) == ipv6)
           local_interface_data = add_unique_interface(local_interface_data,
-          ipa2);
-        }
+                                                     ipa2);
       }
     else
       {
@@ -1089,9 +1078,8 @@ Returns:       nothing
 void
 host_mask(int count, int *binary, int mask)
 {
-int i;
 if (mask < 0) mask = 99999;
-for (i = 0; i < count; i++)
+for (int i = 0; i < count; i++)
   {
   int wordmask;
   if (mask == 0) wordmask = 0;
@@ -1138,17 +1126,17 @@ Returns:      the number of characters placed in buffer, not counting
 int
 host_nmtoa(int count, int *binary, int mask, uschar *buffer, int sep)
 {
-int i, j;
+int j;
 uschar *tt = buffer;
 
 if (count == 1)
   {
   j = binary[0];
-  for (i = 24; i >= 0; i -= 8)
+  for (int i = 24; i >= 0; i -= 8)
     tt += sprintf(CS tt, "%d.", (j >> i) & 255);
   }
 else
-  for (i = 0; i < 4; i++)
+  for (int i = 0; i < 4; i++)
     {
     j = binary[i];
     tt += sprintf(CS tt, "%04x%c%04x%c", (j >> 16) & 0xffff, sep, j & 0xffff, sep);
@@ -1278,7 +1266,6 @@ Returns:
 BOOL
 host_is_in_net(const uschar *host, const uschar *net, int maskoffset)
 {
-int i;
 int address[4];
 int incoming[4];
 int mlen;
@@ -1311,7 +1298,7 @@ if (insize != size) return FALSE;
 
 /* Else do the masked comparison. */
 
-for (i = 0; i < size; i++)
+for (int i = 0; i < size; i++)
   {
   int mask;
   if (mlen == 0) mask = 0;
@@ -1406,9 +1393,8 @@ for (h = host; h != last->next; h = h->next)
 
   if (h->address != NULL)
     {
-    ip_address_item *ip;
     if (Ustrcmp(h->address, "0.0.0.0") == 0) goto FOUND_LOCAL;
-    for (ip = local_interface_data; ip != NULL; ip = ip->next)
+    for (ip_address_item * ip = local_interface_data; ip; ip = ip->next)
       if (Ustrcmp(h->address, ip->address) == 0) goto FOUND_LOCAL;
     yield = HOST_FOUND;  /* At least one remote address has been found */
     }
@@ -1591,13 +1577,13 @@ while (*s != 0) *t++ = tolower(*s++);
 
 /* If the host has aliases, build a copy of the alias list */
 
-if (hosts->h_aliases != NULL)
+if (hosts->h_aliases)
   {
   int count = 1;
-  uschar **aliases, **ptr;
-  for (aliases = USS hosts->h_aliases; *aliases != NULL; aliases++) count++;
+  uschar **ptr;
+  for (uschar ** aliases = USS hosts->h_aliases; *aliases; aliases++) count++;
   ptr = sender_host_aliases = store_get_perm(count * sizeof(uschar *));
-  for (aliases = USS hosts->h_aliases; *aliases != NULL; aliases++)
+  for (uschar ** aliases = USS hosts->h_aliases; *aliases; aliases++)
     {
     uschar *s = *aliases;
     int len = Ustrlen(s) + 1;
@@ -1656,12 +1642,11 @@ host_name_lookup(void)
 {
 int old_pool, rc;
 int sep = 0;
-uschar *hname, *save_hostname;
+uschar *save_hostname;
 uschar **aliases;
 uschar buffer[256];
 uschar *ordername;
 const uschar *list = host_lookup_order;
-dns_record *rr;
 dns_answer dnsa;
 dns_scan dnss;
 
@@ -1673,7 +1658,7 @@ HDEBUG(D_host_lookup)
 /* For testing the case when a lookup does not complete, we have a special
 reserved IP address. */
 
-if (running_in_test_harness &&
+if (f.running_in_test_harness &&
     Ustrcmp(sender_host_address, "99.99.99.99") == 0)
   {
   HDEBUG(D_host_lookup)
@@ -1713,11 +1698,10 @@ while ((ordername = string_nextinlist(&list, &sep, buffer, sizeof(buffer))))
 
       store_pool = POOL_PERM;        /* Save names in permanent storage */
 
-      for (rr = dns_next_rr(&dnsa, &dnss, RESET_ANSWERS);
+      for (dns_record * rr = dns_next_rr(&dnsa, &dnss, RESET_ANSWERS);
            rr;
-           rr = dns_next_rr(&dnsa, &dnss, RESET_NEXT))
-        if (rr->type == T_PTR)
-         count++;
+           rr = dns_next_rr(&dnsa, &dnss, RESET_NEXT)) if (rr->type == T_PTR)
+       count++;
 
       /* Get store for the list of aliases. For compatibility with
       gethostbyaddr, we make an empty list if there are none. */
@@ -1726,13 +1710,11 @@ while ((ordername = string_nextinlist(&list, &sep, buffer, sizeof(buffer))))
 
       /* Re-scan and extract the names */
 
-      for (rr = dns_next_rr(&dnsa, &dnss, RESET_ANSWERS);
+      for (dns_record * rr = dns_next_rr(&dnsa, &dnss, RESET_ANSWERS);
            rr;
-           rr = dns_next_rr(&dnsa, &dnss, RESET_NEXT))
+           rr = dns_next_rr(&dnsa, &dnss, RESET_NEXT)) if (rr->type == T_PTR)
         {
-        uschar *s = NULL;
-        if (rr->type != T_PTR) continue;
-        s = store_get(ssize);
+        uschar * s = store_get(ssize);
 
         /* If an overlong response was received, the data will have been
         truncated and dn_expand may fail. */
@@ -1795,9 +1777,9 @@ while ((ordername = string_nextinlist(&list, &sep, buffer, sizeof(buffer))))
 /* If we have failed to find a name, return FAIL and log when required.
 NB host_lookup_msg must be in permanent store.  */
 
-if (sender_host_name == NULL)
+if (!sender_host_name)
   {
-  if (host_checking || !log_testing_mode)
+  if (host_checking || !f.log_testing_mode)
     log_write(L_host_lookup_failed, LOG_MAIN, "no host name found for IP "
       "address %s", sender_host_address);
   host_lookup_msg = US" (failed to find host name from IP address)";
@@ -1827,26 +1809,19 @@ the names, and accepts only those that have the correct IP address. */
 
 save_hostname = sender_host_name;   /* Save for error messages */
 aliases = sender_host_aliases;
-for (hname = sender_host_name; hname; hname = *aliases++)
+for (uschar * hname = sender_host_name; hname; hname = *aliases++)
   {
   int rc;
   BOOL ok = FALSE;
-  host_item h;
-  dnssec_domains d;
-
-  h.next = NULL;
-  h.name = hname;
-  h.mx = MX_NONE;
-  h.address = NULL;
-  d.request = sender_host_dnssec ? US"*" : NULL;;
-  d.require = NULL;
+  host_item h = { .next = NULL, .name = hname, .mx = MX_NONE, .address = NULL };
+  dnssec_domains d =
+    { .request = sender_host_dnssec ? US"*" : NULL, .require = NULL };
 
   if (  (rc = host_find_bydns(&h, NULL, HOST_FIND_BY_A | HOST_FIND_BY_AAAA,
          NULL, NULL, NULL, &d, NULL, NULL)) == HOST_FOUND
      || rc == HOST_FOUND_LOCAL
      )
     {
-    host_item *hh;
     HDEBUG(D_host_lookup) debug_printf("checking addresses for %s\n", hname);
 
     /* If the forward lookup was not secure we cancel the is-secure variable */
@@ -1855,7 +1830,7 @@ for (hname = sender_host_name; hname; hname = *aliases++)
          h.dnssec == DS_YES ? "DNSSEC verified (AD)" : "unverified");
     if (h.dnssec != DS_YES) sender_host_dnssec = FALSE;
 
-    for (hh = &h; hh; hh = hh->next)
+    for (host_item * hh = &h; hh; hh = hh->next)
       if (host_is_in_net(hh->address, sender_host_address, 0))
         {
         HDEBUG(D_host_lookup) debug_printf("  %s OK\n", hh->address);
@@ -1966,8 +1941,7 @@ int
 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;
+int yield, times;
 host_item *last = NULL;
 BOOL temp_error = FALSE;
 #if HAVE_IPV6
@@ -2010,11 +1984,11 @@ lookups here (except when testing standalone). */
 /* Initialize the flag that gets set for DNS syntax check errors, so that the
 interface to this function can be similar to host_find_bydns. */
 
-host_find_failed_syntax = FALSE;
+f.host_find_failed_syntax = FALSE;
 
 /* Loop to look up both kinds of address in an IPv6 world */
 
-for (i = 1; i <= times;
+for (int i = 1; i <= times;
      #if HAVE_IPV6
        af = AF_INET,     /* If 2 passes, IPv4 on the second */
      #endif
@@ -2032,7 +2006,7 @@ for (i = 1; i <= times;
   if (slow_lookup_log) time_msec = get_time_in_ms();
 
   #if HAVE_IPV6
-  if (running_in_test_harness)
+  if (f.running_in_test_harness)
     hostdata = host_fake_gethostbyname(host->name, af, &error_num);
   else
     {
@@ -2045,7 +2019,7 @@ for (i = 1; i <= times;
     }
 
   #else    /* not HAVE_IPV6 */
-  if (running_in_test_harness)
+  if (f.running_in_test_harness)
     hostdata = host_fake_gethostbyname(host->name, AF_INET, &error_num);
   else
     {
@@ -2104,7 +2078,7 @@ for (i = 1; i <= times;
 
   ipv4_addr = hostdata->h_length == sizeof(struct in_addr);
 
-  for (addrlist = USS hostdata->h_addr_list; *addrlist != NULL; addrlist++)
+  for (uschar ** addrlist = USS hostdata->h_addr_list; *addrlist; addrlist++)
     {
     uschar *text_address =
       host_ntoa(ipv4_addr? AF_INET:AF_INET6, *addrlist, NULL, NULL);
@@ -2170,7 +2144,7 @@ if (host->address == NULL)
 
   HDEBUG(D_host_lookup) debug_printf("%s\n", msg);
   if (temp_error) goto RETURN_AGAIN;
-  if (host_checking || !log_testing_mode)
+  if (host_checking || !f.log_testing_mode)
     log_write(L_host_lookup_failed, LOG_MAIN, "%s", msg);
   return HOST_FIND_FAILED;
   }
@@ -2184,8 +2158,7 @@ yield = local_host_check?
 
 HDEBUG(D_host_lookup)
   {
-  const host_item *h;
-  if (fully_qualified_name != NULL)
+  if (fully_qualified_name)
     debug_printf("fully qualified name = %s\n", *fully_qualified_name);
   debug_printf("%s looked up these IP addresses:\n",
     #if HAVE_IPV6
@@ -2198,9 +2171,9 @@ HDEBUG(D_host_lookup)
     "gethostbyname"
     #endif
     );
-  for (h = host; h != last->next; h = h->next)
+  for (const host_item * h = host; h != last->next; h = h->next)
     debug_printf("  name=%s address=%s\n", h->name,
-      (h->address == NULL)? US"<null>" : h->address);
+      h->address ? h->address : US"<null>");
   }
 
 /* Return the found status. */
@@ -2279,7 +2252,6 @@ set_address_from_dns(host_item *host, host_item **lastptr,
   const uschar **fully_qualified_name,
   BOOL dnssec_request, BOOL dnssec_require, int whichrrs)
 {
-dns_record *rr;
 host_item *thishostlast = NULL;    /* Indicates not yet filled in anything */
 BOOL v6_find_again = FALSE;
 BOOL dnssec_fail = FALSE;
@@ -2402,104 +2374,101 @@ for (; i >= 0; i--)
 
   fully_qualified_name = NULL;
 
-  for (rr = dns_next_rr(&dnsa, &dnss, RESET_ANSWERS);
+  for (dns_record * rr = dns_next_rr(&dnsa, &dnss, RESET_ANSWERS);
        rr;
-       rr = dns_next_rr(&dnsa, &dnss, RESET_NEXT))
+       rr = dns_next_rr(&dnsa, &dnss, RESET_NEXT)) if (rr->type == type)
     {
-    if (rr->type == type)
-      {
-      dns_address *da = dns_address_from_rr(&dnsa, rr);
+    dns_address * da = dns_address_from_rr(&dnsa, rr);
 
-      DEBUG(D_host_lookup)
-        if (!da) debug_printf("no addresses extracted from A6 RR for %s\n",
-            host->name);
+    DEBUG(D_host_lookup)
+      if (!da) debug_printf("no addresses extracted from A6 RR for %s\n",
+         host->name);
 
-      /* This loop runs only once for A and AAAA records, but may run
-      several times for an A6 record that generated multiple addresses. */
+    /* This loop runs only once for A and AAAA records, but may run
+    several times for an A6 record that generated multiple addresses. */
 
-      for (; da; da = da->next)
-        {
-        #ifndef STAND_ALONE
-        if (ignore_target_hosts != NULL &&
-              verify_check_this_host(&ignore_target_hosts, NULL,
-                host->name, da->address, NULL) == OK)
-          {
-          DEBUG(D_host_lookup)
-            debug_printf("ignored host %s [%s]\n", host->name, da->address);
-          continue;
-          }
-        #endif
+    for (; da; da = da->next)
+      {
+      #ifndef STAND_ALONE
+      if (ignore_target_hosts != NULL &&
+           verify_check_this_host(&ignore_target_hosts, NULL,
+             host->name, da->address, NULL) == OK)
+       {
+       DEBUG(D_host_lookup)
+         debug_printf("ignored host %s [%s]\n", host->name, da->address);
+       continue;
+       }
+      #endif
 
-        /* If this is the first address, stick it in the given host block,
-        and change the name if the returned RR has a different name. */
+      /* If this is the first address, stick it in the given host block,
+      and change the name if the returned RR has a different name. */
 
-        if (thishostlast == NULL)
-          {
-          if (strcmpic(host->name, rr->name) != 0)
-            host->name = string_copy_dnsdomain(rr->name);
-          host->address = da->address;
-          host->sort_key = host->mx * 1000 + random_number(500) + randoffset;
-          host->status = hstatus_unknown;
-          host->why = hwhy_unknown;
-          thishostlast = host;
-          }
+      if (thishostlast == NULL)
+       {
+       if (strcmpic(host->name, rr->name) != 0)
+         host->name = string_copy_dnsdomain(rr->name);
+       host->address = da->address;
+       host->sort_key = host->mx * 1000 + random_number(500) + randoffset;
+       host->status = hstatus_unknown;
+       host->why = hwhy_unknown;
+       thishostlast = host;
+       }
 
-        /* Not the first address. Check for, and ignore, duplicates. Then
-        insert in the chain at a random point. */
+      /* Not the first address. Check for, and ignore, duplicates. Then
+      insert in the chain at a random point. */
 
-        else
-          {
-          int new_sort_key;
-          host_item *next;
-
-          /* End of our local chain is specified by "thishostlast". */
-
-          for (next = host;; next = next->next)
-            {
-            if (Ustrcmp(CS da->address, next->address) == 0) break;
-            if (next == thishostlast) { next = NULL; break; }
-            }
-          if (next != NULL) continue;  /* With loop for next address */
-
-          /* Not a duplicate */
-
-          new_sort_key = host->mx * 1000 + random_number(500) + randoffset;
-          next = store_get(sizeof(host_item));
-
-          /* New address goes first: insert the new block after the first one
-          (so as not to disturb the original pointer) but put the new address
-          in the original block. */
-
-          if (new_sort_key < host->sort_key)
-            {
-            *next = *host;                                  /* Copies port */
-            host->next = next;
-            host->address = da->address;
-            host->sort_key = new_sort_key;
-            if (thishostlast == host) thishostlast = next;  /* Local last */
-            if (*lastptr == host) *lastptr = next;          /* Global last */
-            }
-
-          /* Otherwise scan down the addresses for this host to find the
-          one to insert after. */
-
-          else
-            {
-            host_item *h = host;
-            while (h != thishostlast)
-              {
-              if (new_sort_key < h->next->sort_key) break;
-              h = h->next;
-              }
-            *next = *h;                                 /* Copies port */
-            h->next = next;
-            next->address = da->address;
-            next->sort_key = new_sort_key;
-            if (h == thishostlast) thishostlast = next; /* Local last */
-            if (h == *lastptr) *lastptr = next;         /* Global last */
-            }
-          }
-        }
+      else
+       {
+       int new_sort_key;
+       host_item *next;
+
+       /* End of our local chain is specified by "thishostlast". */
+
+       for (next = host;; next = next->next)
+         {
+         if (Ustrcmp(CS da->address, next->address) == 0) break;
+         if (next == thishostlast) { next = NULL; break; }
+         }
+       if (next != NULL) continue;  /* With loop for next address */
+
+       /* Not a duplicate */
+
+       new_sort_key = host->mx * 1000 + random_number(500) + randoffset;
+       next = store_get(sizeof(host_item));
+
+       /* New address goes first: insert the new block after the first one
+       (so as not to disturb the original pointer) but put the new address
+       in the original block. */
+
+       if (new_sort_key < host->sort_key)
+         {
+         *next = *host;                                  /* Copies port */
+         host->next = next;
+         host->address = da->address;
+         host->sort_key = new_sort_key;
+         if (thishostlast == host) thishostlast = next;  /* Local last */
+         if (*lastptr == host) *lastptr = next;          /* Global last */
+         }
+
+       /* Otherwise scan down the addresses for this host to find the
+       one to insert after. */
+
+       else
+         {
+         host_item *h = host;
+         while (h != thishostlast)
+           {
+           if (new_sort_key < h->next->sort_key) break;
+           h = h->next;
+           }
+         *next = *h;                                 /* Copies port */
+         h->next = next;
+         next->address = da->address;
+         next->sort_key = new_sort_key;
+         if (h == thishostlast) thishostlast = next; /* Local last */
+         if (h == *lastptr) *lastptr = next;         /* Global last */
+         }
+       }
       }
     }
   }
@@ -2568,7 +2537,6 @@ host_find_bydns(host_item *host, const uschar *ignore_target_hosts, int whichrrs
   const uschar **fully_qualified_name, BOOL *removed)
 {
 host_item *h, *last;
-dns_record *rr;
 int rc = DNS_FAIL;
 int ind_type = 0;
 int yield;
@@ -2591,20 +2559,21 @@ if (fully_qualified_name != NULL) *fully_qualified_name = host->name;
 dns_init((whichrrs & HOST_FIND_QUALIFY_SINGLE) != 0,
          (whichrrs & HOST_FIND_SEARCH_PARENTS) != 0,
         dnssec_request);
-host_find_failed_syntax = FALSE;
+f.host_find_failed_syntax = FALSE;
 
 /* First, if requested, look for SRV records. The service name is given; we
 assume TCP protocol. DNS domain names are constrained to a maximum of 256
 characters, so the code below should be safe. */
 
-if ((whichrrs & HOST_FIND_BY_SRV) != 0)
+if (whichrrs & HOST_FIND_BY_SRV)
   {
-  uschar buffer[300];
-  uschar *temp_fully_qualified_name = buffer;
+  gstring * g;
+  uschar * temp_fully_qualified_name;
   int prefix_length;
 
-  (void)sprintf(CS buffer, "_%s._tcp.%n%.256s", srv_service, &prefix_length,
-    host->name);
+  g = string_fmt_append(NULL, "_%s._tcp.%n%.256s",
+       srv_service, &prefix_length, host->name);
+  temp_fully_qualified_name = string_from_gstring(g);
   ind_type = T_SRV;
 
   /* Search for SRV records. If the fully qualified name is different to
@@ -2613,7 +2582,8 @@ if ((whichrrs & HOST_FIND_BY_SRV) != 0)
 
   dnssec = DS_UNK;
   lookup_dnssec_authenticated = NULL;
-  rc = dns_lookup_timerwrap(&dnsa, buffer, ind_type, CUSS &temp_fully_qualified_name);
+  rc = dns_lookup_timerwrap(&dnsa, temp_fully_qualified_name, ind_type,
+       CUSS &temp_fully_qualified_name);
 
   DEBUG(D_dns)
     if ((dnssec_request || dnssec_require)
@@ -2629,7 +2599,7 @@ if ((whichrrs & HOST_FIND_BY_SRV) != 0)
       { dnssec = DS_NO; lookup_dnssec_authenticated = US"no"; }
     }
 
-  if (temp_fully_qualified_name != buffer && fully_qualified_name != NULL)
+  if (temp_fully_qualified_name != g->s && fully_qualified_name != NULL)
     *fully_qualified_name = temp_fully_qualified_name + prefix_length;
 
   /* On DNS failures, we give the "try again" error unless the domain is
@@ -2748,18 +2718,15 @@ if (rc != DNS_SUCCEED)
     if (rc == HOST_IGNORED) rc = HOST_FIND_FAILED;  /* No special action */
 
   DEBUG(D_host_lookup)
-    {
-    host_item *h;
-    if (host->address != NULL)
+    if (host->address)
       {
-      if (fully_qualified_name != NULL)
+      if (fully_qualified_name)
         debug_printf("fully qualified name = %s\n", *fully_qualified_name);
-      for (h = host; h != last->next; h = h->next)
+      for (host_item * h = host; h != last->next; h = h->next)
         debug_printf("%s %s mx=%d sort=%d %s\n", h->name,
-          (h->address == NULL)? US"<null>" : h->address, h->mx, h->sort_key,
-          (h->status >= hstatus_unusable)? US"*" : US"");
+          h->address ? h->address : US"<null>", h->mx, h->sort_key,
+          h->status >= hstatus_unusable ? US"*" : US"");
       }
-    }
 
   yield = rc;
   goto out;
@@ -2787,12 +2754,11 @@ host which is not the primary hostname. */
 
 last = NULL;    /* Indicates that not even the first item is filled yet */
 
-for (rr = dns_next_rr(&dnsa, &dnss, RESET_ANSWERS);
+for (dns_record * rr = dns_next_rr(&dnsa, &dnss, RESET_ANSWERS);
      rr;
      rr = dns_next_rr(&dnsa, &dnss, RESET_NEXT)) if (rr->type == ind_type)
   {
-  int precedence;
-  int weight = 0;        /* For SRV records */
+  int precedence, weight;
   int port = PORT_NONE;
   const uschar * s = rr->data; /* MUST be unsigned for GETSHORT */
   uschar data[256];
@@ -2804,13 +2770,11 @@ for (rr = dns_next_rr(&dnsa, &dnss, RESET_ANSWERS);
 
   if (ind_type == T_MX)
     weight = random_number(500);
-
-  /* SRV records are specified with a port and a weight. The weight is used
-  in a special algorithm. However, to start with, we just use it to order the
-  records of equal priority (precedence). */
-
   else
     {
+    /* SRV records are specified with a port and a weight. The weight is used
+    in a special algorithm. However, to start with, we just use it to order the
+    records of equal priority (precedence). */
     GETSHORT(weight, s);
     GETSHORT(port, s);
     }
@@ -2825,17 +2789,16 @@ for (rr = dns_next_rr(&dnsa, &dnss, RESET_ANSWERS);
   never know what junk might get into the DNS (and this case has been seen on
   more than one occasion). */
 
-  if (last != NULL)       /* This is not the first record */
+  if (last)       /* This is not the first record */
     {
     host_item *prev = NULL;
 
     for (h = host; h != last->next; prev = h, h = h->next)
-      {
       if (strcmpic(h->name, data) == 0)
         {
         DEBUG(D_host_lookup)
           debug_printf("discarded duplicate host %s (MX=%d)\n", data,
-            (precedence > h->mx)? precedence : h->mx);
+            precedence > h->mx ? precedence : h->mx);
         if (precedence >= h->mx) goto NEXT_MX_RR; /* Skip greater precedence */
         if (h == host)                            /* Override first item */
           {
@@ -2851,14 +2814,13 @@ for (rr = dns_next_rr(&dnsa, &dnss, RESET_ANSWERS);
         if (h == last) last = prev;
         break;
         }
-      }
     }
 
   /* If this is the first MX or SRV record, put the data into the existing host
   block. Otherwise, add a new block in the correct place; if it has to be
   before the first block, copy the first block's data to a new second block. */
 
-  if (last == NULL)
+  if (!last)
     {
     host->name = string_copy_dnsdomain(data);
     host->address = NULL;
@@ -2870,10 +2832,9 @@ for (rr = dns_next_rr(&dnsa, &dnss, RESET_ANSWERS);
     host->dnssec = dnssec;
     last = host;
     }
+  else
 
   /* Make a new host item and seek the correct insertion place */
-
-  else
     {
     int sort_key = precedence * 1000 + weight;
     host_item *next = store_get(sizeof(host_item));
@@ -2898,21 +2859,18 @@ for (rr = dns_next_rr(&dnsa, &dnss, RESET_ANSWERS);
       host->next = next;
       if (last == host) last = next;
       }
+    else
 
     /* Else scan down the items we have inserted as part of this exercise;
     don't go further. */
-
-    else
       {
       for (h = host; h != last; h = h->next)
-        {
         if (sort_key < h->next->sort_key)
           {
           next->next = h->next;
           h->next = next;
           break;
           }
-        }
 
       /* Join on after the last host item that's part of this
       processing if we haven't stopped sooner. */
@@ -2945,7 +2903,7 @@ remaining in the same priority group. */
 
 if (ind_type == T_SRV)
   {
-  host_item **pptr;
+  host_item ** pptr;
 
   if (host == last && host->name[0] == 0)
     {
@@ -2989,10 +2947,9 @@ if (ind_type == T_SRV)
 
       for (ppptr = pptr, hhh = h;
            hhh != hh;
-           ppptr = &(hhh->next), hhh = hhh->next)
-        {
-        if (hhh->sort_key >= randomizer) break;
-        }
+           ppptr = &hhh->next, hhh = hhh->next)
+        if (hhh->sort_key >= randomizer)
+         break;
 
       /* hhh now points to the host that should go first; ppptr points to the
       place that points to it. Unfortunately, if the start of the minilist is
@@ -3017,7 +2974,6 @@ if (ind_type == T_SRV)
           hhh->next = temp.next;
           h->next = hhh;
           }
-
         else
           {
           hhh->next = h;               /* The rest of the chain follows it */
@@ -3170,14 +3126,14 @@ if (rc != HOST_FIND_FAILED) yield = rc;
 
 DEBUG(D_host_lookup)
   {
-  if (fully_qualified_name != NULL)
+  if (fully_qualified_name)
     debug_printf("fully qualified name = %s\n", *fully_qualified_name);
   debug_printf("host_find_bydns yield = %s (%d); returned hosts:\n",
-    (yield == HOST_FOUND)? "HOST_FOUND" :
-    (yield == HOST_FOUND_LOCAL)? "HOST_FOUND_LOCAL" :
-    (yield == HOST_FIND_SECURITY)? "HOST_FIND_SECURITY" :
-    (yield == HOST_FIND_AGAIN)? "HOST_FIND_AGAIN" :
-    (yield == HOST_FIND_FAILED)? "HOST_FIND_FAILED" : "?",
+    yield == HOST_FOUND                ? "HOST_FOUND" :
+    yield == HOST_FOUND_LOCAL  ? "HOST_FOUND_LOCAL" :
+    yield == HOST_FIND_SECURITY        ? "HOST_FIND_SECURITY" :
+    yield == HOST_FIND_AGAIN   ? "HOST_FIND_AGAIN" :
+    yield == HOST_FIND_FAILED  ? "HOST_FIND_FAILED" : "?",
     yield);
   for (h = host; h != last->next; h = h->next)
     {
@@ -3267,7 +3223,7 @@ while (Ufgets(buffer, 256, stdin) != NULL)
   else if (Ustrcmp(buffer, "require_dnssec")    == 0) require_dnssec = TRUE;
   else if (Ustrcmp(buffer, "no_require_dnssec") == 0) require_dnssec = FALSE;
   else if (Ustrcmp(buffer, "test_harness") == 0)
-    running_in_test_harness = !running_in_test_harness;
+    f.running_in_test_harness = !f.running_in_test_harness;
   else if (Ustrcmp(buffer, "ipv6") == 0) disable_ipv6 = !disable_ipv6;
   else if (Ustrcmp(buffer, "res_debug") == 0)
     {
@@ -3323,7 +3279,6 @@ printf("Testing host_aton\n");
 printf("> ");
 while (Ufgets(buffer, 256, stdin) != NULL)
   {
-  int i;
   int x[4];
   int len = Ustrlen(buffer);
 
@@ -3334,7 +3289,7 @@ while (Ufgets(buffer, 256, stdin) != NULL)
 
   len = host_aton(buffer, x);
   printf("length = %d ", len);
-  for (i = 0; i < len; i++)
+  for (int i = 0; i < len; i++)
     {
     printf("%04x ", (x[i] >> 16) & 0xffff);
     printf("%04x ", x[i] & 0xffff);