First pass update for 4.60 documentation.
authorPhilip Hazel <ph10@hermes.cam.ac.uk>
Thu, 10 Nov 2005 12:30:13 +0000 (12:30 +0000)
committerPhilip Hazel <ph10@hermes.cam.ac.uk>
Thu, 10 Nov 2005 12:30:13 +0000 (12:30 +0000)
13 files changed:
doc/doc-docbook/AdMarkup.txt
doc/doc-docbook/HowItWorks.txt
doc/doc-docbook/Makefile
doc/doc-docbook/MyAsciidoc.conf
doc/doc-docbook/MyStyle-fo.xsl
doc/doc-docbook/MyStyle-html.xsl
doc/doc-docbook/MyStyle.xsl
doc/doc-docbook/Pre-xml
doc/doc-docbook/TidyHTML-filter
doc/doc-docbook/TidyHTML-spec
doc/doc-docbook/filter.ascd
doc/doc-docbook/spec.ascd
doc/doc-txt/OptionLists.txt

index 40942a6..4267f55 100644 (file)
@@ -1,4 +1,4 @@
-$Cambridge: exim/doc/doc-docbook/AdMarkup.txt,v 1.1 2005/06/16 10:32:31 ph10 Exp $
+$Cambridge: exim/doc/doc-docbook/AdMarkup.txt,v 1.2 2005/11/10 12:30:13 ph10 Exp $
 
 Asciidoc markup used in the Exim documentation
 ----------------------------------------------
@@ -130,6 +130,8 @@ example:
   This is an AsciiDoc comment block.
   ///
 
+You can also include one-line comments by starting the line with //.
+
 
 URL REFERENCES
 
@@ -185,7 +187,8 @@ asterisk or if any lines in the block end in a backslash (as is quite often the
 case in Exim configuration examples), you have to use a "listing block" or a
 "literal block" instead of a "literal paragraph". Otherwise an initial asterisk
 makes AsciiDoc think this is a list item, and a terminating backslash causes
-lines to be concatenated.
+lines to be concatenated. Also, a blank line in the block generates two output
+items, so that case should also be avoided.
 
 Another time when you have to use an explicit block is when a display forms
 part of a list item. This is because you have to indent such displays more than
@@ -404,8 +407,9 @@ insert
   [revisionflag="changed"]
 
 This should precede any index settings at the start of the paragraph. If you
-want to do this for a display, you must use the "&&&" block described above,
-because that's the only type that I have set up to support it.
+want to do this for a display, you must use the "...." or "&&&" blocks
+described above, because that's the only types that I have set up to support
+it.
 
 
 FUDGES
index 9be1466..8491909 100644 (file)
@@ -1,4 +1,4 @@
-$Cambridge: exim/doc/doc-docbook/HowItWorks.txt,v 1.1 2005/06/16 10:32:31 ph10 Exp $
+$Cambridge: exim/doc/doc-docbook/HowItWorks.txt,v 1.2 2005/11/10 12:30:13 ph10 Exp $
 
 CREATING THE EXIM DOCUMENTATION
 
@@ -366,6 +366,13 @@ The index.html file as built by xmlto contains the whole table of contents in a
 single line, which makes is hard to debug by hand. Since I was postprocessing
 it anyway, I arranged to insert newlines after every '>' character.
 
+The TidyHTML-spec script also processes every HTML file, to tidy up some of the
+untidy features therein. It turns <div class="literallayout"><p> into <div
+class="literallayout"> and a matching </p></div> into </div> to get rid of
+unwanted vertical white space in literallayout blocks. Before each occurrence
+of </td> it inserts &nbsp; so that the table's cell is a little bit wider than
+the text itself.
+
 The TidyHTML-spec script also takes the opportunity to postprocess the
 spec.html/ix01.html file, which contains the document index. Again, the index
 is generated as one single line, so it splits it up. Then it creates a list of
index 802f740..60bf5ff 100644 (file)
@@ -1,4 +1,4 @@
-# $Cambridge: exim/doc/doc-docbook/Makefile,v 1.1 2005/06/16 10:32:31 ph10 Exp $
+# $Cambridge: exim/doc/doc-docbook/Makefile,v 1.2 2005/11/10 12:30:13 ph10 Exp $
 
 # Make file for Exim documentation from Asciidoc source.
 
@@ -25,10 +25,10 @@ filter-fo.xml: filter.xml Pre-xml
              Pre-xml -bookinfo <filter.xml >filter-fo.xml
 
 filter-html.xml: filter.xml Pre-xml
-             Pre-xml <filter.xml >filter-html.xml
+             Pre-xml -html <filter.xml >filter-html.xml
 
 filter-txt.xml: filter.xml Pre-xml
-             Pre-xml -ascii <filter.xml >filter-txt.xml
+             Pre-xml -ascii -html <filter.xml >filter-txt.xml
 
 filter.fo:    filter-fo.xml MyStyle-filter-fo.xsl MyStyle-fo.xsl MyStyle.xsl
              /bin/rm -rf filter.fo filter-fo.fo
@@ -36,16 +36,18 @@ filter.fo:    filter-fo.xml MyStyle-filter-fo.xsl MyStyle-fo.xsl MyStyle.xsl
              /bin/mv -f filter-fo.fo filter.fo
 
 filter.ps:    filter.fo
-             fop filter.fo -ps filter.ps
+             fop filter.fo -ps filter-tmp.ps
+             mv filter-tmp.ps filter.ps
 
 filter.pdf:   filter.fo
-             fop filter.fo -pdf filter.pdf
+             fop filter.fo -pdf filter-tmp.pdf
+             mv filter-tmp.pdf filter.pdf
 
 filter.html:  filter-html.xml TidyHTML-filter MyStyle-nochunk-html.xsl MyStyle-html.xsl MyStyle.xsl
              /bin/rm -rf filter.html filter-html.html
              xmlto -x MyStyle-nochunk-html.xsl html-nochunks filter-html.xml
              /bin/mv -f filter-html.html filter.html
-              ./TidyHTML-filter
+             ./TidyHTML-filter
 
 filter.txt:   filter-txt.xml Tidytxt MyStyle-txt-html.xsl MyStyle-html.xsl MyStyle.xsl
              /bin/rm -rf filter-txt.html
@@ -75,10 +77,10 @@ spec-fo.xml:  spec.xml Pre-xml
              Pre-xml <spec.xml >spec-fo.xml
 
 spec-html.xml: spec.xml Pre-xml
-             Pre-xml -abstract -oneindex <spec.xml >spec-html.xml
+             Pre-xml -abstract -html -oneindex <spec.xml >spec-html.xml
 
 spec-txt.xml: spec.xml Pre-xml
-             Pre-xml -abstract -ascii -noindex <spec.xml >spec-txt.xml
+             Pre-xml -abstract -ascii -html -noindex <spec.xml >spec-txt.xml
 
 spec.fo:      spec-fo.xml MyStyle-spec-fo.xsl MyStyle-fo.xsl MyStyle.xsl MyTitleStyle.xsl
              /bin/rm -rf spec.fo spec-fo.fo
@@ -86,10 +88,12 @@ spec.fo:      spec-fo.xml MyStyle-spec-fo.xsl MyStyle-fo.xsl MyStyle.xsl MyTitle
              /bin/mv -f spec-fo.fo spec.fo
 
 spec.ps:      spec.fo
-             FOP_OPTS=-Xmx512m fop spec.fo -ps spec.ps
+             FOP_OPTS=-Xmx512m fop spec.fo -ps spec-tmp.ps
+             mv spec-tmp.ps spec.ps
 
 spec.pdf:     spec.fo
-             FOP_OPTS=-Xmx512m fop spec.fo -pdf spec.pdf
+             FOP_OPTS=-Xmx512m fop spec.fo -pdf spec-tmp.pdf
+             mv spec-tmp.pdf spec.pdf
 
 spec.html:    spec-html.xml TidyHTML-spec MyStyle-chunk-html.xsl MyStyle-html.xsl MyStyle.xsl
              /bin/rm -rf spec.html
@@ -126,10 +130,10 @@ test-fo.xml:  test.xml Pre-xml
              ./Pre-xml <test.xml >test-fo.xml
 
 test-html.xml: test.xml Pre-xml
-             ./Pre-xml -abstract -oneindex <test.xml >test-html.xml
+             ./Pre-xml -abstract -html -oneindex <test.xml >test-html.xml
 
 test-txt.xml: test.xml Pre-xml
-             ./Pre-xml -abstract -ascii -noindex <test.xml >test-txt.xml
+             ./Pre-xml -abstract -ascii -html -noindex <test.xml >test-txt.xml
 
 test.fo:      test-fo.xml MyStyle-spec-fo.xsl MyStyle-fo.xsl MyStyle.xsl MyTitleStyle.xsl
              /bin/rm -rf test.fo test-fo.fo
@@ -137,10 +141,12 @@ test.fo:      test-fo.xml MyStyle-spec-fo.xsl MyStyle-fo.xsl MyStyle.xsl MyTitle
              /bin/mv -f test-fo.fo test.fo
 
 test.ps:      test.fo
-             fop test.fo -ps test.ps
+             fop test.fo -ps test-tmp.ps
+             mv test-tmp.ps test.ps
 
 test.pdf:     test.fo
-             fop test.fo -pdf test.pdf
+             fop test.fo -pdf test-tmp.pdf
+             mv test-tmp.pdf test.pdf
 
 test.html:    test-html.xml MyStyle-nochunk-html.xsl MyStyle-html.xsl MyStyle.xsl
              /bin/rm -rf test.html test-html.html
index 4b09e5a..316e167 100644 (file)
@@ -1,4 +1,4 @@
-# $Cambridge: exim/doc/doc-docbook/MyAsciidoc.conf,v 1.1 2005/06/16 10:32:31 ph10 Exp $
+# $Cambridge: exim/doc/doc-docbook/MyAsciidoc.conf,v 1.2 2005/11/10 12:30:13 ph10 Exp $
 
 # Asciidoc configuration customization for creating the DocBook XML sources
 # of the Exim specification and the filter document.
@@ -112,10 +112,17 @@ presubs=specialcharacters,quotes,replacements,macros,callouts
 # The template for my non-monospaced literal layout block
 
 [literallayoutblock]
-<literallayout{revisionflag? revisionflag="{revisionflag}"}>
+<literallayout{revisionflag? revisionflag="{revisionflag}"}>|</literallayout>
+
+# Replace the template for normal literal blocks so as to support the
+# revisionflag feature.
+
+[literalblock]
+<example><title>{title}</title>
+<literallayout{id? id="{id}"} {revisionflag? revisionflag="{revisionflag}"} class="monospaced">
 |
 </literallayout>
-
+{title#}</example>
 
 # Paragraph substitution - use <para> rather than <simplepara>
 
index bd0dd31..3eb6c45 100644 (file)
@@ -1,4 +1,4 @@
-<!-- $Cambridge: exim/doc/doc-docbook/MyStyle-fo.xsl,v 1.1 2005/06/16 10:32:31 ph10 Exp $ -->
+<!-- $Cambridge: exim/doc/doc-docbook/MyStyle-fo.xsl,v 1.2 2005/11/10 12:30:13 ph10 Exp $ -->
 
 <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
                 xmlns:fo="http://www.w3.org/1999/XSL/Format"
@@ -80,11 +80,6 @@ entries print in bold. -->
 </xsl:template>
 
 
-
-
-
-
-
 <!--
 Adjust the sizes of the fonts for titles; the defaults are too gross.
 -->
@@ -148,8 +143,6 @@ http://www.sagehill.net/docbookxsl/PrintHeaders.html
 </xsl:attribute-set>
 
 
-
-
 <!-- Things that can be inserted into the footer are:
 
 <fo:page-number/>
index e0b7537..fb43c73 100644 (file)
@@ -1,4 +1,4 @@
-<!-- $Cambridge: exim/doc/doc-docbook/MyStyle-html.xsl,v 1.1 2005/06/16 10:32:31 ph10 Exp $ -->
+<!-- $Cambridge: exim/doc/doc-docbook/MyStyle-html.xsl,v 1.2 2005/11/10 12:30:13 ph10 Exp $ -->
 
 <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version='1.0'>
 
@@ -8,22 +8,6 @@ specific to HTML output. -->
 
 <xsl:import href="MyStyle.xsl"/>
 
-<xsl:param name="shade.verbatim" select="1"></xsl:param>
-
-<xsl:attribute-set name="shade.verbatim.style">
-  <xsl:attribute name="bgcolor">#F0F0E0</xsl:attribute>
-  <xsl:attribute name="width">100%</xsl:attribute>
-  <xsl:attribute name="cellpadding">2</xsl:attribute>
-  <xsl:attribute name="border">0</xsl:attribute>
-</xsl:attribute-set>
-
-<!-- This is how you can make use of a CSS stylesheet, but at present I'm
-not doing so. -->
-
-<!--
-<xsl:param name="html.stylesheet" select="'Myhtml.css'"/>
--->
-
 
 <!-- This removes the title of the current page from the top of the page -
 redundant because each page is a chapter, whose title shows just below. It also
@@ -37,6 +21,10 @@ think that matters too much. -->
 
 <xsl:param name="show.revisionflag" select="'1'"/>
 
+<!-- This adds an in-line style to the generated HTML. We need this for the
+RevisionFlag stuff. While we are at it, we also set the style for
+<literallayout> blocks. -->
+
 <xsl:template name="system.head.content">
 <style type="text/css">
 <xsl:text>
@@ -51,10 +39,43 @@ span.deleted { text-decoration: line-through;
                background-color: #FF7F7F; }
 span.changed { background-color: #99ff99; }
 span.off     {  }
+
+<!-- Styles for <literallayout> -->
+
+pre.literallayout {
+  background-color: #E8E8D0;
+  padding-left: 0.5cm;
+  padding-top:  5px;
+  padding-bottom: 5px;
+}
+
+div[class=changed] pre.literallayout {
+  background-color: #99ff99;
+  padding-left: 0.5cm;
+  padding-top:  5px;
+  padding-bottom: 5px;
+}
+
+div.literallayout {
+  background-color: #E8E8D0;
+  padding-left: 0.5cm;
+  padding-top:  5px;
+  padding-bottom: 5px;
+}
+
+div[class=changed] div.literallayout {
+  background-color: #99ff99;
+  padding-left: 0.5cm;
+  padding-top:  5px;
+  padding-bottom: 5px;
+}
+
 </xsl:text>
 </style>
 </xsl:template>
 
+<!-- Here's the template for the actual revision flag thingy. -->
+
 <xsl:template match="*[@revisionflag]">
   <xsl:choose>
     <xsl:when test="local-name(.) = 'para' or local-name(.) = 'simpara'                     or local-name(.) = 'formalpara'                     or local-name(.) = 'section'                     or local-name(.) = 'sect1'                     or local-name(.) = 'sect2'                     or local-name(.) = 'sect3'                     or local-name(.) = 'sect4'                     or local-name(.) = 'sect5'                     or local-name(.) = 'chapter'                     or local-name(.) = 'preface'                     or local-name(.) = 'itemizedlist'                     or local-name(.) = 'varlistentry'                     or local-name(.) = 'glossary'                     or local-name(.) = 'bibliography'                     or local-name(.) = 'index'                     or local-name(.) = 'appendix'">
index a3e05cc..78f1cdf 100644 (file)
@@ -1,4 +1,4 @@
-<!-- $Cambridge: exim/doc/doc-docbook/MyStyle.xsl,v 1.1 2005/06/16 10:32:31 ph10 Exp $ -->
+<!-- $Cambridge: exim/doc/doc-docbook/MyStyle.xsl,v 1.2 2005/11/10 12:30:13 ph10 Exp $ -->
 
 <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version='1.0'>
 
@@ -12,7 +12,7 @@ have happen in all forms of output. It is imported by all the drivers. -->
 
 <!-- Set no relative indent for titles and body -->
 
-<xsl:param name="title.margin.left">0pt</xsl:param>
+<xsl:param name="body.start.indent">0pt</xsl:param>
 
 
 <!-- This removes the dot at the end of run-in titles, which we use
index 113e6f9..4e28ada 100755 (executable)
@@ -1,6 +1,6 @@
 #! /usr/bin/perl
 
-# $Cambridge: exim/doc/doc-docbook/Pre-xml,v 1.1 2005/06/16 10:32:31 ph10 Exp $
+# $Cambridge: exim/doc/doc-docbook/Pre-xml,v 1.2 2005/11/10 12:30:13 ph10 Exp $
 
 # Script to pre-process XML input before processing it for various purposes.
 # Options specify which transformations are to be done. Monospaced literal
 #            Replace &#169;   by (c)
 #            Put quotes round <literal> text
 #            Put quotes round <quote> text
-
+#
 # -bookinfo: Remove the <bookinfo> element from the file
-
+#
 # -fi:       Replace "fi" by &#xFB01; except when it is in an XML element, or
 #            inside a <literal>.
-
+#
+# -html:     Certain things are done only for HTML output:
+#
+#            If <literallayout> is followed by optional # space and then a
+#            newline, the space and newline are removed, because otherwise you
+#            get a blank line in the HTML output.
+#
 # -noindex   Remove the XML to generate a Concept and an Options index.
 # -oneindex  Ditto, but add XML to generate a single index.
 
@@ -50,7 +56,7 @@ if ($ascii)
   $s =~ s/&#x2020;/*/g;
   $s =~ s/&#x2021;/**/g;
   $s =~ s/&#x00a0;/ /g;
-  $s =~ s/&#x00a9;/(c)/g;
+  $s =~ s/&#169;/(c)/g;
   $s =~ s/<quote>/"/g;
   $s =~ s/<\/quote>/"/g;
   }
@@ -64,7 +70,9 @@ $s;
 $abstract  = 0;
 $ascii     = 0;
 $bookinfo  = 0;
+$html      = 0;
 $inliteral = 0;
+$inliterallayout = 0;
 $ligatures = 0;
 $madeindex = 0;
 $noindex   = 0;
@@ -76,6 +84,7 @@ foreach $arg (@ARGV)
   elsif ($arg eq "-abstract") { $abstract = 1; }
   elsif ($arg eq "-ascii")    { $ascii = 1; }
   elsif ($arg eq "-bookinfo") { $bookinfo = 1; }
+  elsif ($arg eq "-html")     { $html = 1; }
   elsif ($arg eq "-noindex")  { $noindex = 1; }
   elsif ($arg eq "-oneindex") { $oneindex = 1; }
   else  { die "** Pre-xml: Unknown option \"$arg\"\n"; }
@@ -99,6 +108,7 @@ while (<STDIN>)
 
   if (/^<literallayout class="monospaced">/)
     {
+    $_ = substr($_, 0, -1) if $html;
     print;
     while (<STDIN>)
       {
@@ -128,16 +138,21 @@ while (<STDIN>)
 
   # A line that is not in a monospaced literal block; keep track of which
   # parts are in <literal> and which not. The latter get processed by the
-  # function above.
+  # function above. Items in <literal> get quoted unless they are also in
+  # a <literallayout> block, or are already being quoted.
 
   for (;;)
     {
+    $_ = substr($_, 0, -1) if $html && /^<literallayout[^>]*>\s*\n$/;
+    $inliterallayout = 1 if /^<literallayout/;
+    $inliterallayout = 0 if /^<\/literallayout/;
+
     if ($inliteral)
       {
-      if (/^(.*?)<\/literal>(.*)$/)
+      if (/^(.*?)<\/literal>(?!<\/quote>)(.*)$/)
         {
         print $1;
-        print "\"" if $ascii;
+        print "\"" if $ascii && !$inliterallayout;
         print "</literal>";
         $inliteral = 0;
         $_ = "$2\n";
@@ -153,11 +168,11 @@ while (<STDIN>)
 
     else
       {
-      if (/^(.*?)<literal>(.*)$/)
+      if (/^(.*?)(?<!<quote>)<literal>(.*)$/)
         {
         print &process($1);
         print "<literal>";
-        print "\"" if $ascii;
+        print "\"" if $ascii && !$inliterallayout;
         $inliteral = 1;
         $_ = "$2\n";
         }
index f23a9a7..5056c17 100755 (executable)
@@ -1,15 +1,19 @@
 #! /usr/bin/perl
 
-# $Cambridge: exim/doc/doc-docbook/TidyHTML-filter,v 1.1 2005/06/16 10:32:31 ph10 Exp $
+# $Cambridge: exim/doc/doc-docbook/TidyHTML-filter,v 1.2 2005/11/10 12:30:13 ph10 Exp $
 
 # Script to tidy up the filter HTML file that is generated by xmlto. The
 # following changes are made:
 #
 # 1. Split very long lines.
 # 2. Create reverse links from chapter and section titles back to the TOC.
+# 3. Turn <div class="literallayout"><p> into <div class="literallayout"> and
+#    a matching </p></div> into </div> to get rid of unwanted vertical white
+#    space.
 
 
 $tocref = 1;
+$thisdiv = 0;
 
 # Read in the filter.html file.
 
@@ -56,7 +60,17 @@ for (; $i < scalar(@text); $i++)
 
 for (; $i < scalar(@text); $i++)
   {
-  if ($text[$i] =~ /^<h[23] /)
+  if ($text[$i] eq "<div class=\"literallayout\">\n" && $text[$i+1] eq "<p>\n")
+    {
+    $text[++$i] = "";
+    $thisdiv = 1;
+    }
+  elsif ($thisdiv && $text[$i] eq "</p>\n" && $text[$i+1] eq "</div>\n")
+    {
+    $text[$i] = "";
+    $thisdiv = 0;
+    }
+  elsif ($text[$i] =~ /^<h[23] /)
     {
     $i++;
     if ($text[$i] =~ /^<a( xmlns="[^"]+")? id="([^"]+)">$/)
index 8459bcf..05a9d82 100755 (executable)
@@ -1,6 +1,6 @@
 #! /usr/bin/perl
 
-# $Cambridge: exim/doc/doc-docbook/TidyHTML-spec,v 1.1 2005/06/16 10:32:31 ph10 Exp $
+# $Cambridge: exim/doc/doc-docbook/TidyHTML-spec,v 1.2 2005/11/10 12:30:13 ph10 Exp $
 
 # Script to tidy up the spec HTML files that are generated by xmlto. The
 # following changes are made:
@@ -9,6 +9,11 @@
 # 2. Create reverse links from chapter and section titles back to the TOC.
 # 3. Tidy the ix01.html file - the actual index - by splitting long lines.
 # 4. Insert links from the letter divisions to the top of the Index.
+# 5. Turn <div class="literallayout"><p> into <div class="literallayout"> and
+#    a matching </p></div> into </div> to get rid of unwanted vertical white
+#    space.
+# 6. Before each occurrence of </td> insert &nbsp; so that the table's cell
+#    is a little bit wider than the text itself.
 
 chdir "spec.html";
 
@@ -52,7 +57,10 @@ open (OUT, ">index.html") || die "Failed to open index.html for writing: $!\n";
 print OUT @toc;
 close(OUT);
 
-# Now scan each of the other page files and insert the reverse links.
+# Now scan each of the other page files and insert the reverse links. While
+# we are at it, we tidy up <div class="literallayout"> by removing unwanted
+# paragraph marks, which generate unwanted vertical space. We also insert
+# &nbsp; before </td> to push table cells apart from each other.
 
 foreach $file (@chlist)
   {
@@ -60,9 +68,26 @@ foreach $file (@chlist)
   @text = <IN>;
   close(IN);
 
+  # Insert a newline after certain elements, and split the lines so that each
+  # one is a separate element in the vector. This makes it easier to recognize
+  # these elements.
+
   foreach $line (@text)
     {
-    if ($line =~ /^(.*?)<a( xmlns="[^"]+")? id="([^"]+)"><\/a>(.+?)<\/h(.*)$/)
+    $line =~ s/<p>\s*(?!\n)/<p>\n/g;
+    $line =~ s/<\/p>\s*(?!\n)/<\/p>\n/g;
+    $line =~ s/<\/div>\s*(?!\n)/<\/div>\n/g;
+    $line =~ s/<div([^>]*)>(?!\n)/<div$1>\n/g;
+    }
+
+  for ($i = 0; $i < scalar(@text); $i++)
+    { splice @text, $i, 1, (split /(?<=\n)/, $text[$i]); }
+
+  $thisdiv = 0;
+
+  for ($i = 0; $i < scalar(@text); $i++)
+    {
+    if ($text[$i] =~ /^(.*?)<a( xmlns="[^"]+")? id="([^"]+)"><\/a>(.+?)<\/h(.*)$/)
       {
       my($pre, $opt, $id, $title, $post) = ($1, $2, $3, $4, $5);
 
@@ -73,7 +98,22 @@ foreach $file (@chlist)
       $ref = $backref{"$file"} if !defined $ref;
 
       # Adjust the line
-      $line = "$pre<a$opt href=\"index.html#$ref\" id=\"$id\">$title</a></h$post";
+      $text[$i]= "$pre<a$opt href=\"index.html#$ref\" id=\"$id\">$title</a></h$post";
+      }
+
+    elsif ($text[$i] eq "<div class=\"literallayout\">\n" && $text[$i+1] eq "<p>\n")
+      {
+      $text[++$i] = "";
+      $thisdiv = 1;
+      }
+    elsif ($thisdiv && $text[$i] eq "</p>\n" && $text[$i+1] eq "</div>\n")
+      {
+      $text[$i] = "";
+      $thisdiv = 0;
+      }
+    elsif ($text[$i] =~ /^\s*<\/td>/)
+      {
+      $text[$i] = "&nbsp;$text[$i]";
       }
     }
 
index 8fd9c7e..e8763f5 100644 (file)
@@ -1,5 +1,5 @@
 ///
-$Cambridge: exim/doc/doc-docbook/filter.ascd,v 1.1 2005/06/16 10:32:31 ph10 Exp $
+$Cambridge: exim/doc/doc-docbook/filter.ascd,v 1.2 2005/11/10 12:30:13 ph10 Exp $
 
 This file contains the Asciidoc source for the document that describes Exim's
 filtering facilities from a user's point of view. See the file AdMarkup.txt for
@@ -21,9 +21,9 @@ Exim's interfaces to mail filtering
 :author:          Philip Hazel
 :copyright:       University of Cambridge
 :cpyear:          2005
-:date:            13 May 2005
+:date:            06 October 2005
 :doctitleabbrev:  Exim filtering
-:revision:        4.50
+:revision:        4.60
 
 
 //////////////////////////////////////////////////////////////////////////////
@@ -38,7 +38,7 @@ Forwarding and filtering in Exim
 
 This document describes the user interfaces to Exim's in-built mail filtering
 facilities, and is copyright (C) University of Cambridge 2005. It corresponds
-to Exim version 4.50.
+to Exim version 4.60.
 
 
 
@@ -163,10 +163,10 @@ The recipient is by default the user running the command, and so is the sender,
 but the command can be run with the %-f% option to supply a different sender.
 For example,
 
-...
+....
 /usr/sbin/sendmail -bf myfilter \
    -f islington@never.where <test-message
-...
+....
 
 Alternatively, if the %-f% option is not used, but the first line of the
 supplied message is a ``From'' separator from a message folder file (not the same
@@ -239,8 +239,8 @@ Sieve filter files
 ------------------
 The code for Sieve filtering in Exim was contributed by Michael Haardt, and
 most of the content of this chapter is taken from the notes he provided. Since
-Sieve is a extensible language, it is important to understand ``Sieve'' in this
-context as ``the specific implementation of Sieve for Exim''.
+Sieve is an extensible language, it is important to understand ``Sieve'' in
+this context as ``the specific implementation of Sieve for Exim''.
 
 This chapter does not contain a description of Sieve, since that can be found
 in RFC 3028, which should be read in conjunction with these notes.
@@ -281,13 +281,13 @@ Strings containing header names
 RFC 3028 does not specify what happens if a string denoting a header field does
 not contain a valid header name, for example, it contains a colon. This
 implementation generates an error instead of ignoring the header field in order
-to ease script debugging, which fits in the common picture of Sieve.
+to ease script debugging, which fits in with the common picture of Sieve.
 
 
 
 Exists test with empty list of headers
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-The *exists* test succeeds only if all specified headers exist. RFC 3028
+The *exists* test succeeds only if all the specified headers exist. RFC 3028
 does not explicitly specify what happens on an empty list of headers. This
 implementation evaluates that condition as true, interpreting the RFC in a
 strict sense.
@@ -357,12 +357,12 @@ it to be.
 
 String arguments
 ~~~~~~~~~~~~~~~~
-There has been confusion if the string arguments to *require* are to be
-matched case-sensitively or not. This implementation matches them with
-the match type ^:is^ (default, see section 2.7.1) and the comparator
-^i;ascii-casemap^ (default, see section 2.7.3). The RFC defines the
-command defaults clearly, so any different implementations violate RFC
-3028. The same is valid for comparator names, also specified as strings.
+There has been confusion if the string arguments to *require* are to be matched
+case-sensitively or not. This implementation matches them with the match type
+^:is^ (default, see section 2.7.1 of the RFC) and the comparator
+^i;ascii-casemap^ (default, see section 2.7.3 of the RFC). The RFC defines the
+command defaults clearly, so any different implementations violate RFC 3028.
+The same is valid for comparator names, also specified as strings.
 
 
 
@@ -371,7 +371,7 @@ Number units
 There is a mistake in RFC 3028: the suffix G denotes gibi-, not tebibyte.
 The mistake is obvious, because RFC 3028 specifies G to denote 2^30
 (which is gibi, not tebi), and that is what this implementation uses as
-scaling factor for the suffix G.
+the scaling factor for the suffix G.
 
 
 
@@ -388,13 +388,13 @@ RFC 3028 requires the use of CRLF to terminate a line.
 The rationale was that CRLF is universally used in network protocols
 to mark the end of the line. This implementation does not embed Sieve
 in a network protocol, but uses Sieve scripts as part of the Exim MTA.
-Since all parts of Exim use LF as newline character, this implementation
+Since all parts of Exim use LF as the newline character, this implementation
 does, too, by default, though the system administrator may choose (at Exim
 compile time) to use CRLF instead.
 
 Exim violates RFC 2822, section 3.6.8, by accepting 8-bit header names, so
 this implementation repeats this violation to stay consistent with Exim.
-This is in preparation to UTF-8 data.
+This is in preparation for UTF-8 data.
 
 Sieve scripts cannot contain NUL characters in strings, but mail
 headers could contain MIME encoded NUL characters, which could never
@@ -411,7 +411,7 @@ evaluate the first test as true.
   header :contains "Subject" ["def"]
   header :matches "Subject" ["abc?def"]
 
-Note that by considering Sieve to be a MUA, RFC 2047 can be interpreted
+Note that by considering Sieve to be an MUA, RFC 2047 can be interpreted
 in a way that NUL characters truncating strings is allowed for Sieve
 implementations, although not recommended. It is further allowed to use
 encoded NUL characters in headers, but that's not recommended either.
@@ -425,7 +425,7 @@ implementation violates RFC 3028 and treats such MIME words literally.
 That way at least something could be matched.
 
 The folder specified by *fileinto* must not contain the character
-sequence ``..'' to avoid security problems. RFC 3028 does not specify the
+sequence ``##`..`##'' to avoid security problems. RFC 3028 does not specify the
 syntax of folders apart from *keep* being equivalent to
 
   fileinto "INBOX";
@@ -434,7 +434,7 @@ This implementation uses _inbox_ instead.
 
 Sieve script errors currently cause messages to be silently filed into
 _inbox_.  RFC 3028 requires that the user is notified of that condition.
-This may be implemented in future by adding a header line to mails that
+This may be implemented in the future by adding a header line to mails that
 are filed into _inbox_ due to an error in the filter.
 
 
@@ -489,7 +489,7 @@ it is part of a condition, it must also be free of round brackets
 - Otherwise, it must be enclosed in double quotation marks. In this case, the
 character \ (backslash) is treated as an ``escape character'' within the string,
 causing the following character or characters to be treated specially:
-
++
 &&&&
 `\n`   is replaced by a newline
 `\r`   is replaced by a carriage return
@@ -515,10 +515,6 @@ The maximum permitted length of a data string, before expansion, is 1024
 characters.
 
 
-++++++++++++
-<?hard-pagebreak?>
-++++++++++++
-
 [[SECTfilterstringexpansion]]
 String expansion
 ~~~~~~~~~~~~~~~~
@@ -1066,10 +1062,10 @@ in the format of a 'To:' or 'Cc:' header line. In fact, the text you supply
 here is copied exactly into the appropriate header line. It may contain
 additional information as well as email addresses. For example:
 
-...
+....
 mail to "Julius Caesar <jc@rome.example>, \
          <ma@rome.example> (Mark A.)"
-...
+....
 
 Similarly, the texts supplied for ^from^ and ^reply_to^ are copied into
 their respective header lines.
@@ -1112,7 +1108,7 @@ forward file, Exim normally adds a 'Sender:' header to the message,
 though it can be configured not to do this.
 
 The %extra_headers% keyword allows you to add custom header lines to the
-message. The text supplied must be one or more syntactically valid RFC 2882
+message. The text supplied must be one or more syntactically valid RFC 2822
 header lines. You can use ``\n'' within quoted text to specify newlines between
 headers, and also to define continued header lines. For example:
 
@@ -1237,9 +1233,6 @@ being tested by means of the %-bf% option (see section <<SECTtesting>> above),
 the value of the string is written to the standard output.
 
 
-++++++++++++
-<?hard-pagebreak?>
-++++++++++++
 [[SECTfail]]
 The fail command
 ~~~~~~~~~~~~~~~~
@@ -1322,9 +1315,6 @@ negative forms of condition that are more English-like.
 
 
 
-++++++++++++
-<?hard-pagebreak?>
-++++++++++++
 String testing conditions
 ~~~~~~~~~~~~~~~~~~~~~~~~~
 There are a number of conditions that operate on text strings, using the words
@@ -1606,8 +1596,17 @@ Details of the personal condition
 The basic ^personal^ test is roughly equivalent to the following:
 
   not error_message and
-  $message_headers does not contain "\nList-" and
-  $header_auto-submitted: does not contain "auto-" and
+  $message_headers does not contain "\nList-Id:" and
+  $message_headers does not contain "\nList-Help:" and
+  $message_headers does not contain "\nList-Subscribe:" and
+  $message_headers does not contain "\nList-Unsubscribe:" and
+  $message_headers does not contain "\nList-Post:" and
+  $message_headers does not contain "\nList-Owner:" and
+  $message_headers does not contain "\nList-Archive:" and
+    (
+    "${if def h_auto-submitted:{present}{absent}}" is "absent" or
+    $header_auto-submitted: is "no"
+    ) and
   $header_precedence: does not contain "bulk" and
   $header_precedence: does not contain "list" and
   $header_precedence: does not contain "junk" and
@@ -1745,7 +1744,7 @@ Throw away all mail from one site, except from postmaster:
      seen finish
   endif
 
-Handle multiple personal mailboxes
+Handle multiple personal mailboxes:
 
   # Exim filter
   if $local_part_suffix is "-foo"
index 88b6440..6a91d6d 100644 (file)
@@ -1,5 +1,5 @@
 ////////////////////////////////////////////////////////////////////////////
-$Cambridge: exim/doc/doc-docbook/spec.ascd,v 1.1 2005/06/16 10:32:31 ph10 Exp $
+$Cambridge: exim/doc/doc-docbook/spec.ascd,v 1.2 2005/11/10 12:30:13 ph10 Exp $
 
 This is the primary source of the Exim Manual. It is an AsciiDoc document
 that is converted into DocBook XML for subsequent conversion into printing
@@ -26,9 +26,9 @@ Specification of the Exim Mail Transfer Agent
 :author:          Philip Hazel
 :copyright:       University of Cambridge
 :cpyear:          2005
-:date:            13 May 2005
+:date:            01 November 2005
 :doctitleabbrev:  The Exim MTA
-:revision:        4.50
+:revision:        4.60
 
 
 //////////////////////////////////////////////////////////////////////////////
@@ -53,8 +53,8 @@ incorrect XML.
 
 :ACL:             access control lists (ACLs)
 :star:            *
-:previousversion: 4.40
-:version:         4.50
+:previousversion: 4.50
+:version:         4.60
 
 
 ////////////////////////////////////////////////////////////////////////////
@@ -74,6 +74,14 @@ because is it not something that is likely to change often.
   <see><emphasis>rewriting</emphasis></see>
 </indexterm>
 <indexterm role="concept">
+  <primary>Bounce Address Tag Validation</primary>
+  <see><emphasis>BATV</emphasis></see>
+</indexterm>
+<indexterm role="concept">
+  <primary>Client SMTP Authorization</primary>
+  <see><emphasis>CSA</emphasis></see>
+</indexterm>
+<indexterm role="concept">
   <primary>CR character</primary>
   <see><emphasis>carriage return</emphasis></see>
 </indexterm>
@@ -120,6 +128,10 @@ because is it not something that is likely to change often.
   <see><emphasis>limit</emphasis></see>
 </indexterm>
 <indexterm role="concept">
+  <primary>monitor</primary>
+  <see><emphasis>Exim monitor</emphasis></see>
+</indexterm>
+<indexterm role="concept">
   <primary>no_<emphasis>xxx</emphasis></primary>
   <see>entry for xxx</see>
 </indexterm>
@@ -185,12 +197,12 @@ run on hosts that are permanently connected to the Internet. However, it can be
 used on intermittently connected hosts with suitable configuration adjustments.
 
 Configuration files currently exist for the following operating systems: AIX,
-BSD/OS (aka BSDI), Darwin (Mac OS X), DGUX, FreeBSD, GNU/Hurd, GNU/Linux,
-HI-OSF (Hitachi), HP-UX, IRIX, MIPS RISCOS, NetBSD, OpenBSD, QNX, SCO, SCO
-SVR4.2 (aka UNIX-SV), Solaris (aka SunOS5), SunOS4, Tru64-Unix (formerly
-Digital UNIX, formerly DEC-OSF1), Ultrix, and Unixware. Some of these operating
-systems are no longer current and cannot easily be tested, so the configuration
-files may no longer work in practice.
+BSD/OS (aka BSDI), Darwin (Mac OS X), DGUX, Dragonfly, FreeBSD, GNU/Hurd,
+GNU/Linux, HI-OSF (Hitachi), HI-UX, HP-UX, IRIX, MIPS RISCOS, NetBSD, OpenBSD,
+OpenUNIX, QNX, SCO, SCO SVR4.2 (aka UNIX-SV), Solaris (aka SunOS5), SunOS4,
+Tru64-Unix (formerly Digital UNIX, formerly DEC-OSF1), Ultrix, and Unixware.
+Some of these operating systems are no longer current and cannot easily be
+tested, so the configuration files may no longer work in practice.
 
 There are also configuration files for compiling Exim in the Cygwin environment
 that can be installed on systems running Windows. However, this document does
@@ -249,6 +261,16 @@ Internet mail. Inevitably, however, the book is unlikely to be fully up-to-date
 with the latest release of Exim. (Note that the earlier book about Exim,
 published by O'Reilly, covers Exim 3, and many things have changed in Exim 4.)
 
+[revisionflag="changed"]
+cindex:[Debian,information sources]
+If you are using a Debian distribution of Exim, you will find information about
+Debian-specific features in the file
+&&&&
+_/usr/share/doc/exim4-base/README.Debian_
+&&&&
+The command ^man update-exim.conf^ is another source of Debian-specific
+information.
+
 cindex:[_doc/NewStuff_]
 cindex:[_doc/ChangeLog_]
 cindex:[change log]
@@ -294,7 +316,7 @@ FTP and web sites
 ~~~~~~~~~~~~~~~~~
 cindex:[web site]
 cindex:[FTP site]
-The primary distribution site for Exim is currently the University of
+The primary site for Exim source distributions is currently the University of
 Cambridge's FTP site, whose contents are described in 'Where to find the Exim
 distribution' below. In addition, there is a web site and an FTP site at
 %exim.org%. These are now also hosted at the University of Cambridge. The
@@ -330,14 +352,19 @@ or search the archives via the mailing lists link on the Exim home page. The
 *http://www.egroups.com/list/exim-users[]*, an archiving system with searching
 capabilities.
 
+[revisionflag="changed"]
+cindex:[Debian,mailing list for]
+If you are using a Debian distribution of Exim, you may wish to subscribe to
+the Debian-specific mailing list, which is
+'pkg-exim4-users@lists.alioth.debian.org'.
+
 
 Exim training
 ~~~~~~~~~~~~~
 cindex:[training courses]
-From time to time (approximately annually at the time of writing),
-lecture-based training courses are run by the author of Exim in Cambridge, UK.
-Details can be found on the web site
-*http://www-tus.csx.cam.ac.uk/courses/exim/[]*.
+From time to time (approximately annually at the time of writing), training
+courses are run by the author of Exim in Cambridge, UK. Details can be found on
+the web site *http://www-tus.csx.cam.ac.uk/courses/exim/[]*.
 
 
 Bug reports
@@ -346,7 +373,7 @@ cindex:[bug reports]
 cindex:[reporting bugs]
 Reports of obvious bugs should be emailed to 'bugs@exim.org'. However, if
 you are unsure whether some behaviour is a bug or not, the best thing to do is
-to post a message to the 'exim-users' mailing list and have it discussed.
+to post a message to the 'exim-dev' mailing list and have it discussed.
 
 
 
@@ -582,7 +609,8 @@ cindex:[local delivery,definition of]
 cindex:[remote delivery, definition of]
 The terms 'local delivery' and 'remote delivery' are used to distinguish
 delivery to a file or a pipe on the local host from delivery by SMTP over
-TCP/IP to a remote host.
+TCP/IP to another host. As far as Exim is concerned, all hosts other than the
+host it is running on are 'remote'.
 
 cindex:[return path,definition of]
 'Return path' is another name that is used for the sender address in a
@@ -634,6 +662,10 @@ Support for the cdb (Constant DataBase) lookup method is provided by code
 contributed by Nigel Metheringham of (at the time he contributed it) Planet
 Online Ltd. which contains the following statements:
 +
+++++++++++++++++++++++
+<blockquote>
+++++++++++++++++++++++
++
 Copyright (c) 1998 Nigel Metheringham, Planet Online Ltd
 +
 This program is free software; you can redistribute it and/or modify it under
@@ -647,6 +679,10 @@ the spec and sample code for cdb can be obtained from
 from Dan Bernstein's implementation (which has no license restrictions applied
 to it).
 +
+++++++++++++++++++++++
+</blockquote>
+++++++++++++++++++++++
++
 The implementation is completely contained within the code of Exim.
 It does not link against an external cdb library.
 
@@ -666,6 +702,10 @@ by code taken from the Cyrus-SASL library and adapted by Alexander S.
 Sabourenkov. The permission notice appears below, in accordance with the
 conditions expressed therein.
 +
+++++++++++++++++++++++
+<blockquote>
+++++++++++++++++++++++
++
 Copyright (c) 2001 Carnegie Mellon University.  All rights reserved.
 +
 Redistribution and use in source and binary forms, with or without
@@ -686,19 +726,22 @@ prior written permission. For permission or any other legal
 details, please contact
 +
 &&&
-Office of Technology Transfer
-Carnegie Mellon University
-5000 Forbes Avenue
-Pittsburgh, PA  15213-3890
-(412) 268-4387, fax: (412) 268-7395
-tech-transfer@andrew.cmu.edu
+              Office of Technology Transfer
+              Carnegie Mellon University
+              5000 Forbes Avenue
+              Pittsburgh, PA  15213-3890
+              (412) 268-4387, fax: (412) 268-7395
+              tech-transfer@andrew.cmu.edu
 &&&
+///
+The need to indent that block explicitly is a pain.
+///
 
 . Redistributions of any form whatsoever must retain the following
 acknowledgment:
 +
-'This product includes software developed by Computing Services
-at Carnegie Mellon University (*http://www.cmu.edu/computing/[]*).'
+``This product includes software developed by Computing Services
+at Carnegie Mellon University (*http://www.cmu.edu/computing/[]*).''
 +
 CARNEGIE MELLON UNIVERSITY DISCLAIMS ALL WARRANTIES WITH REGARD TO
 THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
@@ -708,7 +751,16 @@ WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
 AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
 OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 
-. cindex:[monitor]
+///
+Note, no "+" line there, because we want to terminate the inner list item
+before ending the block quote.
+///
++
+++++++++++++++++++++++
+</blockquote>
+++++++++++++++++++++++
+
+- cindex:[Exim monitor,acknowledgement]
 cindex:[X-windows]
 cindex:[Athena]
 The Exim Monitor program, which is an X-Window application, includes
@@ -716,6 +768,10 @@ modified versions of the Athena StripChart and TextPop widgets.
 This code is copyright by DEC and MIT, and their permission notice appears
 below, in accordance with the conditions expressed therein.
 +
+++++++++++++++++++++++
+<blockquote>
+++++++++++++++++++++++
++
 Copyright 1987, 1988 by Digital Equipment Corporation, Maynard, Massachusetts,
 and the Massachusetts Institute of Technology, Cambridge, Massachusetts.
 +
@@ -736,8 +792,12 @@ ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
 WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
 ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
 SOFTWARE.
++
+++++++++++++++++++++++
+</blockquote>
+++++++++++++++++++++++
 
-. Many people have contributed code fragments, some large, some small, that were
+- Many people have contributed code fragments, some large, some small, that were
 not covered by any specific licence requirements. It is assumed that the
 contributors are happy to see their code incoporated into Exim under the GPL.
 
@@ -847,7 +907,7 @@ normally encoding numbers in base 62. However, in the Darwin operating
 system (Mac OS X) and when Exim is compiled to run under Cygwin, base 36
 (avoiding the use of lower case letters) is used instead, because the message
 id is used to construct file names, and the names of files in those systems are
-not case-sensitive.
+not always case-sensitive.
 
 cindex:[pid (process id),re-use of]
 The detail of the contents of the message id have changed as Exim has evolved.
@@ -888,8 +948,8 @@ Receiving mail
 ~~~~~~~~~~~~~~
 cindex:[receiving mail]
 cindex:[message,reception]
-The only way Exim can receive mail from a remote host is using SMTP over
-TCP/IP, in which case the sender and recipient addresses are tranferred using
+The only way Exim can receive mail from another host is using SMTP over
+TCP/IP, in which case the sender and recipient addresses are transferred using
 SMTP commands. However, from a locally running process (such as a user's MUA),
 there are several possibilities:
 
@@ -1004,21 +1064,17 @@ An administrator can ``thaw'' such messages when the problem has been corrected,
 and can also freeze individual messages by hand if necessary. In addition, an
 administrator can force a delivery error, causing a bounce message to be sent.
 
-cindex:[%auto_thaw%]
-There is an option called %auto_thaw%, which can be used to cause Exim to
-retry frozen messages after a certain time. When this is set, no message will
-remain on the queue for ever, because the delivery timeout will eventually be
-reached. Delivery failure reports (bounce messages) that reach this timeout are
-discarded.
-
+[revisionflag="changed"]
 cindex:[%timeout_frozen_after%]
-There is also an option called %timeout_frozen_after%, which discards frozen
-messages after a certain time.
+cindex:[%ignore_bounce_errors_after%]
+There are options called %ignore_bounce_errors_after% and
+%timeout_frozen_after%, which discard frozen messages after a certain time.
+The first applies only to frozen bounces, the second to any frozen messages.
 
 cindex:[message,log file for]
 cindex:[log,file for each message]
 While Exim is working on a message, it writes information about each delivery
-attempt to the main log file. This includes successful, unsuccessful, and
+attempt to its main log file. This includes successful, unsuccessful, and
 delayed deliveries for each recipient (see chapter <<CHAPlog>>). The log lines
 are also written to a separate 'message log' file for each message. These
 logs are solely for the benefit of the administrator, and are normally deleted
@@ -1069,7 +1125,7 @@ configuration of the driver), and the generic driver name when discussing
 the driver's features in general.
 
 A 'router' is a driver that operates on an address, either determining how
-its delivery should happen, by routing it to a specific transport, or
+its delivery should happen, by assigning it to a specific transport, or
 converting the address into one or more new addresses (for example, via an
 alias file). A router may also explicitly choose to fail an address, causing it
 to be bounced.
@@ -1085,11 +1141,10 @@ cindex:[preconditions,definition of]
 An address is processed by passing it to each configured router instance in
 turn, subject to certain preconditions, until a router accepts the address or
 specifies that it should be bounced. We will describe this process in more
-detail shortly. As a simple example, the diagram below illustrates how each
-recipient address in a message is processed in a small configuration of three
-routers that are configured in various ways.
+detail shortly. First, as a simple example, we consider how each recipient
+address in a message is processed in a small configuration of three routers.
 
-To make this a more concrete example, we'll describe it in terms of some actual
+To make this a more concrete example, it is described in terms of some actual
 routers, but remember, this is only an example. You can configure Exim's
 routers in many different ways, and there may be any number of routers in a
 configuration.
@@ -1101,22 +1156,15 @@ is set up which looks for the special domains known to the host (for example,
 its own domain name), and the router is run for addresses that do 'not'
 match. Typically, this is a router that looks up domains in the DNS in order to
 find the hosts to which this address routes. If it succeeds, the address is
-queued for a suitable SMTP transport; if it does not succeed, the router is
+assigned to a suitable SMTP transport; if it does not succeed, the router is
 configured to fail the address.
 
-///
-The example pictured could be a configuration of this type. The second and
-third routers can only be run for addresses for which the preconditions for
-the first router are not met. If one of these preconditions checks the
-domain, the second and third routers are run only for domains that are somehow
-special to the local host.
-///
-
-The second router does redirection -- also known as aliasing and forwarding.
-When it generates one or more new addresses from the original, each of them is
-routed independently from the start. Otherwise, the router may cause an address
-to fail, or it may simply decline to handle the address, in which case the
-address is passed to the next router.
+The second router is reached only when the domain is recognized as one that
+``belongs'' to the local host. This router does redirection -- also known as
+aliasing and forwarding. When it generates one or more new addresses from the
+original, each of them is routed independently from the start. Otherwise, the
+router may cause an address to fail, or it may simply decline to handle the
+address, in which case the address is passed to the next router.
 
 The final router in many configurations is one that checks to see if the
 address belongs to a local mailbox. The precondition may involve a check to
@@ -1161,7 +1209,7 @@ passed to the next router. When all the preconditions on a router 'are' met,
 the router is run. What happens next depends on the outcome, which is one of
 the following:
 
-- 'accept': The router accepts the address, and either queues it for a
+- 'accept': The router accepts the address, and either assigns it to a
 transport, or generates one or more ``child'' addresses. Processing the original
 address ceases,
 cindex:[%unseen% option]
@@ -1171,15 +1219,10 @@ for keeping archive copies of messages). When %unseen% is set, the address is
 passed to the next router. Normally, however, an 'accept' return marks the
 end of routing.
 +
-cindex:[case of local parts]
-cindex:[address duplicate, discarding]
-If child addresses are generated, Exim checks to see whether they are
-duplicates of any existing recipient addresses. During this check, local parts
-are treated as case-sensitive. Duplicate addresses are discarded. Each of the
-remaining child addresses is then processed independently, starting with the
-first router by default. It is possible to change this by setting the
-%redirect_router% option to specify which router to start at for child
-addresses. Unlike %pass_router% (see below) the router specified by
+Any child addresses generated by the router are processed independently,
+starting with the first router by default. It is possible to change this by
+setting the %redirect_router% option to specify which router to start at for
+child addresses. Unlike %pass_router% (see below) the router specified by
 %redirect_router% may be anywhere in the router configuration.
 
 - 'pass': The router recognizes the address, but cannot handle it itself. It
@@ -1191,26 +1234,26 @@ must be below the current router (to avoid loops).
 - 'decline': The router declines to accept the address because it does not
 recognize it at all. By default, the address is passed to the next router, but
 this can be prevented by setting the %no_more% option. When %no_more% is set,
-all the remaining routers are skipped.
+all the remaining routers are skipped. In effect, %no_more% converts 'decline'
+into 'fail'.
 
 - 'fail': The router determines that the address should fail, and queues it for
 the generation of a bounce message. There is no further processing of the
 original address unless %unseen% is set on the router.
 
-- 'defer': The router cannot handle the address at the present time. (A database
-may be offline, or a DNS lookup may have timed out.) No further processing of
-the address happens in this delivery attempt. It is tried again next time the
-message is considered for delivery.
+- 'defer': The router cannot handle the address at the present time. (A
+database may be offline, or a DNS lookup may have timed out.) No further
+processing of the address happens in this delivery attempt. It is tried again
+next time the message is considered for delivery.
 
 - 'error': There is some error in the router (for example, a syntax error in
 its configuration). The action is as for defer.
 
 If an address reaches the end of the routers without having been accepted by
-any of them, it is bounced as unrouteable.
-The default error message in this situation is ``unrouteable address'', but you
-can set your own message by making use of the %cannot_route_message% option.
-This can be set for any router; the value from the last router that ``saw''
-the address is used.
+any of them, it is bounced as unrouteable. The default error message in this
+situation is ``unrouteable address'', but you can set your own message by
+making use of the %cannot_route_message% option. This can be set for any
+router; the value from the last router that ``saw'' the address is used.
 
 Sometimes while routing you want to fail a delivery when some conditions are
 met but others are not, instead of passing the address on for further routing.
@@ -1219,6 +1262,16 @@ when the relevant conditions are met. The ^redirect^ router has a ``fail''
 facility for this purpose.
 
 
+Duplicate addresses
+~~~~~~~~~~~~~~~~~~~
+
+[revisionflag="changed"]
+cindex:[case of local parts]
+cindex:[address duplicate, discarding]
+Once routing is complete, Exim scans the addresses that are assigned to local
+and remote transports, and discards any duplicates that it finds. During this
+check, local parts are treated as case-sensitive.
+
 
 
 [[SECTrouprecon]]
@@ -1255,13 +1308,16 @@ simulate the effect of the scanner.
 - Routers can be designated for use only when verifying an address, as
 opposed to routing it for delivery. The %verify_only% option controls this.
 
-- Certain routers can be explicitly skipped when running the routers to check an
-address given in the SMTP EXPN command (see the %expn% option).
+- Individual routers can be explicitly skipped when running the routers to
+check an address given in the SMTP EXPN command (see the %expn% option).
 
-- If the %domains% option is set, the domain of the address must be in the set of
-domains that it defines.
+- If the %domains% option is set, the domain of the address must be in the set
+of domains that it defines.
 
-- If the %local_parts% option is set, the local part of the address must be in
+- cindex:[$local_part_prefix$]
+cindex:[$local_part$]
+cindex:[$local_part_suffix$]
+If the %local_parts% option is set, the local part of the address must be in
 the set of local parts that it defines. If %local_part_prefix% or
 %local_part_suffix% is in use, the prefix or suffix is removed from the local
 part before this check. If you want to do precondition tests on local parts
@@ -1269,11 +1325,14 @@ that include affixes, you can do so by using a %condition% option (see below)
 that uses the variables $local_part$, $local_part_prefix$, and
 $local_part_suffix$ as necessary.
 
-- If the %check_local_user% option is set, the local part must be the name of
-an account on the local host.
-If this check succeeds, the uid and gid of the local user are placed in
-$local_user_uid$ and $local_user_gid$; these values can be used in the
-remaining preconditions.
+- cindex:[$local_user_uid$]
+cindex:[$local_user_gid$]
+cindex:[$home$]
+If the %check_local_user% option is set, the local part must be the name of
+an account on the local host. If this check succeeds, the uid and gid of the
+local user are placed in $local_user_uid$ and $local_user_gid$ and the user's
+home directory is placed in $home$; these values can be used in the remaining
+preconditions.
 
 - If the %router_home_directory% option is set, it is expanded at this point,
 because it overrides the value of $home$. If this expansion were left till
@@ -1333,13 +1392,12 @@ can be processed entirely independently of each other.
 
 - cindex:[routing,loops in]
 cindex:[loop,while routing]
-A router that accepts an address may set up a local or a remote transport for
-it. However, the transport is not run at this time. Instead, the address is
-placed on a list for the particular transport, to be run later. Alternatively,
-the router may generate one or more new addresses (typically from alias,
-forward, or filter files). New addresses are fed back into this process from
-the top, but in order to avoid loops, a router ignores any address which has an
-identically-named ancestor that was processed by itself.
+A router that accepts an address may assign it to a local or a remote transport. However, the transport is not run at this time. Instead, the address is
+placed on a list for the particular transport, which will be run later.
+Alternatively, the router may generate one or more new addresses (typically
+from alias, forward, or filter files). New addresses are fed back into this
+process from the top, but in order to avoid loops, a router ignores any address
+which has an identically-named ancestor that was processed by itself.
 
 - When all the routing has been done, addresses that have been successfully
 handled are passed to their assigned transports. When local transports are
@@ -1405,7 +1463,7 @@ uses the %-q% option with a time interval to start queue runners at regular
 intervals, or use some other means (such as 'cron') to start them. If you do
 not arrange for queue runners to be run, messages that fail temporarily at the
 first attempt will remain on your queue for ever. A queue runner process works
-it way through the queue, one message at a time, trying each delivery that has
+its way through the queue, one message at a time, trying each delivery that has
 passed its retry time.
 You can run several queue runners at once.
 
@@ -1481,7 +1539,7 @@ cindex:[bounce message,failure to deliver]
 If a bounce message (either locally generated or received from a remote host)
 itself suffers a permanent delivery failure, the message is left on the queue,
 but it is frozen, awaiting the attention of an administrator. There are options
-which can be used to make Exim discard such failed messages, or to keep them
+that can be used to make Exim discard such failed messages, or to keep them
 for only a short time (see %timeout_frozen_after% and
 %ignore_bounce_errors_after%).
 
@@ -1688,7 +1746,7 @@ detected early in Exim's execution (such as a malformed configuration file) can
 be logged.
 
 cindex:[content scanning,specifying at build time]
-Exim's interfaces for calling virus and spam scanning sofware directly from
+Exim's interfaces for calling virus and spam scanning software directly from
 access control lists are not compiled by default. If you want to include these
 facilities, you need to set
 
@@ -1869,6 +1927,25 @@ FAQ, where some common problems are covered.
 
 
 
+Output from ``make''
+~~~~~~~~~~~~~~~~~~~~
+
+[revisionflag="changed"]
+The output produced by the 'make' process for compile lines is often very
+unreadable, because these lines can be very long. For this reason, the normal
+output is suppressed by default, and instead output similar to that which
+appears when compiling the 2.6 Linux kernel is generated: just a short line for
+each module that is being compiled or linked. However, it is still possible to
+get the full output, by calling 'make' like this:
+
+  FULLECHO='' make -e
+
+The value of FULLECHO defaults to ``@'', the flag character that suppresses
+command reflection in 'make'. When you ask for the full output, it is
+given in addition to the the short output.
+
+
+
 
 [[SECToverride]]
 Overriding build-time options for Exim
@@ -1958,14 +2035,11 @@ case of LDAP, NIS, and NIS+, the settings for _Local/Makefile_ are:
   LOOKUP_NISPLUS=yes
 
 and similar settings apply to the other lookup types. They are all listed in
-_src/EDITME_. In most cases the relevant include files and interface
+_src/EDITME_. In many cases the relevant include files and interface
 libraries need to be installed before compiling Exim.
 cindex:[cdb,including support for]
-However, in the case of cdb, which is included in the binary only if
-
-  LOOKUP_CDB=yes
-
-is set, the code is entirely contained within Exim, and no external include
+However, there are some optional lookup types (such as cdb) for which
+the code is entirely contained within Exim, and no external include
 files or libraries are required. When a lookup type is not included in the
 binary, attempts to configure Exim to use it cause run time configuration
 errors.
@@ -1981,7 +2055,7 @@ chapter <<CHAPperl>>.
 
 cindex:[X11 libraries, location of]
 The location of the X11 libraries is something that varies a lot between
-operating systems, and of course there are different versions of X11 to cope
+operating systems, and there may be different versions of X11 to cope
 with. Exim itself makes no use of X11, but if you are compiling the Exim
 monitor, the X11 libraries must be available.
 The following three variables are set in _OS/Makefile-Default_:
@@ -2063,10 +2137,17 @@ Installing Exim binaries and scripts
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 cindex:[installing Exim]
 cindex:[BIN_DIRECTORY]
-The command 'make install' runs the 'exim_install' script with no
-arguments. The script copies binaries and utility scripts into the directory
-whose name is specified by the BIN_DIRECTORY setting in
-_Local/Makefile_.
+The command 'make install' runs the 'exim_install' script with no arguments.
+The script copies binaries and utility scripts into the directory whose name is
+specified by the BIN_DIRECTORY setting in _Local/Makefile_.
+cindex:[setuid,installing Exim with]
+The install script copies files only if they are newer than the files they are
+going to replace. The Exim binary is required to be owned by root and have the
+'setuid' bit set, for normal configurations. Therefore, you must run 'make
+install' as root so that it can set up the Exim binary in this way. However, in
+some special situations (for example, if a host is doing no local deliveries)
+it may be possible to run Exim without making the binary setuid root (see
+chapter <<CHAPsecurity>> for details).
 
 cindex:[CONFIGURE_FILE]
 Exim's run time configuration file is named by the CONFIGURE_FILE setting
@@ -2098,15 +2179,6 @@ directories are supported, but no NIS or NIS+ support is configured. Domains
 other than the name of the local host are routed using the DNS, with delivery
 over SMTP.
 
-cindex:[setuid,installing Exim with]
-The install script copies files only if they are newer than the files they are
-going to replace. The Exim binary is required to be owned by root and have the
-'setuid' bit set, for normal configurations. Therefore, you must run 'make
-install' as root so that it can set up the Exim binary in this way. However, in
-some special situations (for example, if a host is doing no local deliveries)
-it may be possible to run Exim without making the binary setuid root (see
-chapter <<CHAPsecurity>> for details).
-
 It is possible to install Exim for special purposes (such as building a binary
 distribution) in a private part of the file system. You can do this by a
 command such as
@@ -2224,13 +2296,15 @@ a remote one. Then try getting it to deliver mail, both locally and remotely.
 This can be done by passing messages directly to Exim, without going through a
 user agent. For example:
 
-  exim -v postmaster@your.domain.example
-  From: user@your.domain.example
-  To: postmaster@your.domain.example
-  Subject: Testing Exim
+....
+exim -v postmaster@your.domain.example
+From: user@your.domain.example
+To: postmaster@your.domain.example
+Subject: Testing Exim
 
-  This is a test message.
-  ^D
+This is a test message.
+^D
+....
 
 The %-v% option causes Exim to output some verification of what it is doing.
 In this case you should see copies of three log lines, one for the message's
@@ -2332,7 +2406,9 @@ version automatically makes it available to MUAs, or any other programs that
 call the MTA directly. However, if you are running an Exim daemon, you do need
 to send it a HUP signal, to make it re-exec itself, and thereby pick up the new
 binary. You do not need to stop processing mail in order to install a new
-version of Exim.
+version of Exim. The install script does not modify an existing runtime
+configuration file.
+
 
 
 
@@ -2576,7 +2652,7 @@ function, which provides extensive line-editing facilities, for reading the
 test data. A line history is supported.
 +
 Long expansion expressions can be split over several lines by using backslash
-continuations. As in Exim's run time configuration, whitespace at the start of
+continuations. As in Exim's run time configuration, white space at the start of
 continuation lines is ignored. Each argument or data line is passed through the
 string expansion mechanism, and the result is output. Variable values from the
 configuration file (for example, $qualify_domain$) are available, but no
@@ -2637,6 +2713,7 @@ be set by means of additional command line options (see the next four options).
 
 *-bfd*~<'domain'>::
 oindex:[%-bfd%]
+cindex:[$qualify_domain$]
 This sets the domain of the recipient address when a filter file is being
 tested by means of the %-bf% option. The default is the value of
 $qualify_domain$.
@@ -3217,13 +3294,14 @@ cindex:[debugging,%-d% option]
 This option causes debugging information to be written to the standard
 error stream. It is restricted to admin users because debugging output may show
 database queries that contain password information. Also, the details of users'
-filter files should be protected. When %-d% is used, %-v% is assumed. If
-%-d% is given on its own, a lot of standard debugging data is output. This can
-be reduced, or increased to include some more rarely needed information, by
-following %-d% with a string made up of names preceded by plus or minus
-characters. These add or remove sets of debugging data, respectively. For
+filter files should be protected. When %-d% is used, %-v% is assumed. If %-d%
+is given on its own, a lot of standard debugging data is output. This can be
+reduced, or increased to include some more rarely needed information, by
+directly following %-d% with a string made up of names preceded by plus or
+minus characters. These add or remove sets of debugging data, respectively. For
 example, %-d+filter% adds filter debugging, whereas %-d-all+filter% selects
-only filter debugging. The available debugging categories are:
+only filter debugging. Note that no spaces are allowed in the debug setting.
+The available debugging categories are:
 +
 &&&
 `acl            ` ACL interpretation
@@ -3256,9 +3334,16 @@ only filter debugging. The available debugging categories are:
 `transport      ` transports
 `uid            ` changes of uid/gid and looking up uid/gid
 `verify         ` address verification logic
-`all            ` all of the above, and also %-v%
+`all            ` almost all of the above (see below), and also %-v%
 &&&
 +
+[revisionflag="changed"]
+The `all` option excludes `memory` when used as `+all`, but includes it for
+`-all`. The reason for this is that `+all` is something that people tend to use
+when generating debug output for Exim maintainers. If `+memory` is included, an
+awful lot of output that is very rarely of interest is generated, so it now has
+to be explicitly requested. However, `-all` does turn everything off.
++
 The
 cindex:[resolver, debugging output]
 cindex:[DNS resolver, debugging output]
@@ -3403,6 +3488,12 @@ the normal retry time has not yet been reached. This option requires the caller
 to be an admin user. However, there is an option called %prod_requires_admin%
 which can be set false to relax this restriction (and also the same requirement
 for the %-q%, %-R%, and %-S% options).
++
+[revisionflag="changed"]
+The deliveries happen synchronously, that is, the original Exim process does
+not terminate until all the delivery attempts have finished. No output is
+produced unless there is a serious error. If you want to see what is happening,
+use the %-v% option as well, or inspect Exim's main log.
 
 *-Mar*~<'message~id'>~<'address'>~<'address'>~...::
 oindex:[%-Mar%]
@@ -3663,7 +3754,7 @@ false and one of the queueing options in the configuration file is in effect.
 +
 If there is a temporary delivery error during foreground delivery, the
 message is left on the queue for later delivery, and the original reception
-process exists. See chapter <<CHAPnonqueueing>> for a way of setting up a
+process exits. See chapter <<CHAPnonqueueing>> for a way of setting up a
 restricted configuration that never queues messages.
 
 
@@ -3818,6 +3909,7 @@ $interface_address$ and the port number, if present, in $interface_port$.
 *-oMr*~<'protocol~name'>::
 oindex:[%-oMr%]
 cindex:[protocol,incoming -- specifying for local message]
+cindex:[$received_protocol$]
 See %-oMa% above for general remarks about the %-oM% options. The %-oMr% option
 sets the received protocol value that is stored in $received_protocol$.
 However, this applies only when %-bs% is not used. For interactive SMTP input
@@ -4310,8 +4402,8 @@ delivery using two separate commands (one to put a message on the queue, using
 
 If ALT_CONFIG_PREFIX is defined _in Local/Makefile_, it specifies a
 prefix string with which any file named in a %-C% command line option must
-start. In addition, the file name must not contain the sequence `/../`. There
-is no default setting for ALT_CONFIG_PREFIX; when it is unset, any file
+start. In addition, the file name must not contain the sequence ``##`/../`##''.
+There is no default setting for ALT_CONFIG_PREFIX; when it is unset, any file
 name can be used with %-C%.
 
 One-off changes to a configuration can be specified by the %-D% command line
@@ -4371,10 +4463,10 @@ want to use this feature, you must set
 in _Local/Makefile_ before building Exim. Full details of the
 'local_scan()' facility are given in chapter <<CHAPlocalscan>>.
 
-cindex:[configuration file,leading whitespace in]
-cindex:[configuration file,trailing whitespace in]
-cindex:[whitespace,in configuration file]
-Leading and trailing whitespace in configuration lines is always ignored.
+cindex:[configuration file,leading white space in]
+cindex:[configuration file,trailing white space in]
+cindex:[white space,in configuration file]
+Leading and trailing white space in configuration lines is always ignored.
 
 Blank lines in the file, and lines starting with a # character (ignoring
 leading white space) are treated as comments and are ignored. *Note*: a
@@ -4382,9 +4474,9 @@ leading white space) are treated as comments and are ignored. *Note*: a
 and does not introduce a comment.
 
 Any non-comment line can be continued by ending it with a backslash. Note that
-the general rule for whitespace means that trailing white space after the
-backslash is ignored, and leading white space at the start of continuation
-lines is also ignored. Comment lines beginning with # (but not empty lines) may
+the general rule for white space means that trailing white space after the
+backslash and leading white space at the start of continuation
+lines is ignored. Comment lines beginning with # (but not empty lines) may
 appear in the middle of a sequence of continuation lines.
 
 A convenient way to create a configuration file is to start from the
@@ -4458,9 +4550,17 @@ continuations, is the replacement text, and has leading and trailing white
 space removed. Quotes are not removed. The replacement text can never end with
 a backslash character, but this doesn't seem to be a serious limitation.
 
+[revisionflag="changed"]
+Macros may also be defined between router, transport, authenticator, or ACL
+definitions. They may not, however, be defined within an individual driver or
+ACL, or in the %local_scan%, retry, or rewrite sections of the configuration.
+
+
+Macro substitution
+~~~~~~~~~~~~~~~~~~
 Once a macro is defined, all subsequent lines in the file (and any included
 files) are scanned for the macro name; if there are several macros, the line is
-scanned for each in turn, in the order in which they are defined. The
+scanned for each in turn, in the order in which the macros are defined. The
 replacement text is not re-scanned for the current macro, though it is scanned
 for subsequently defined macros. For this reason, a macro name may not contain
 the name of a previously defined macro as a substring. You could, for example,
@@ -4472,14 +4572,50 @@ define
 &&&
 
 but putting the definitions in the opposite order would provoke a configuration
-error.
+error. Macro expansion is applied to individual physical lines from the file,
+before checking for line continuation or file inclusion (see above). If a line
+consists solely of a macro name, and the expansion of the macro is empty, the
+line is ignored. A macro at the start of a line may turn the line into a
+comment line or a `.include` line.
+
+
+Redefining macros
+~~~~~~~~~~~~~~~~~
+[revisionflag="changed"]
+Once defined, the value of a macro can be redefined later in the configuration
+(or in an included file). Redefinition is specified by using '==' instead of
+'='. For example:
+
+  MAC =  initial value
+  ...
+  MAC == updated value
+
+Redefinition does not alter the order in which the macros are applied to
+the subsequent lines of the configuration file. It is still the same
+order in which the macros were originally defined. All that changes is
+the macro's value. Redefinition makes it possible to accumulate values.
+For example:
+
+  MAC =  initial value
+  ...
+  MAC == MAC and something added
+
+This can be helpful in situations where the configuration file is built
+from a number of other files.
+
+
+Overriding macro values
+~~~~~~~~~~~~~~~~~~~~~~~
+The values set for macros in the configuration file can be overridden by the
+%-D% command line option, but Exim gives up its root privilege when %-D% is
+used, unless called by root or the Exim user. A definition on the command line
+using the %-D% option causes all definitions and redefinitions within the file
+to be ignored.
+
 
-Macro expansion is applied to individual lines from the file, before checking
-for line continuation or file inclusion (see below). If a line consists solely
-of a macro name, and the expansion of the macro is empty, the line is ignored.
-A macro at the start of a line may turn the line into a comment line or a
-`.include` line.
 
+Example of macro usage
+~~~~~~~~~~~~~~~~~~~~~~
 As an example of macro usage, consider a configuration where aliases are looked
 up in a MySQL database. It helps to keep the file less cluttered if long
 strings such as SQL statements are defined separately as macros, for example:
@@ -4497,11 +4633,6 @@ In earlier versions of Exim macros were sometimes used for domain, host, or
 address lists. In Exim 4 these are handled better by named lists -- see section
 <<SECTnamedlists>>.
 
-Macros in the configuration file can be overridden by the %-D% command line
-option, but Exim gives up its root privilege when %-D% is used, unless called
-by root or the Exim user.
-
-
 
 Conditional skips in the configuration file
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -4573,12 +4704,14 @@ Boolean options
 ~~~~~~~~~~~~~~~
 cindex:[format,boolean]
 cindex:[boolean configuration values]
+oindex:[%no_%'xxx']
+oindex:[%not_%'xxx']
 Options whose type is given as boolean are on/off switches. There are two
 different ways of specifying such options: with and without a data value. If
 the option name is specified on its own without data, the switch is turned on;
 if it is preceded by ``no_'' or ``not_'' the switch is turned off. However,
-boolean options may optionally be followed by an equals sign and one of the
-words ``true'', ``false'', ``yes'', or ``no'', as an alternative syntax. For example,
+boolean options may be followed by an equals sign and one of the words
+``true'', ``false'', ``yes'', or ``no'', as an alternative syntax. For example,
 the following two settings have exactly the same effect:
 
   queue_only
@@ -4736,9 +4869,10 @@ cindex:[string list, definition]
 The data for some configuration options is a list of items, with colon as the
 default separator. Many of these options are shown with type ``string list'' in
 the descriptions later in this document. Others are listed as ``domain list'',
-``host list'', ``address list'', or ``local part list''. Syntactically, they are all
-the same; however, those other than ``string list'' are subject to particular
-kinds of interpretation, as described in chapter <<CHAPdomhosaddlists>>.
+``host list'', ``address list'', or ``local part list''. Syntactically, they
+are all the same; however, those other than ``string list'' are subject to
+particular kinds of interpretation, as described in chapter
+<<CHAPdomhosaddlists>>.
 
 In all these cases, the entire list is treated as a single string as far as the
 input syntax is concerned. The %trusted_users% setting in section
@@ -4750,8 +4884,13 @@ example, the list
 
   local_interfaces = 127.0.0.1 : ::::1
 
-+contains two IP addresses, the IPv4 address 127.0.0.1 and the IPv6 address
-1.
+contains two IP addresses, the IPv4 address 127.0.0.1 and the IPv6 address ::1.
+
+[revisionflag="changed"]
+*Note*: Although leading and trailing white space is ignored in individual list
+items, it is not ignored when parsing the list. The space after the first colon
+in the example above is necessary. If it were not there, the list would be
+interpreted as the two items 127.0.0.1:: and 1.
 
 cindex:[list separator, changing]
 cindex:[IPv6,addresses in lists]
@@ -4784,7 +4923,7 @@ items, the second of which is empty:
 
   senders = user1@domain : : user2@domain
 
-*Note*: there must be whitespace between the two colons, as otherwise they
+*Note*: there must be white space between the two colons, as otherwise they
 are interpreted as representing a single colon data character (and the list
 would then contain just one item). If you want to specify a list that contains
 just one, empty item, you can do it as in this example:
@@ -4829,7 +4968,7 @@ you would use the ^appendfile^ driver. Each of the drivers is described in
 detail in its own separate chapter later in this manual.
 
 You can have several routers, transports, or authenticators that are based on
-the same underlying driver (each must have a different name).
+the same underlying driver (each must have a different instance name).
 
 The order in which routers are defined is important, because addresses are
 passed to individual routers one by one, in order. The order in which
@@ -4961,19 +5100,37 @@ Just to be sure there's no misunderstanding: at this point in the configuration
 we aren't actually setting up any controls. We are just defining some domains
 and hosts that will be used in the controls that are specified later.
 
-The next configuration line is a genuine option setting:
+The next two configuration lines are genuine option settings:
 
   acl_smtp_rcpt = acl_check_rcpt
+  acl_smtp_data = acl_check_data
 
-This option specifies an 'Access Control List' (ACL) which is to be used
-during an incoming SMTP session for every recipient of a message (every
-RCPT command). The name of the list is 'acl_check_rcpt', and we will
-come to its definition below, in the ACL section of the configuration. ACLs
-control which recipients are accepted for an incoming message -- if a
+[revisionflag="changed"]
+These options specify 'Access Control Lists' (ACLs) that are to be used during
+an incoming SMTP session for every recipient of a message (every RCPT command),
+and after the contents of the message have been received, respectively. The
+names of the lists are 'acl_check_rcpt' and 'acl_check_data', and we will come
+to their definitions below, in the ACL section of the configuration. The RCPT
+ACL controls which recipients are accepted for an incoming message -- if a
 configuration does not provide an ACL to check recipients, no SMTP mail can be
-accepted.
+accepted. The DATA ACL allows the contents of a message to be checked.
+
+[revisionflag="changed"]
+Two commented-out option settings are next:
+
+[revisionflag="changed"]
+....
+# av_scanner = clamd:/tmp/clamd
+# spamd_address = 127.0.0.1 783
+....
+
+[revisionflag="changed"]
+These are example settings that can be used when Exim is compiled with the
+content-scanning extension. The first specifies the interface to the virus
+scanner, and the second specifies the interface to SpamAssassin. Further
+details are given in chapter <<CHAPexiscan>>.
 
-Two commented-out options settings are next:
+Two more commented-out options settings follow:
 
   # qualify_domain =
   # qualify_recipient =
@@ -4988,7 +5145,7 @@ you set only the first one, its value is used in both cases.
 cindex:[domain literal,recognizing format]
 The following line must be uncommented if you want Exim to recognize
 addresses of the form 'user@[10.11.12.13]' that is, with a ``domain literal''
-(an IP address) instead of a named domain.
+(an IP address within square brackets) instead of a named domain.
 
   # allow_domain_literals
 
@@ -5088,11 +5245,12 @@ It starts with the line
 
   begin acl
 
-and it contains the definition of one ACL called 'acl_check_rcpt' that was
-referenced in the setting of %acl_smtp_rcpt% above.
+and it contains the definitions of two ACLs, called 'acl_check_rcpt' and
+'acl_check_data', that were referenced in the settings of %acl_smtp_rcpt% and
+%acl_smtp_data% above.
 
 cindex:[RCPT,ACL for]
-This ACL is used for every RCPT command in an incoming SMTP message. Each
+The first ACL is used for every RCPT command in an incoming SMTP message. Each
 RCPT command specifies one of the message's recipients. The ACL statements
 are considered in order, until the recipient address is either accepted or
 rejected. The RCPT command is then accepted or rejected, according to the
@@ -5108,19 +5266,21 @@ ACL, and names it.
 This ACL statement accepts the recipient if the sending host matches the list.
 But what does that strange list mean? It doesn't actually contain any host
 names or IP addresses. The presence of the colon puts an empty item in the
-list; Exim matches this only if the incoming message didn't come from a remote
-host. The colon is important. Without it, the list itself is empty, and can
-never match anything.
+list; Exim matches this only if the incoming message did not come from a remote
+host, because in that case, the remote hostname is empty. The colon is
+important. Without it, the list itself is empty, and can never match anything.
 
 What this statement is doing is to accept unconditionally all recipients in
 messages that are submitted by SMTP from local processes using the standard
 input and output (that is, not using TCP/IP). A number of MUAs operate in this
 manner.
 
-  deny    domains       = +local_domains
+  deny    message       = Restricted characters in address
+          domains       = +local_domains
           local_parts   = ^[.] : ^.*[@%!/|]
 
-  deny    domains       = !+local_domains
+  deny    message       = Restricted characters in address
+          domains       = !+local_domains
           local_parts   = ^[./|] : ^.*[@%!] : ^.*/\\.\\./
 
 These statements are concerned with local parts that contain any of the
@@ -5185,12 +5345,35 @@ in cases where the subsequent tests are incorrectly denying access.
 This statement requires the sender address to be verified before any subsequent
 ACL statement can be used. If verification fails, the incoming recipient
 address is refused. Verification consists of trying to route the address, to
-see if a
-bounce
-message could be delivered to it. In the case of remote addresses, basic
-verification checks only the domain, but 'callouts' can be used for more
-verification if required. Section <<SECTaddressverification>> discusses the
-details of address verification.
+see if a bounce message could be delivered to it. In the case of remote
+addresses, basic verification checks only the domain, but 'callouts' can be
+used for more verification if required. Section <<SECTaddressverification>>
+discusses the details of address verification.
+
+  accept  hosts         = +relay_from_hosts
+          control       = submission
+
+[revisionflag="changed"]
+This statement accepts the address if the message is coming from one of the
+hosts that are defined as being allowed to relay through this host. Recipient
+verification is omitted here, because in many cases the clients are dumb MUAs
+that do not cope well with SMTP error responses. For the same reason, the
+second line specifies ``submission mode'' for messages that are accepted. This
+is described in detail in section <<SECTsubmodnon>>; it causes Exim to fix
+messages that are deficient in some way, for example, because they lack a
+'Date:' header line. If you are actually relaying out from MTAs, you should
+probably add recipient verification here, and disable submission mode.
+
+  accept  authenticated = *
+          control       = submission
+
+[revisionflag="changed"]
+This statement accepts the address if the client host has authenticated itself.
+Submission mode is again specified, on the grounds that such messages are most
+likely to come from MUAs. The default configuration does not define any
+authenticators, which means that no client can in fact authenticate. You will
+need to add authenticator definitions if you want to make use of this ACL
+statement.
 
 ....
 # deny    message       = rejected because $sender_host_address is \
@@ -5211,7 +5394,6 @@ line.
 
   accept  domains       = +local_domains
           endpass
-          message       = unknown user
           verify        = recipient
 
 This statement accepts the incoming recipient address if its domain is one of
@@ -5223,43 +5405,61 @@ ACL statement. However, if the condition below %endpass% fails, that is, if a
 recipient in a local domain cannot be verified, access is denied and the
 recipient is rejected.
 
-cindex:[customizing,ACL failure message]
-The %message% modifier provides a customized error message for the failure.
-
   accept  domains       = +relay_to_domains
           endpass
-          message       = unrouteable address
           verify        = recipient
 
 This statement accepts the incoming recipient address if its domain is one of
 the domains for which this host is a relay, but again, only if the address can
 be verified.
 
-  accept  hosts         = +relay_from_hosts
-
-Control reaches this statement only if the recipient's domain is neither a
-local domain, nor a relay domain. The statement accepts the address if the
-message is coming from one of the hosts that are defined as being allowed to
-relay through this host. Recipient verification is omitted here, because in
-many cases the clients are dumb MUAs that do not cope well with SMTP error
-responses. If you are actually relaying out from MTAs, you should probably add
-recipient verification here.
-
-  accept  authenticated = *
-
-Control reaches here for attempts to relay to arbitrary domains from arbitrary
-hosts. The statement accepts the address only if the client host has
-authenticated itself. The default configuration does not define any
-authenticators, which means that no client can in fact authenticate. You will
-need to add authenticator definitions if you want to make use of this ACL
-statement.
-
   deny    message       = relay not permitted
 
 The final statement denies access, giving a specific error message. Reaching
 the end of the ACL also causes access to be denied, but with the generic
 message ``administrative prohibition''.
 
+  acl_check_data:
+
+[revisionflag="changed"]
+This line marks the start of the second ACL, and names it. Most of the contents
+of this ACL are commented out:
+
+[revisionflag="changed"]
+....
+# deny    malware   = *
+#         message   = This message contains a virus \
+#                     ($malware_name).
+....
+
+[revisionflag="changed"]
+These lines are examples of how to arrange for messages to be scanned for
+viruses when Exim has been compiled with the content-scanning extension, and a
+suitable virus scanner is installed. If the message is found to contain a
+virus, it is rejected with the given custom error message.
+
+[revisionflag="changed"]
+....
+# warn    spam      = nobody
+#         message   = X-Spam_score: $spam_score\n\
+#                     X-Spam_score_int: $spam_score_int\n\
+#                     X-Spam_bar: $spam_bar\n\
+#                     X-Spam_report: $spam_report
+....
+
+[revisionflag="changed"]
+These lines are an example of how to arrange for messages to be scanned by
+SpamAssassin when Exim has been compiled with the content-scanning extension,
+and SpamAssassin has been installed. The SpamAssassin check is run with
+`nobody` as its user parameter, and the results are added to the message as a
+series of extra header line. In this case, the message is not rejected,
+whatever the spam score.
+
+  accept
+
+[revisionflag="changed"]
+This final line in the DATA ACL accepts the message unconditionally.
+
 
 
 Router configuration
@@ -5353,24 +5553,44 @@ _Local/Makefile_ before building Exim.
   userforward:
     driver = redirect
     check_local_user
+  # local_part_suffix = +* : -*
+  # local_part_suffix_optional
     file = $home/.forward
+  # allow_filter
     no_verify
     no_expn
     check_ancestor
-  # allow_filter
     file_transport = address_file
     pipe_transport = address_pipe
     reply_transport = address_reply
 
+[revisionflag="changed"]
 This is the most complicated router in the default configuration. It is another
 redirection router, but this time it is looking for forwarding data set up by
-individual users. The %check_local_user% setting means that the first thing it
-does is to check that the local part of the address is the login name of a
-local user. If it is not, the router is skipped. When a local user is found,
-the file called _.forward_ in the user's home directory is consulted. If it
-does not exist, or is empty, the router declines. Otherwise, the contents of
-_.forward_ are interpreted as redirection data (see chapter <<CHAPredirect>>
-for more details).
+individual users. The %check_local_user% setting specifies a check that the
+local part of the address is the login name of a local user. If it is not, the
+router is skipped. The two commented options that follow %check_local_user%,
+namely:
+
+[revisionflag="changed"]
+....
+# local_part_suffix = +* : -*
+# local_part_suffix_optional
+....
+
+[revisionflag="changed"]
+cindex:[$local_part_suffix$]
+show how you can specify the recognition of local part suffixes. If the first
+is uncommented, a suffix beginning with either a plus or a minus sign, followed
+by any sequence of characters, is removed from the local part and placed in the
+variable $local_part_suffix$. The second suffix option specifies that the
+presence of a suffix in the local part is optional. When a suffix is present,
+the check for a local login uses the local part with the suffix removed.
+
+When a local user account is found, the file called _.forward_ in the user's
+home directory is consulted. If it does not exist, or is empty, the router
+declines. Otherwise, the contents of _.forward_ are interpreted as redirection
+data (see chapter <<CHAPredirect>> for more details).
 
 cindex:[Sieve filter,enabling in default router]
 Traditional _.forward_ files contain just a list of addresses, pipes, or
@@ -5381,8 +5601,7 @@ filter'' or ``#Sieve filter'', respectively. User filtering is discussed in the
 separate document entitled 'Exim's interfaces to mail filtering'.
 
 The %no_verify% and %no_expn% options mean that this router is skipped when
-verifying addresses, or when running as a consequence of an SMTP EXPN
-command.
+verifying addresses, or when running as a consequence of an SMTP EXPN command.
 There are two reasons for doing this:
 
 . Whether or not a local user has a _.forward_ file is not really relevant when
@@ -5395,7 +5614,6 @@ The group is the Exim group, and no additional groups are set up.
 It may therefore not be possible for Exim to read users' _.forward_ files at
 this time.
 
-
 The setting of %check_ancestor% prevents the router from generating a new
 address that is the same as any previous address that was redirected. (This
 works round a problem concerning a bad interaction between aliasing and
@@ -5413,12 +5631,16 @@ transport.
   localuser:
     driver = accept
     check_local_user
+  # local_part_suffix = +* : -*
+  # local_part_suffix_optional
     transport = local_delivery
 
+[revisionflag="changed"]
 The final router sets up delivery into local mailboxes, provided that the local
-part is the name of a local login, by accepting the address and queuing it for
+part is the name of a local login, by accepting the address and assigning it to
 the ^local_delivery^ transport. Otherwise, we have reached the end of the
-routers, so the address is bounced.
+routers, so the address is bounced. The commented suffix settings fulfil the
+same purpose as they do for the ^userforward^ router.
 
 
 
@@ -5552,14 +5774,11 @@ O'Reilly (*http://www.oreilly.com/catalog/regex/[]*).
 
 The documentation for the syntax and semantics of the regular expressions that
 are supported by PCRE is included in plain text in the file
-_doc/pcrepattern.txt_ in the Exim distribution, and also in the HTML
-tarbundle of Exim documentation, and as an appendix to the Exim book
-(*http://www.uit.co.uk/exim-book/[]*).
-
-It describes in detail the features of the regular expressions that PCRE
-supports, so no further description is included here. The PCRE functions are
-called from Exim using the default option settings (that is, with no PCRE
-options set), except that the PCRE_CASELESS option is set when the
+_doc/pcrepattern.txt_ in the Exim distribution, and also in the HTML tarbundle
+of Exim documentation. It describes in detail the features of the regular
+expressions that PCRE supports, so no further description is included here. The
+PCRE functions are called from Exim using the default option settings (that is,
+with no PCRE options set), except that the PCRE_CASELESS option is set when the
 matching is required to be case-insensitive.
 
 In most cases, when a regular expression is required in an Exim configuration,
@@ -5594,8 +5813,8 @@ You need to use:
 
   domains = ^\\d{3}\\.example\$
 
-if you want 'example' to be the top-level domain. (The backslash before the
-\$ is another artefact of string expansion.)
+if you want 'example' to be the top-level domain. The backslash before the
+\$ is needed because string expansion also interprets dollar characters.
 
 
 
@@ -5657,7 +5876,7 @@ messages. Two different kinds of syntax are used:
 
 . A string that is to be expanded may contain explicit lookup requests. These
 cause parts of the string to be replaced by data that is obtained from the
-lookup.
+lookup. String expansions are described in detail in chapter <<CHAPexpand>>.
 
 . Lists of domains, hosts, and email addresses can contain lookup requests as a
 way of avoiding excessively long linear lists. In this case, the data that is
@@ -5665,6 +5884,17 @@ returned by the lookup is often (but not always) discarded; whether the lookup
 succeeds or fails is what really counts. These kinds of list are described in
 chapter <<CHAPdomhosaddlists>>.
 
+[revisionflag="changed"]
+String expansions, lists, and lookups interact with each other in such a way
+that there is no order in which to describe any one of them that does not
+involve references to the others. Each of these three chapters makes more sense
+if you have read the other two first. If you are reading this for the first
+time, be aware that some of it will make a lot more sense after you have read
+chapters <<CHAPdomhosaddlists>> and <<CHAPexpand>>.
+
+
+Examples of different lookup syntax
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 It is easy to confuse the two different kinds of lookup, especially as the
 lists that may contain the second kind are always expanded before being
 processed as lists. Therefore, they may also contain lookups of the first kind.
@@ -5674,17 +5904,16 @@ Be careful to distinguish between the following two examples:
   domains = lsearch;/some/file
 
 The first uses a string expansion, the result of which must be a domain list.
-String expansions are described in detail in chapter <<CHAPexpand>>. The
-expansion takes place first, and the file that is searched could contain lines
-like this:
+The expansion takes place before the string is processed as a list, and the
+file that is searched could contain lines like this:
 
-  192.168.3.4: domain1 : domain2 : ...
-  192.168.1.9: domain3 : domain4 : ...
+  192.168.3.4: domain1:domain2:...
+  192.168.1.9: domain3:domain4:...
 
-Thus, the result of the expansion is a list of domains (and possibly other
-types of item that are allowed in domain lists).
+The result of the expansion (assuming the lookup succeeds) is a list of domains
+(and possibly other types of item that are allowed in domain lists).
 
-In the second case, the lookup is a single item in a domain list. It causes
+In the second example, the lookup is a single item in a domain list. It causes
 Exim to use a lookup to see if the domain that is being processed can be found
 in the file. The file could contains lines like this:
 
@@ -5694,8 +5923,8 @@ in the file. The file could contains lines like this:
 Any data that follows the keys is not relevant when checking that the domain
 matches the list item.
 
-It is possible to use both kinds of lookup at once. Consider a file containing
-lines like this:
+It is possible, though no doubt confusing, to use both kinds of lookup at once.
+Consider a file containing lines like this:
 
   192.168.5.6: lsearch;/another/file
 
@@ -5704,25 +5933,24 @@ first %domains% setting above generates the second setting, which therefore
 causes a second lookup to occur.
 
 The rest of this chapter describes the different lookup types that are
-available. Any of them can be used in either of the circumstances described
-above. The syntax requirements for the two cases are described in chapters
-<<CHAPexpand>> and <<CHAPdomhosaddlists>>, respectively.
+available. Any of them can be used in any part of the configuration where a
+lookup is permitted.
 
 
 Lookup types
 ~~~~~~~~~~~~
 cindex:[lookup,types of]
 cindex:[single-key lookup,definition of]
-Two different styles of data lookup are implemented:
+Two different types of data lookup are implemented:
 
-- The 'single-key' style requires the specification of a file in which to look,
+- The 'single-key' type requires the specification of a file in which to look,
 and a single key to search for. The key must be a non-empty string for the
 lookup to succeed. The lookup type determines how the file is searched.
 
 - cindex:[query-style lookup,definition of]
-The 'query' style accepts a generalized database query.
-No particular key value is assumed by Exim for query-style lookups. You can
-use whichever Exim variable(s) you need to construct the database query.
+The 'query-style' type accepts a generalized database query. No particular key
+value is assumed by Exim for query-style lookups. You can use whichever Exim
+variables you need to construct the database query.
 
 The code for each lookup type is in a separate source file that is included in
 the binary of Exim only if the corresponding compile-time option is set. The
@@ -5853,9 +6081,9 @@ that the keys in an ^lsearch^ file are literal strings. There is no
 wildcarding of any kind.
 +
 cindex:[lookup,lsearch -- colons in keys]
-cindex:[whitespace,in lsearch key]
+cindex:[white space,in lsearch key]
 In most ^lsearch^ files, keys are not required to contain colons or #
-characters, or whitespace. However, if you need this feature, it is available.
+characters, or white space. However, if you need this feature, it is available.
 If a key begins with a doublequote character, it is terminated only by a
 matching quote (or end of line), and the normal escaping rules apply to its
 contents (see section <<SECTstrings>>). An optional colon is permitted after
@@ -5887,19 +6115,19 @@ of wildcard are recognized:
 --
 .. The string may begin with an asterisk to mean ``ends with''. For example:
 
-  *.a.b.c       data for anything.a.b.c
-  *fish         data for anythingfish
+      *.a.b.c       data for anything.a.b.c
+      *fish         data for anythingfish
 
 .. The string may begin with a circumflex to indicate a regular expression. For
 example, for ^wildlsearch^:
 
-  ^\N\d+\.a\.b\N    data for <digits>.a.b
+      ^\N\d+\.a\.b\N    data for <digits>.a.b
 
 Note the use of `\N` to disable expansion of the contents of the regular
 expression. If you are using ^nwildlsearch^, where the keys are not
 string-expanded, the equivalent entry is:
 
-  ^\d+\.a\.b        data for <digits>.a.b
+      ^\d+\.a\.b        data for <digits>.a.b
 
 If the regular expression contains white space or colon characters, you must
 either quote it (see ^lsearch^ above), or represent these characters in other
@@ -5912,7 +6140,7 @@ that is used to implement ^(n)wildlsearch^ means that the string may begin with
 a lookup name terminated by a semicolon, and followed by lookup data. For
 example:
 
-  cdb;/some/file  data for keys that match the file
+      cdb;/some/file  data for keys that match the file
 
 The data that is obtained from the nested lookup is discarded.
 --
@@ -5983,6 +6211,12 @@ cindex:[lookup,PostgreSQL]
 ^pgsql^: The format of the query is an SQL statement that is passed to a
 PostgreSQL database. See section <<SECTsql>>.
 
+[revisionflag="changed"]
+- cindex:[sqlite lookup type]
+cindex:[lookup,sqlite]
+^sqlite^: The format of the query is a file name followed by an SQL statement
+that is passed to an SQLite database. See section <<SECTsqlite>>.
+
 - ^testdb^: This is a lookup type that is used for testing Exim. It is
 not likely to be useful in normal operation.
 
@@ -6009,7 +6243,7 @@ Temporary errors in lookups
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~
 cindex:[lookup,temporary error in]
 Lookup functions can return temporary error codes if the lookup cannot be
-completed. For example, a NIS or LDAP database might be unavailable. For this
+completed. For example, an SQL or LDAP database might be unavailable. For this
 reason, it is not advisable to use a lookup that might do this for critical
 options such as a list of local domains.
 
@@ -6249,6 +6483,12 @@ the data can be an IP address, written as normal; inversion and the addition of
 If the data for a PTR record is not a syntactically valid IP address, it is not
 altered and nothing is added.
 
+cindex:[MX record,in ^dnsdb^ lookup]
+cindex:[SRV record,in ^dnsdb^ lookup]
+For an MX lookup, both the preference value and the host name are returned for
+each record, separated by a space. For an SRV lookup, the priority, weight,
+port, and host name are returned for each record, separated by spaces.
+
 For any record type, if multiple records are found (or, for A6 lookups, if a
 single record leads to multiple addresses), the data is returned as a
 concatenation, with newline as the default separator. The order, of course,
@@ -6259,20 +6499,19 @@ by the new separator at the start of the query. For example:
   ${lookup dnsdb{>: a=host1.example}}
 
 It is permitted to specify a space as the separator character. Further
-whitespace is ignored.
-
-cindex:[SRV record,in ^dnsdb^ lookup]
-For SRV records, the priority, weight, port, and host name are returned for
-each record, separated by spaces.
+white space is ignored.
 
+Pseudo dnsdb record types
+~~~~~~~~~~~~~~~~~~~~~~~~~
 cindex:[MX record,in ^dnsdb^ lookup]
-For MX records, both the preference value and the host name are returned for
-each record, separated by a space. However, if you want only host names, you
-can use the pseudo-type MXH:
+By default, both the preference value and the host name are returned for
+each MX record, separated by a space. If you want only host names, you can use
+the pseudo-type MXH:
 
   ${lookup dnsdb{mxh=a.b.example}}
 
-In this case, the preference values are omitted.
+In this case, the preference values are omitted, and just the host names are
+returned.
 
 cindex:[name server,for enclosing domain]
 Another pseudo-type is ZNS (for ``zone NS''). It performs a lookup for NS
@@ -6297,11 +6536,29 @@ given domain are on a blacklist. You can probably assume that the name servers
 for the high-level domains such as %com% or %co.uk% are not going to be on such
 a list.
 
+[revisionflag="changed"]
+cindex:[CSA,in ^dnsdb^ lookup]
+A third pseudo-type is CSA (Client SMTP Authorization), which looks up SRV
+records according to the CSA rules, which are described in section
+<<SECTverifyCSA>>. Although ^dnsdb^ supports SRV lookups directly, this is not
+sufficient because of the extra parent domain search behaviour of CSA. The
+result of a successful lookup such as:
+
+[revisionflag="changed"]
+....
+${lookup dnsdb {csa=$sender_helo_name}}
+....
+
+[revisionflag="changed"]
+has two space-separated fields: an authorization code and a target host name.
+The authorization code can be ``Y'' for yes, ``N'' for no, ``X'' for explicit
+authorization required but absent, or ``?'' for unknown.
+
 
 
 Multiple dnsdb lookups
 ~~~~~~~~~~~~~~~~~~~~~~
-In the previous section, ^dnsdb^ lookups for a single domain are described.
+In the previous sections, ^dnsdb^ lookups for a single domain are described.
 However, you can specify a list of domains or IP addresses in a single
 ^dnsdb^ lookup. The list is specified in the normal Exim way, with colon as
 the default separator, but with the ability to change this. For example:
@@ -6705,6 +6962,41 @@ operator is to double any quote characters within the text.
 
 
 [[SECTsql]]
+SQL lookups
+~~~~~~~~~~~
+[revisionflag="changed"]
+cindex:[SQL lookup types]
+Exim can support lookups in Interbase, MySQL, Oracle, PostgreSQL, and SQLite
+databases. Queries for these databases contain SQL statements, so an example
+might be
+
+....
+${lookup mysql{select mailbox from users where id='userx'}\
+  {$value}fail}
+....
+
+If the result of the query contains more than one field, the data for each
+field in the row is returned, preceded by its name, so the result of
+
+....
+${lookup pgsql{select home,name from users where id='userx'}\
+  {$value}}
+....
+
+might be
+
+  home=/home/userx name="Mister X"
+
+Empty values and values containing spaces are double quoted, with embedded
+quotes escaped by a backslash. If the result of the query contains just one
+field, the value is passed back verbatim, without a field name, for example:
+
+  Mister X
+
+If the result of the query yields more than one row, it is all concatenated,
+with a newline between the data for each row.
+
+
 More about MySQL, PostgreSQL, Oracle, and Interbase
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 cindex:[MySQL,lookup type]
@@ -6716,14 +7008,14 @@ cindex:[lookup,Oracle]
 cindex:[Interbase lookup type]
 cindex:[lookup,Interbase]
 If any MySQL, PostgreSQL, Oracle, or Interbase lookups are used, the
-%mysql_servers%, %pgsql_servers%, %oracle_servers%, or %ibase_servers%
-option (as appropriate) must be set to a colon-separated list of server
-information. Each item in the list is a slash-separated list of four items:
-host name, database name, user name, and password. In the case of Oracle, the
-host name field is used for the ``service name'', and the database name field is
-not used and should be empty. For example:
+%mysql_servers%, %pgsql_servers%, %oracle_servers%, or %ibase_servers% option
+(as appropriate) must be set to a colon-separated list of server information.
+Each item in the list is a slash-separated list of four items: host name,
+database name, user name, and password. In the case of Oracle, the host name
+field is used for the ``service name'', and the database name field is not used
+and should be empty. For example:
 
-  hide oracle_servers = oracle.plc.example//ph10/abcdwxyz
+  hide oracle_servers = oracle.plc.example//userx/abcdwxyz
 
 Because password data is sensitive, you should always precede the setting with
 ``hide'', to prevent non-admin users from obtaining the setting via the %-bP%
@@ -6735,40 +7027,9 @@ hide mysql_servers = localhost/users/root/secret:\
 ....
 
 For MySQL and PostgreSQL, a host may be specified as <'name'>:<'port'> but
-because this is a colon-separated list, the colon has to be doubled.
-
-For each query, these parameter groups are tried in order until a connection
-and a query succeeds. Queries for these databases are SQL statements, so an
-example might be
-
-....
-${lookup mysql{select mailbox from users where id='ph10'}\
-  {$value}fail}
-....
-
-If the result of the query contains more than one field, the data for
-each field in the row is returned, preceded by its name, so the result
-of
-
-....
-${lookup pgsql{select home,name from users where id='ph10'}\
-  {$value}}
-....
-
-might be
-
-  home=/home/ph10 name="Philip Hazel"
-
-Values containing spaces and empty values are double quoted, with embedded
-quotes escaped by a backslash.
-
-If the result of the query contains just one field, the value is passed back
-verbatim, without a field name, for example:
-
-  Philip Hazel
-
-If the result of the query yields more than one row, it is all concatenated,
-with a newline between the data for each row.
+because this is a colon-separated list, the colon has to be doubled. For each
+query, these parameter groups are tried in order until a connection and a query
+succeeds.
 
 The %quote_mysql%, %quote_pgsql%, and %quote_oracle% expansion operators
 convert newline, tab, carriage return, and backspace to \n, \t, \r, and \b
@@ -6779,7 +7040,6 @@ for MySQL because these escapes are not recognized in contexts where these
 characters are not special.
 
 
-
 Special MySQL features
 ~~~~~~~~~~~~~~~~~~~~~~
 For MySQL, an empty host name or the use of ``localhost'' in %mysql_servers%
@@ -6805,8 +7065,6 @@ anything (for example, setting a field to the value it already has), the result
 is zero because no rows are affected.
 
 
-
-
 Special PostgreSQL features
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~
 PostgreSQL lookups can also use Unix domain socket connections to the database.
@@ -6825,6 +7083,44 @@ If a PostgreSQL query is issued that does not request any data (an insert,
 update, or delete command), the result of the lookup is the number of rows
 affected.
 
+[[SECTsqlite]]
+More about SQLite
+~~~~~~~~~~~~~~~~~
+[revisionflag="changed"]
+cindex:[lookup,SQLite]
+cindex:[SQLite lookup type]
+SQLite is different to the other SQL lookups because a file name is required in
+addition to the SQL query. An SQLite database is a single file, and there is no
+daemon as in the other SQL databases. The interface to Exim requires the name
+of the file, as an absolute path, to be given at the start of the query. It is
+separated from the query by white space. This means that the path name cannot
+contain white space. Here is a lookup expansion example:
+
+....
+${lookup sqlite {/some/thing/sqlitedb \
+  select name from aliases where id='userx';}}
+....
+
+[revisionflag="changed"]
+In a list, the syntax is similar. For example:
+
+....
+domainlist relay_domains = sqlite;/some/thing/sqlitedb \
+   select * from relays where ip='$sender_host_address';
+....
+
+[revisionflag="changed"]
+The only character affected by the %quote_sqlite% operator is a single
+quote, which it doubles.
+
+[revisionflag="changed"]
+The SQLite library handles multiple simultaneous accesses to the database
+internally. Multiple readers are permitted, but only one process can
+update at once. Attempts to access the database while it is being updated
+are rejected after a timeout period, during which the SQLite library
+waits for the lock to be released. In Exim, the default timeout is set
+to 5 seconds, but it can be changed by means of the %sqlite_lock_timeout%
+option.
 
 
 
@@ -6839,7 +7135,8 @@ cindex:[list of domains; hosts; etc.]
 A number of Exim configuration options contain lists of domains, hosts,
 email addresses, or local parts. For example, the %hold_domains% option
 contains a list of domains whose delivery is currently suspended. These lists
-are also used as data in ACL statements (see chapter <<CHAPACL>>).
+are also used as data in ACL statements (see chapter <<CHAPACL>>), and as
+arguments to expansion conditions such as %match_domain%.
 
 Each item in one of these lists is a pattern to be matched against a domain,
 host, email address, or local part, respectively. In the sections below, the
@@ -6856,7 +7153,7 @@ expansion must be a list, possibly containing empty items, which is split up
 into separate items for matching. By default, colon is the separator character,
 but this can be varied if necessary. See sections <<SECTlistconstruct>> and
 <<SECTempitelis>> for details of the list syntax; the second of these discusses
-the way you specify empty list items.
+the way to specify empty list items.
 
 
 If the string expansion is forced to fail, Exim behaves as if the item it is
@@ -7935,7 +8232,7 @@ them are expanded every time they are used; others are expanded only once.
 
 When a string is being expanded it is copied verbatim from left to right except
 when a dollar or backslash character is encountered. A dollar specifies the
-start of a portion of the string which is interpreted and replaced as described
+start of a portion of the string that is interpreted and replaced as described
 below in section <<SECTexpansionitems>> onwards. Backslash is used as an escape
 character, as described in the following section.
 
@@ -7947,8 +8244,8 @@ Literal text in expanded strings
 cindex:[expansion,including literal text]
 An uninterpreted dollar can be included in an expanded string by putting a
 backslash in front of it. A backslash can be used to prevent any special
-character being treated specially in an expansion, including itself. If the
-string appears in quotes in the configuration file, two backslashes are
+character being treated specially in an expansion, including backslash itself.
+If the string appears in quotes in the configuration file, two backslashes are
 required because the quotes themselves cause interpretation of backslashes when
 the string is read in (see section <<SECTstrings>>).
 
@@ -8004,15 +8301,16 @@ Forced expansion failure
 ~~~~~~~~~~~~~~~~~~~~~~~~
 cindex:[expansion,forced failure]
 A number of expansions that are described in the following section have
-alternative ``true'' and ``false'' substrings, enclosed in curly brackets. Which
-one is used depends on some condition that is evaluated as part of the
-expansion. If, instead of a ``false'' substring, the word ``fail'' is used (not in
-curly brackets), the entire string expansion fails in a way that can be
-detected by the code that requested the expansion. This is called ``forced
-expansion failure'', and its consequences depend on the circumstances. In some
-cases it is no different from any other expansion failure, but in others a
-different action may be taken. Such variations are mentioned in the
-documentation of the option that is being expanded.
+alternative ``true'' and ``false'' substrings, enclosed in brace characters
+(which are sometimes called ``curly brackets''). Which of the two strings is
+used depends on some condition that is evaluated as part of the expansion. If,
+instead of a ``false'' substring, the word ``fail'' is used (not in braces),
+the entire string expansion fails in a way that can be detected by the code
+that requested the expansion. This is called ``forced expansion failure'', and
+its consequences depend on the circumstances. In some cases it is no different
+from any other expansion failure, but in others a different action may be
+taken. Such variations are mentioned in the documentation of the option that is
+being expanded.
 
 
 
@@ -8033,10 +8331,10 @@ Substitute the contents of the named variable, for example
   ${domain}
 +
 The second form can be used to separate the name from subsequent alphanumeric
-characters. This form (using curly brackets) is available only for variables;
-it does 'not' apply to message headers. The names of the variables are given
-in section <<SECTexpvar>> below. If the name of a non-existent variable is given,
-the expansion fails.
+characters. This form (using braces) is available only for variables; it does
+'not' apply to message headers. The names of the variables are given in section
+<<SECTexpvar>> below. If the name of a non-existent variable is given, the
+expansion fails.
 
 *\$\{*<'op'>*:*<'string'>*\}*::
 cindex:[expansion,operators]
@@ -8051,23 +8349,77 @@ below. The operator notation is used for simple expansion items that have just
 one argument, because it reduces the number of braces and therefore makes the
 string easier to understand.
 
-*\$\{extract\{*<'key'>*\}\{*<'string1'>*\}\{*<'string2'>*\}\{*<'string3'>*\}\}*::
-cindex:[expansion,extracting substrings by key]
-The key and <'string1'> are first expanded separately. Leading and trailing
-whitespace is removed from the key (but not from any of the strings). The key
-must not consist entirely of digits. The expanded <'string1'> must be of the
-form:
-
-  <key1> = <value1>  <key2> = <value2> ...
+*\$\{dlfunc\{*<'file'>*\}\{*<'function'>*\}\{*<'arg'>*\}\{*<'arg'>*\}...\}*::
 +
-where the equals signs and spaces (but not both) are optional. If any of the
-values contain white space, they must be enclosed in double quotes, and any
-values that are enclosed in double quotes are subject to escape processing as
-described in section <<SECTstrings>>. The expanded <'string1'> is searched for
-the value that corresponds to the key. The search is case-insensitive. If the
-key is found, <'string2'> is expanded, and replaces the whole item; otherwise
-<'string3'> is used. During the expansion of <'string2'> the variable $value$
-contains the value that has been extracted. Afterwards, it is restored to any
+[revisionflag="changed"]
+This expansion dynamically loads and then calls a locally-written C function.
+This functionality is available only if Exim is compiled with
++
+[revisionflag="changed"]
+....
+  EXPAND_DLFUNC=yes
+....
++
+[revisionflag="changed"]
+set in _Local/Makefile_. Once loaded, Exim remembers the dynamically loaded
+object so that it doesn't reload the same object file in the same Exim process
+(but of course Exim does start new processes frequently).
++
+[revisionflag="changed"]
+There may be from zero to eight arguments to the function. When compiling
+a local function that is to be called in this way, _local_scan.h_ should be
+included. The Exim variables and functions that are defined by that API
+are also available for dynamically loaded functions. The function itself
+must have the following type:
++
+[revisionflag="changed"]
+....
+int dlfunction(uschar **yield, int argc, uschar *argv[])
+....
++
+[revisionflag="changed"]
+Where `uschar` is a typedef for `unsigned char` in _local_scan.h_. The
+function should return one of the following values:
++
+[revisionflag="changed"]
+`OK`: Success. The string that is placed in the variable 'yield' is put into
+the expanded string that is being built.
++
+[revisionflag="changed"]
+`FAIL`: A non-forced expansion failure occurs, with the error message taken
+from 'yield', if it is set.
++
+[revisionflag="changed"]
+`FAIL_FORCED`: A forced expansion failure occurs, with the error message
+taken from 'yield' if it is set.
++
+[revisionflag="changed"]
+`ERROR`: Same as `FAIL`, except that a panic log entry is written.
++
+[revisionflag="changed"]
+When compiling a function that is to be used in this way with gcc,
+you need to add %-shared% to the gcc command. Also, in the Exim build-time
+configuration, you must add %-export-dynamic% to EXTRALIBS.
+
+
+*\$\{extract\{*<'key'>*\}\{*<'string1'>*\}\{*<'string2'>*\}\{*<'string3'>*\}\}*::
+cindex:[expansion,extracting substrings by key]
+The key and <'string1'> are first expanded separately. Leading and trailing
+white space is removed from the key (but not from any of the strings). The key
+must not consist entirely of digits. The expanded <'string1'> must be of the
+form:
+
+  <key1> = <value1>  <key2> = <value2> ...
++
+cindex:[$value$]
+where the equals signs and spaces (but not both) are optional. If any of the
+values contain white space, they must be enclosed in double quotes, and any
+values that are enclosed in double quotes are subject to escape processing as
+described in section <<SECTstrings>>. The expanded <'string1'> is searched for
+the value that corresponds to the key. The search is case-insensitive. If the
+key is found, <'string2'> is expanded, and replaces the whole item; otherwise
+<'string3'> is used. During the expansion of <'string2'> the variable $value$
+contains the value that has been extracted. Afterwards, it is restored to any
 previous value it might have had.
 +
 If \{<'string3'>\} is omitted, the item is replaced by an empty string if the
@@ -8090,7 +8442,7 @@ This forces an expansion failure (see section <<SECTforexpfai>>);
 *\$\{extract\{*<'number'>*\}\{*<'separators'>*\}\{*<'string1'>*\}\{*<'string2'>*\}\{*<'string3'>*\}\}*::
 cindex:[expansion,extracting substrings by number]
 The <'number'> argument must consist entirely of decimal digits,
-apart from leading and trailing whitespace, which is ignored.
+apart from leading and trailing white space, which is ignored.
 This is what distinguishes this form of %extract% from the previous kind. It
 behaves in the same way, except that, instead of extracting a named field, it
 extracts from <'string1'> the field whose number is given as the first
@@ -8175,12 +8527,12 @@ The difference between %rheader%, %bheader%, and %header% is in the way the
 data in the header line is interpreted.
 +
 --
-- cindex:[whitespace,in header lines]
+- cindex:[white space,in header lines]
 %rheader% gives the original ``raw'' content of the header line, with no
-processing at all, and without the removal of leading and trailing whitespace.
+processing at all, and without the removal of leading and trailing white space.
 
 - cindex:[base64 encoding,in header lines]
-%bheader% removes leading and trailing whitespace, and then decodes base64 or
+%bheader% removes leading and trailing white space, and then decodes base64 or
 quoted-printable MIME ``words'' within the header text, but does no character
 set translation. If decoding of what looks superficially like a MIME ``word''
 fails, the raw string is returned. If decoding
@@ -8428,6 +8780,49 @@ The ^redirect^ router has an option called %forbid_filter_perl% which locks
 out the use of this expansion item in filter files.
 
 
+*\$\{prvs\{*<'address'>*\}\{*<'secret'>*\}\{*<'keynumber'>*\}\}*::
++
+[revisionflag="changed"]
+cindex:[prvs,expansion item]
+The first argument is a complete email address and the second is secret
+keystring. The third argument, specifying a key number, is optional. If absent,
+it defaults to 0. The result of the expansion is a prvs-signed email address,
+to be typically used with the %return_path% option on an ^smtp^ transport as
+part of a bounce address tag validation (BATV) scheme. For more discussion and
+an example, see section <<SECTverifyPRVS>>.
+
+
+*\$\{prvscheck\{*<'address'>*\}\{*<'secret'>*\}\{*<'string'>*\}\}*::
++
+[revisionflag="changed"]
+cindex:[prvscheck,expansion item]
+This expansion item is the complement of the %prvs% item. It is used for
+checking prvs-signed addresses. If the expansion of the first argument does not
+yield a syntactically valid prvs-signed address, the whole item expands to the
+empty string. When the first argument does expand to a syntactically valid
+prvs-signed address, the second argument is expanded, with the prvs-decoded
+version of the address and the key number extracted from the address in the
+variables $prvscheck_address$ and $prvscheck_keynum$, respectively.
++
+[revisionflag="changed"]
+These two variables can be used in the expansion of the second argument to
+retrieve the secret. The validity of the prvs-signed address is then checked
+against the secret. The result is stored in the variable $prvscheck_result$,
+which is empty for failure or ``1'' for success.
++
+[revisionflag="changed"]
+The third argument is optional; if it is missing, it defaults to an empty
+string. This argument is now expanded. If the result is an empty string, the
+result of the expansion is the decoded version of the address. This is the case
+whether or not the signature was valid. Otherwise, the result of the expansion
+is the expansion of the third argument.
++
+[revisionflag="changed"]
+All three variables can be used in the expansion of the third argument.
+However, once the expansion is complete, only $prvscheck_result$ remains set.
+For more discussion and an example, see section <<SECTverifyPRVS>>.
+
+
 *\$\{readfile\{*<'file~name'>*\}\{*<'eol~string'>*\}\}*::
 cindex:[expansion,inserting an entire file]
 cindex:[file,inserting into expansion]
@@ -8510,15 +8905,20 @@ command is run in a separate process, but under the same uid and gid. As in
 other command executions from Exim, a shell is not used by default. If you want
 a shell, you must explicitly code it.
 +
+[revisionflag="changed"]
 cindex:[return code,from %run% expansion]
+cindex:[$value$]
 If the command succeeds (gives a zero return code) <'string1'> is expanded and
 replaces the entire item; during this expansion, the standard output from the
 command is in the variable $value$. If the command fails, <'string2'>, if
-present, is expanded. If it is absent, the result is empty. Alternatively,
-<'string2'> can be the word ``fail'' (not in braces) to force expansion failure
-if the command does not succeed. If both strings are omitted, the result is the
-standard output on success, and nothing on failure.
-+
+present, is expanded and used. Once again, during the expansion, the standard
+output from the command is in the variable $value$. If <'string2'> is absent,
+the result is empty. Alternatively, <'string2'> can be the word ``fail'' (not
+in braces) to force expansion failure if the command does not succeed. If both
+strings are omitted, the result is contents of the standard output on success,
+and nothing on failure.
++
+cindex:[$runrc$]
 The return code from the command is put in the variable $runrc$, and this
 remains set afterwards, so in a filter file you can do things like this:
 
@@ -8654,18 +9054,26 @@ not parse successfully, the result is empty.
 
 
 *\$\{base62:*<'digits'>*\}*::
++
+[revisionflag="changed"]
 cindex:[base62]
 cindex:[expansion,conversion to base 62]
 The string must consist entirely of decimal digits. The number is converted to
-base 62 (sic) and output as a string of six characters, including leading
-zeros. *Note*: Just to be absolutely clear: this is 'not' base64
-encoding.
+base 62 and output as a string of six characters, including leading zeros. In
+the few operating environments where Exim uses base 36 instead of base 62 for
+its message identifiers (because those systems do not have case-sensitive file
+names), base 36 is used by this operator, despite its name. *Note*: Just to be
+absolutely clear: this is 'not' base64 encoding.
 
 *\$\{base62d:*<'base-62~digits'>*\}*::
++
+[revisionflag="changed"]
 cindex:[base62]
 cindex:[expansion,conversion to base 62]
-The string must consist entirely of base-62 digits. The number is converted to
-decimal and output as a string.
+The string must consist entirely of base-62 digits, or, in operating
+environments where Exim uses base 36 instead of base 62 for its message
+identifiers, base-36 digits. The number is converted to decimal and output as a
+string.
 
 
 *\$\{domain:*<'string'>*\}*::
@@ -8685,14 +9093,16 @@ controlled by the %print_topbitchars% option.
 
 *\$\{eval:*<'string'>*\}*::
 *\$\{eval10:*<'string'>*\}*::
++
+[revisionflag="changed"]
 cindex:[expansion,expression evaluation]
 cindex:[expansion,arithmetic expression]
 These items supports simple arithmetic in expansion strings. The string (after
 expansion) must be a conventional arithmetic expression, but it is limited to
-the four basic operators (plus, minus, times, divide) and parentheses. All
-operations are carried out using integer arithmetic. Plus and minus have a
-lower priority than times and divide; operators with the same priority are
-evaluated from left to right.
+five basic operators (plus, minus, times, divide, remainder) and parentheses.
+All operations are carried out using integer arithmetic. Plus and minus have a
+lower priority than times, divide, and remainder; operators with the same
+priority are evaluated from left to right.
 +
 For %eval%, numbers may be decimal, octal (starting with ``0'') or hexadecimal
 (starting with ``0x''). For %eval10%, all numbers are taken as decimal, even if
@@ -8703,10 +9113,12 @@ A number may be followed by ``K'' or ``M'' to multiply it by 1024 or 1024\*1024,
 respectively. Negative numbers are supported. The result of the computation is
 a decimal representation of the answer (without ``K'' or ``M''). For example:
 +
+[revisionflag="changed"]
 &&&
 `\${eval:1+1}     `  yields 2
 `\${eval:1+2*3}   `  yields 7
 `\${eval:(1+2)*3} `  yields 9
+`\${eval:2+42%5}  `  yields 4
 &&&
 +
 As a more realistic example, in an ACL you might have
@@ -8938,13 +9350,17 @@ cindex:[file,extracting characteristics]
 The string, after expansion, must be a file path. A call to the 'stat()'
 function is made for this path. If 'stat()' fails, an error occurs and the
 expansion fails. If it succeeds, the data from the stat replaces the item, as a
-series of <'name'>=<'value'> pairs, where the values are all numerical,
-except for the value of ``smode''. The names are: ``mode'' (giving the mode as a
+series of <'name'>=<'value'> pairs, where the values are all numerical, except
+for the value of ``smode''. The names are: ``mode'' (giving the mode as a
 4-digit octal number), ``smode'' (giving the mode in symbolic format as a
-10-character string, as for the 'ls' command), ``inode'', ``device'', ``links'',
-``uid'', ``gid'', ``size'', ``atime'', ``mtime'', and ``ctime''. You can extract individual
-fields using the %extract% expansion item. *Warning*: The file size may be
-incorrect on 32-bit systems for files larger than 2GB.
+10-character string, as for the 'ls' command), ``inode'', ``device'',
+``links'', ``uid'', ``gid'', ``size'', ``atime'', ``mtime'', and ``ctime''. You
+can extract individual fields using the %extract% expansion item.
++
+[revisionflag="changed"]
+The use of the %stat% expansion in users' filter files can be locked out by the
+system administrator. *Warning*: The file size may be incorrect on 32-bit
+systems for files larger than 2GB.
 
 
 *\$\{str2b64:*<'string'>*\}*::
@@ -9124,9 +9540,8 @@ exists in the message. For example,
 
   ${if def:header_reply-to:{$h_reply-to:}{$h_from:}}
 +
-Note that no %\$% appears before %header_% or %h_% in the condition,
-and that header names must be terminated by colons if white space does not
-follow.
+*Note*: no %\$% appears before %header_% or %h_% in the condition, and the
+header name must be terminated by a colon if white space does not follow.
 
 *eq~\{*<'string1'>*\}\{*<'string2'>*\}*::
 cindex:[string,comparison]
@@ -9267,19 +9682,70 @@ of the %if% expansion, the previous values are restored. After testing a
 combination of conditions using %or%, the subsequent values of the numeric
 variables are those of the condition that succeeded.
 
-*match_domain~\{*<'string1'>*\}\{*<'string2'>*\}*::
+*match_address~\{*<'string1'>*\}\{*<'string2'>*\}*::
 See *match_local_part*.
 
-*match_address~\{*<'string1'>*\}\{*<'string2'>*\}*::
+*match_domain~\{*<'string1'>*\}\{*<'string2'>*\}*::
 See *match_local_part*.
 
+*match_ip~\{*<'string1'>*\}\{*<'string2'>*\}*::
++
+[revisionflag="changed"]
+This condition matches an IP address to a list of IP address patterns. It must
+be followed by two argument strings. The first (after expansion) must be an IP
+address or an empty string. The second (after expansion) is a restricted host
+list that can match only an IP address, not a host name. For example:
++
+[revisionflag="changed"]
+....
+${if match_ip{$sender_host_address}{1.2.3.4:5.6.7.8}{...}{...}}
+....
++
+[revisionflag="changed"]
+The specific types of host list item that are permitted in the list are:
++
+--
+- An IP address, optionally with a CIDR mask.
+
+- A single asterisk, which matches any IP address.
+
+- An empty item, which matches only if the IP address is empty. This could be
+useful for testing for a locally submitted message or one from specific hosts
+in a single test such as
+
+....
+   ${if match_ip{$sender_host_address}{:4.3.2.1:...}{...}{...}}
+....
+
+where the first item in the list is the empty string.
+
+- The item @[] matches any of the local host's interface addresses.
+
+- Lookups are assumed to be ``net-'' style lookups, even if `net-` is not
+specified. Thus, the following are equivalent:
+
+....
+   ${if match_ip{$sender_host_address}{lsearch;/some/file}...
+   ${if match_ip{$sender_host_address}{net-lsearch;/some/file}...
+....
+
+You do need to specify the `net-` prefix if you want to specify a
+specific address mask, for example, by using `net24-`.
+--
++
+[revisionflag="changed"]
+Consult section <<SECThoslispatip>> for further details of these patterns.
+
+
+
 *match_local_part~\{*<'string1'>*\}\{*<'string2'>*\}*::
 cindex:[domain list,in expansion condition]
 cindex:[address list,in expansion condition]
 cindex:[local part list,in expansion condition]
-These conditions make it possible to test domain, address, and local
-part lists within expansions. Each condition requires two arguments: an item
-and a list to match. A trivial example is:
+This condition, together with %match_address% and %match_domain%, make it
+possible to test domain, address, and local part lists within expansions. Each
+condition requires two arguments: an item and a list to match. A trivial
+example is:
 
   ${if match_domain{a.b.c}{x.y.z:a.b.c:p.q.r}{yes}{no}}
 +
@@ -9298,8 +9764,8 @@ caselessly.
 +
 *Note*: Host lists are 'not' supported in this way. This is because
 hosts have two identities: a name and an IP address, and it is not clear
-how to specify cleanly how such a test would work. At least, I haven't come
-up with anything yet.
+how to specify cleanly how such a test would work. However, IP addresses can be
+matched using %match_ip%.
 
 *pam~\{*<'string1'>*:*<'string2'>*:...\}*::
 cindex:[PAM authentication]
@@ -9319,7 +9785,7 @@ in _Local/Makefile_. You probably need to add %-lpam% to EXTRALIBS, and
 in some releases of GNU/Linux %-ldl% is also needed.
 +
 The argument string is first expanded, and the result must be a
-colon-separated list of strings. Leading and trailing whitespace is ignored.
+colon-separated list of strings. Leading and trailing white space is ignored.
 The PAM module is initialized with the service name ``exim'' and the user name
 taken from the first item in the colon-separated data string (<'string1'>). The
 remaining items in the data string are passed over in response to requests from
@@ -9390,9 +9856,19 @@ set RADIUS_CONFIG_FILE in _Local/Makefile_ to specify the location of
 the Radius client configuration file in order to build Exim with Radius
 support.
 +
+[revisionflag="changed"]
 With just that one setting, Exim expects to be linked with the %radiusclient%
-library. You can also link Exim with the %libradius% library that comes with
-FreeBSD. To do this, set
+library, using the original API. If you are using release 0.4.0 or later of
+this library, you need to set
++
+[revisionflag="changed"]
+....
+RADIUS_LIB_TYPE=RADIUSCLIENTNEW
+....
++
+[revisionflag="changed"]
+in _Local/Makefile_ when building Exim. You can also link Exim with the
+%libradius% library that comes with FreeBSD. To do this, set
 
   RADIUS_LIB_TYPE=RADLIB
 +
@@ -9509,11 +9985,26 @@ saved with the message, and can be accessed by filters, routers, and transports
 during subsequent delivery.
 
 $acl_verify_message$::
-During the expansion of the %message% and %log_message% modifiers in an ACL
-statement after an address verification has failed, this variable contains the
-original failure message that will be overridden by the expanded string.
++
+[revisionflag="changed"]
+cindex:[$acl_verify_message$]
+After an address verification has failed, this variable contains the failure
+message. It retains its value for use in subsequent modifiers. The message can
+be preserved by coding like this:
++
+[revisionflag="changed"]
+....
+warn !verify = sender
+     set acl_m0 = $acl_verify_message
+....
++
+[revisionflag="changed"]
+You can use $acl_verify_message$ during the expansion of the %message% or
+%log_message% modifiers, to include information about the verification failure.
+
 
 $address_data$::
+cindex:[$address_data$]
 This variable is set by means of the %address_data% option in routers. The
 value then remains with the address while it is processed by subsequent routers
 and eventually a transport. If the transport is handling multiple addresses,
@@ -9538,6 +10029,7 @@ after the end of the current ACL statement. If you want to preserve
 these values for longer, you can save them in ACL variables.
 
 $address_file$::
+cindex:[$address_file$]
 When, as a result of aliasing, forwarding, or filtering, a message is directed
 to a specific file, this variable holds the name of the file when the transport
 is running. At other times, the variable is empty. For example, using the
@@ -9554,23 +10046,27 @@ then up to the transport configuration to generate an appropriate absolute path
 to the relevant file.
 
 $address_pipe$::
+cindex:[$address_pipe$]
 When, as a result of aliasing or forwarding, a message is directed to a pipe,
 this variable holds the pipe command when the transport is running.
 
 $authenticated_id$::
 cindex:[authentication,id]
+cindex:[$authenticated_id$]
 When a server successfully authenticates a client it may be configured to
 preserve some of the authentication information in the variable
 $authenticated_id$ (see chapter <<CHAPSMTPAUTH>>). For example, a user/password
 authenticator configuration might preserve the user name for use in the
-routers. When a message is submitted locally (that is, not over a TCP
-connection), the value of $authenticated_id$ is the login name of the calling
-process.
+routers. Note that this is not the same information that is saved in
+$sender_host_authenticated$. When a message is submitted locally (that is, not
+over a TCP connection), the value of $authenticated_id$ is the login name of
+the calling process.
 
 $authenticated_sender$::
 cindex:[sender,authenticated]
 cindex:[authentication,sender]
 cindex:[AUTH,on MAIL command]
+cindex:[$authenticated_sender$]
 When acting as a server, Exim takes note of the AUTH= parameter on an incoming
 SMTP MAIL command if it believes the sender is sufficiently trusted, as
 described in section <<SECTauthparamail>>. Unless the data is the string
@@ -9578,6 +10074,7 @@ described in section <<SECTauthparamail>>. Unless the data is the string
 available during delivery in the $authenticated_sender$ variable. If the sender
 is not trusted, Exim accepts the syntax of AUTH=, but ignores the data.
 +
+cindex:[$qualify_domain$]
 When a message is submitted locally (that is, not over a TCP connection), the
 value of $authenticated_sender$ is an address constructed from the login
 name of the calling process and $qualify_domain$.
@@ -9585,6 +10082,7 @@ name of the calling process and $qualify_domain$.
 
 $authentication_failed$::
 cindex:[authentication,failure]
+cindex:[$authentication_failed$]
 This variable is set to ``1'' in an Exim server if a client issues an AUTH
 command that does not succeed. Otherwise it is set to ``0''. This makes it
 possible to distinguish between ``did not try to authenticate''
@@ -9597,28 +10095,33 @@ an undefined mechanism.
 $body_linecount$::
 cindex:[message body, line count]
 cindex:[body of message,line count]
+cindex:[$body_linecount$]
 When a message is being received or delivered, this variable contains the
-number of lines in the message's body.
+number of lines in the message's body. See also $message_linecount$.
 
 $body_zerocount$::
 cindex:[message body, binary zero count]
 cindex:[body of message,binary zero count]
 cindex:[binary zero,in message body]
+cindex:[$body_zerocount$]
 When a message is being received or delivered, this variable contains the
 number of binary zero bytes in the message's body.
 
 $bounce_recipient$::
+cindex:[$bounce_recipient$]
 This is set to the recipient address of a bounce message while Exim is creating
 it. It is useful if a customized bounce message text file is in use (see
 chapter <<CHAPemsgcust>>).
 
 $bounce_return_size_limit$::
+cindex:[$bounce_return_size_limit$]
 This contains the value set in the %bounce_return_size_limit% option, rounded
 up to a multiple of 1000. It is useful when a customized error message text
 file is in use (see chapter <<CHAPemsgcust>>).
 
 $caller_gid$::
 cindex:[gid (group id),caller]
+cindex:[$caller_gid$]
 The real group id under which the process that called Exim was running. This is
 not the same as the group id of the originator of a message (see
 $originator_gid$). If Exim re-execs itself, this variable in the new
@@ -9626,25 +10129,30 @@ incarnation normally contains the Exim gid.
 
 $caller_uid$::
 cindex:[uid (user id),caller]
+cindex:[$caller_uid$]
 The real user id under which the process that called Exim was running. This is
 not the same as the user id of the originator of a message (see
 $originator_uid$). If Exim re-execs itself, this variable in the new
 incarnation normally contains the Exim uid.
 
 $compile_date$::
+cindex:[$compile_date$]
 The date on which the Exim binary was compiled.
 
 $compile_number$::
+cindex:[$compile_number$]
 The building process for Exim keeps a count of the number
 of times it has been compiled. This serves to distinguish different
 compilations of the same version of the program.
 
 $demime_errorlevel$::
+cindex:[$demime_errorlevel$]
 This variable is available when Exim is compiled with
 the content-scanning extension and the obsolete %demime% condition. For
 details, see section <<SECTdemimecond>>.
 
 $demime_reason$::
+cindex:[$demime_reason$]
 This variable is available when Exim is compiled with the
 content-scanning extension and the obsolete %demime% condition. For details,
 see section <<SECTdemimecond>>.
@@ -9652,27 +10160,31 @@ see section <<SECTdemimecond>>.
 
 $dnslist_domain$::
 cindex:[black list (DNS)]
+cindex:[$dnslist_domain$]
 When a client host is found to be on a DNS (black) list,
 the list's domain name is put into this variable so that it can be included in
 the rejection message.
 
 $dnslist_text$::
+cindex:[$dnslist_text$]
 When a client host is found to be on a DNS (black) list, the
 contents of any associated TXT record are placed in this variable.
 
 $dnslist_value$::
+cindex:[$dnslist_value$]
 When a client host is found to be on a DNS (black) list,
 the IP address from the resource record is placed in this variable.
 If there are multiple records, all the addresses are included, comma-space
 separated.
 
 $domain$::
-When an address is being routed, or delivered on its own, this
-variable contains the domain. Global address rewriting happens when a message
-is received, so the value of $domain$ during routing and delivery is the
-value after rewriting. $domain$ is set during user filtering, but not during
-system filtering, because a message may have many recipients and the system
-filter is called just once.
+cindex:[$domain$]
+When an address is being routed, or delivered on its own, this variable
+contains the domain. Global address rewriting happens when a message is
+received, so the value of $domain$ during routing and delivery is the value
+after rewriting. $domain$ is set during user filtering, but not during system
+filtering, because a message may have many recipients and the system filter is
+called just once.
 +
 When more than one address is being delivered at once (for example, several
 RCPT commands in one SMTP delivery), $domain$ is set only if they all
@@ -9686,12 +10198,15 @@ At the end of a delivery, if all deferred addresses have the same domain, it is
 set in $domain$ during the expansion of %delay_warning_condition%.
 +
 The $domain$ variable is also used in some other circumstances:
-
-- When an ACL is running for a RCPT command, $domain$ contains the domain
-of the recipient address.
-*Note:* the domain of the sender address is in $sender_address_domain$
-at MAIL time and at RCPT time. $domain$ is not set for the MAIL
-ACL.
++
+--
+- When an ACL is running for a RCPT command, $domain$ contains the domain of
+the recipient address. The domain of the 'sender' address is in
+$sender_address_domain$ at both MAIL time and at RCPT time. $domain$ is not
+normally set during the running of the MAIL ACL. However, if the sender address
+is verified with a callout during the MAIL ACL, the sender domain is placed in
+$domain$ during the expansions of %hosts%, %interface%, and %port% in the
+^smtp^ transport.
 
 - When a rewrite item is being processed (see chapter <<CHAPrewrite>>), $domain$
 contains the domain portion of the address that is being rewritten; it can be
@@ -9709,9 +10224,11 @@ recipient domain (which is what is in $domain$ at this time).
 cindex:[%smtp_etrn_command%]
 When the %smtp_etrn_command% option is being expanded, $domain$ contains
 the complete argument of the ETRN command (see section <<SECTETRN>>).
+--
 
 
 $domain_data$::
+cindex:[$domain_data$]
 When the %domains% option on a router matches a domain by
 means of a lookup, the data read by the lookup is available during the running
 of the router as $domain_data$. In addition, if the driver routes the
@@ -9725,27 +10242,31 @@ the rest of the ACL statement. In all other situations, this variable expands
 to nothing.
 
 $exim_gid$::
+cindex:[$exim_gid$]
 This variable contains the numerical value of the Exim group id.
 
 $exim_path$::
+cindex:[$exim_path$]
 This variable contains the path to the Exim binary.
 
 $exim_uid$::
+cindex:[$exim_uid$]
 This variable contains the numerical value of the Exim user id.
 
 $found_extension$::
+cindex:[$found_extension$]
 This variable is available when Exim is compiled with the
 content-scanning extension and the obsolete %demime% condition. For details,
 see section <<SECTdemimecond>>.
 
 $header_$<'name'>::
-This is not strictly an expansion variable. It is
-expansion syntax for inserting the message header line with the given name.
-Note that the name must be terminated by colon or white space, because it may
-contain a wide variety of characters.
-Note also that braces must 'not' be used.
+This is not strictly an expansion variable. It is expansion syntax for
+inserting the message header line with the given name. Note that the name must
+be terminated by colon or white space, because it may contain a wide variety of
+characters. Note also that braces must 'not' be used.
 
 $home$::
+cindex:[$home$]
 When the %check_local_user% option is set for a router, the user's home
 directory is placed in $home$ when the check succeeds. In particular, this
 means it is set during the running of users' filter files. A router may also
@@ -9756,6 +10277,7 @@ When running a filter test via the %-bf% option, $home$ is set to the value
 of the environment variable HOME.
 
 $host$::
+cindex:[$host$]
 When the ^smtp^ transport is expanding its options for encryption using TLS,
 $host$ contains the name of the host to which it is connected. Likewise, when
 used in the client part of an authenticator configuration (see chapter
@@ -9770,11 +10292,13 @@ is run as a result of a router that sets up a host list, $host$ contains the
 name of the first host.
 
 $host_address$::
+cindex:[$host_address$]
 This variable is set to the remote host's IP address whenever $host$ is set for
 a remote connection. It is also set to the IP address that is being checked
 when the %ignore_target_hosts% option is being processed.
 
 $host_data$::
+cindex:[$host_data$]
 If a %hosts% condition in an ACL is satisfied by means of a lookup, the result
 of the lookup is made available in the $host_data$ variable. This
 allows you, for example, to do things like this:
@@ -9785,6 +10309,7 @@ allows you, for example, to do things like this:
 
 $host_lookup_deferred$::
 cindex:[host name lookup, failure of]
+cindex:[$host_lookup_deferred$]
 This variable normally contains ``0'', as does $host_lookup_failed$. When a
 message comes from a remote host and there is an attempt to look up the host's
 name from its IP address, and the attempt is not successful, one of these
@@ -9811,38 +10336,46 @@ the result, the name is not accepted, and $host_lookup_deferred$ is set to
 ``1''. See also $sender_host_name$.
 
 $host_lookup_failed$::
+cindex:[$host_lookup_failed$]
 See $host_lookup_deferred$.
 
 
 $inode$::
+cindex:[$inode$]
 The only time this variable is set is while expanding the %directory_file%
 option in the ^appendfile^ transport. The variable contains the inode number
 of the temporary file which is about to be renamed. It can be used to construct
 a unique name for the file.
 
 $interface_address$::
-When a message is received over a TCP/IP connection, this variable contains the
-address of the local IP interface. See also the %-oMi% command line option.
-This variable can be used in ACLs and also, for example, to make the file name
-for a TLS certificate depend on which interface is being used.
++
+[revisionflag="changed"]
+cindex:[$interface_address$]
+As soon as a server starts processing a TCP/IP connection, this variable is set
+to the address of the local IP interface, and $interface_port$ is set to the
+port number. These values are therefore available for use in the ``connect''
+ACL. See also the %-oMi% command line option. As well as being used in ACLs,
+these variable could be used, for example, to make the file name for a TLS
+certificate depend on which interface and/or port is being used.
 
 $interface_port$::
-When a message is received over a TCP/IP connection, this variable contains the
-local port number. See also the %-oMi% command line option.
-This variable can be used in ACLs and also, for example, to make the file name
-for a TLS certificate depend on which port is being used.
+cindex:[$interface_port$]
+See $interface_address$.
 
 $ldap_dn$::
+cindex:[$ldap_dn$]
 This variable, which is available only when Exim is compiled with LDAP support,
 contains the DN from the last entry in the most recently successful LDAP
 lookup.
 
 $load_average$::
+cindex:[$load_average$]
 This variable contains the system load average, multiplied by 1000 to that it
 is an integer. For example, if the load average is 0.21, the value of the
 variable is 210. The value is recomputed every time the variable is referenced.
 
 $local_part$::
+cindex:[$local_part$]
 When an address is being routed, or delivered on its own, this
 variable contains the local part. When a number of addresses are being
 delivered together (for example, multiple RCPT commands in an SMTP
@@ -9854,6 +10387,8 @@ $local_part$ is set during user filtering, but not during system filtering,
 because a message may have many recipients and the system filter is called just
 once.
 +
+cindex:[$local_part_prefix$]
+cindex:[$local_part_suffix$]
 If a local part prefix or suffix has been recognized, it is not included in the
 value of $local_part$ during routing and subsequent delivery. The values of
 any prefix or suffix are in $local_part_prefix$ and
@@ -9891,6 +10426,7 @@ to process local parts in a case-dependent manner in a router, you can set the
 %caseful_local_part% option (see chapter <<CHAProutergeneric>>).
 
 $local_part_data$::
+cindex:[$local_part_data$]
 When the %local_parts% option on a router matches a local part by means of a
 lookup, the data read by the lookup is available during the running of the
 router as $local_part_data$. In addition, if the driver routes the address
@@ -9903,43 +10439,50 @@ available during the rest of the ACL statement. In all other situations, this
 variable expands to nothing.
 
 $local_part_prefix$::
+cindex:[$local_part_prefix$]
 When an address is being routed or delivered, and a
 specific prefix for the local part was recognized, it is available in this
 variable, having been removed from $local_part$.
 
 $local_part_suffix$::
+cindex:[$local_part_suffix$]
 When an address is being routed or delivered, and a
 specific suffix for the local part was recognized, it is available in this
 variable, having been removed from $local_part$.
 
 $local_scan_data$::
+cindex:[$local_scan_data$]
 This variable contains the text returned by the 'local_scan()' function when a
 message is received. See chapter <<CHAPlocalscan>> for more details.
 
 $local_user_gid$::
+cindex:[$local_user_gid$]
 See $local_user_uid$.
 
 $local_user_uid$::
-This variable and $local_user_gid$ are set to
-the uid and gid after the %check_local_user% router precondition succeeds.
-This means that their values are available for the remaining preconditions
-(%senders%, %require_files%, and %condition%), for the %address_data%
-expansion, and for any router-specific expansions. At all other times, the
-values in these variables are `(uid_t)(-1)` and `(gid_t)(-1)`,
-respectively.
+cindex:[$local_user_uid$]
+This variable and $local_user_gid$ are set to the uid and gid after the
+%check_local_user% router precondition succeeds. This means that their values
+are available for the remaining preconditions (%senders%, %require_files%, and
+%condition%), for the %address_data% expansion, and for any router-specific
+expansions. At all other times, the values in these variables are `(uid_t)(-1)`
+and `(gid_t)(-1)`, respectively.
 
 $localhost_number$::
+cindex:[$localhost_number$]
 This contains the expanded value of the
 %localhost_number% option. The expansion happens after the main options have
 been read.
 
 $log_inodes$::
+cindex:[$log_inodes$]
 The number of free inodes in the disk partition where Exim's
 log files are being written. The value is recalculated whenever the variable is
 referenced. If the relevant file system does not have the concept of inodes,
 the value of is -1. See also the %check_log_inodes% option.
 
 $log_space$::
+cindex:[$log_space$]
 The amount of free space (as a number of kilobytes) in the disk
 partition where Exim's log files are being written. The value is recalculated
 whenever the variable is referenced. If the operating system does not have the
@@ -9948,14 +10491,16 @@ the space value is -1. See also the %check_log_space% option.
 
 
 $mailstore_basename$::
-This variable is set only when doing deliveries in
-``mailstore'' format in the ^appendfile^ transport. During the expansion of the
-%mailstore_prefix%, %mailstore_suffix%, %message_prefix%, and
-%message_suffix% options, it contains the basename of the files that are being
-written, that is, the name without the ``.tmp'', ``.env'', or ``.msg'' suffix. At all
-other times, this variable is empty.
+cindex:[$mailstore_basename$]
+This variable is set only when doing deliveries in ``mailstore'' format in the
+^appendfile^ transport. During the expansion of the %mailstore_prefix%,
+%mailstore_suffix%, %message_prefix%, and %message_suffix% options, it contains
+the basename of the files that are being written, that is, the name without the
+``.tmp'', ``.env'', or ``.msg'' suffix. At all other times, this variable is
+empty.
 
 $malware_name$::
+cindex:[$malware_name$]
 This variable is available when Exim is compiled with the
 content-scanning extension. It is set to the name of the virus that was found
 when the ACL %malware% condition is true (see section <<SECTscanvirus>>).
@@ -9963,14 +10508,16 @@ when the ACL %malware% condition is true (see section <<SECTscanvirus>>).
 
 $message_age$::
 cindex:[message,age of]
-This variable is set at the start of a delivery attempt to
-contain the number of seconds since the message was received. It does not
-change during a single delivery attempt.
+cindex:[$message_age$]
+This variable is set at the start of a delivery attempt to contain the number
+of seconds since the message was received. It does not change during a single
+delivery attempt.
 
 $message_body$::
 cindex:[body of message,expansion variable]
 cindex:[message body, in expansion]
 cindex:[binary zero,in message body]
+cindex:[$message_body$]
 This variable contains the initial portion of a message's
 body while it is being delivered, and is intended mainly for use in filter
 files. The maximum number of characters of the body that are put into the
@@ -9982,6 +10529,7 @@ Binary zeros are also converted into spaces.
 $message_body_end$::
 cindex:[body of message,expansion variable]
 cindex:[message body, in expansion]
+cindex:[$message_body_end$]
 This variable contains the final portion of a message's
 body while it is being delivered. The format and maximum size are as for
 $message_body$.
@@ -9989,11 +10537,22 @@ $message_body$.
 $message_body_size$::
 cindex:[body of message,size]
 cindex:[message body, size]
-When a message is being delivered, this variable
-contains the size of the body in bytes. The count starts from the character
-after the blank line that separates the body from the header. Newlines are
-included in the count. See also $message_size$, $body_linecount$, and
-$body_zerocount$.
+cindex:[$message_body_size$]
+When a message is being delivered, this variable contains the size of the body
+in bytes. The count starts from the character after the blank line that
+separates the body from the header. Newlines are included in the count. See
+also $message_size$, $body_linecount$, and $body_zerocount$.
+
+$message_exim_id$::
++
+[revisionflag="changed"]
+cindex:[$message_exim_id$]
+When a message is being received or delivered, this variable contains the
+unique message id that is generated and used by Exim to identify the message.
+An id is not created for a message until after its header has been successfully
+received. *Note*: This is 'not' the contents of the 'Message-ID:' header line;
+it is the local id that Exim assigns to the message, for example:
+`1BXTIK-0001yO-VA`.
 
 $message_headers$::
 This variable contains a concatenation of all the header lines when a message
@@ -10001,17 +10560,38 @@ is being processed, except for lines added by routers or transports. The header
 lines are separated by newline characters.
 
 $message_id$::
-When a message is being received or delivered, this variable contains the
-unique message id that is used by Exim to identify the message.
-An id is not created for a message until after its header has been
-successfully received.
-*Note*: This is 'not' the contents of the 'Message-ID:' header line; it
-is the local id that Exim assigns to the message, for example:
-`1BXTIK-0001yO-VA`.
++
+[revisionflag="changed"]
+This is an old name for $message_exim_id$, which is now deprecated.
+
+$message_linecount$::
++
+[revisionflag="changed"]
+cindex:[$message_linecount$]
+This variable contains the total number of lines in the header and body of the
+message. Compare $body_linecount$, which is the count for the body only. During
+the DATA and content-scanning ACLs, $message_linecount$ contains the number of
+lines received. Before delivery happens (that is, before filters, routers, and
+transports run) the count is increased to include the 'Received:' header line
+that Exim standardly adds, and also any other header lines that are added by
+ACLs. The blank line that separates the message header from the body is not
+counted. Here is an example of the use of this variable in a DATA ACL:
++
+[revisionflag="changed"]
+....
+deny message   = Too many lines in message header
+     condition = \
+       ${if <{250}{${eval: $message_linecount - $body_linecount}}}
+....
++
+[revisionflag="changed"]
+In the MAIL and RCPT ACLs, the value is zero because at that stage the
+message has not yet been received.
 
 $message_size$::
 cindex:[size,of message]
 cindex:[message,size]
+cindex:[$message_size$]
 When a message is being processed, this variable contains its size in bytes. In
 most cases, the size includes those headers that were received with the
 message, but not those (such as 'Envelope-to:') that are added to individual
@@ -10031,31 +10611,34 @@ A number of variables whose names start with $mime$ are
 available when Exim is compiled with the content-scanning extension. For
 details, see section <<SECTscanmimepart>>.
 
-
 $n0$ -- $n9$::
 These variables are counters that can be incremented by means
 of the %add% command in filter files.
 
 $original_domain$::
-When a top-level address is being processed for delivery,
-this contains the same value as $domain$. However, if a ``child'' address (for
-example, generated by an alias, forward, or filter file) is being processed,
-this variable contains the domain of the original address. This differs from
-$parent_domain$ only when there is more than one level of aliasing or
-forwarding. When more than one address is being delivered in a single transport
-run, $original_domain$ is not set.
+cindex:[$domain$]
+cindex:[$original_domain$]
+When a top-level address is being processed for delivery, this contains the
+same value as $domain$. However, if a ``child'' address (for example, generated
+by an alias, forward, or filter file) is being processed, this variable
+contains the domain of the original address. This differs from $parent_domain$
+only when there is more than one level of aliasing or forwarding. When more
+than one address is being delivered in a single transport run,
+$original_domain$ is not set.
 +
 If new an address is created by means of a %deliver% command in a system
 filter, it is set up with an artificial ``parent'' address. This has the local
 part 'system-filter' and the default qualify domain.
 
 $original_local_part$::
-When a top-level address is being processed for
-delivery, this contains the same value as $local_part$, unless a prefix or
-suffix was removed from the local part, because $original_local_part$
-always contains the full local part. When a ``child'' address (for example,
-generated by an alias, forward, or filter file) is being processed, this
-variable contains the full local part of the original address.
+cindex:[$local_part$]
+cindex:[$original_local_part$]
+When a top-level address is being processed for delivery, this contains the
+same value as $local_part$, unless a prefix or suffix was removed from the
+local part, because $original_local_part$ always contains the full local part.
+When a ``child'' address (for example, generated by an alias, forward, or
+filter file) is being processed, this variable contains the full local part of
+the original address.
 +
 If the router that did the redirection processed the local part
 case-insensitively, the value in $original_local_part$ is in lower case.
@@ -10067,11 +10650,12 @@ If new an address is created by means of a %deliver% command in a system
 filter, it is set up with an artificial ``parent'' address. This has the local
 part 'system-filter' and the default qualify domain.
 
-
 $originator_gid$::
 cindex:[gid (group id),of originating user]
 cindex:[sender,gid]
-The value of $caller_gid$ that was set when the message
+cindex:[$caller_gid$]
+cindex:[$originator_gid$]
+This variable contains the value of $caller_gid$ that was set when the message
 was received. For messages received via the command line, this is the gid of
 the sending user. For messages received by SMTP over TCP/IP, this is normally
 the gid of the Exim user.
@@ -10079,85 +10663,116 @@ the gid of the Exim user.
 $originator_uid$::
 cindex:[uid (user id),of originating user]
 cindex:[sender,uid]
-The value of $caller_uid$ that was set when the message
-was received. For messages received via the command line, this is the uid of
-the sending user. For messages received by SMTP over TCP/IP, this is normally
-the uid of the Exim user.
+cindex:[$caller_uid$]
+cindex:[$originaltor_uid$]
+The value of $caller_uid$ that was set when the message was received. For
+messages received via the command line, this is the uid of the sending user.
+For messages received by SMTP over TCP/IP, this is normally the uid of the Exim
+user.
 
 $parent_domain$::
+cindex:[$parent_domain$]
 This variable is similar to $original_domain$ (see
 above), except that it refers to the immediately preceding parent address.
 
 $parent_local_part$::
+cindex:[$parent_local_part$]
 This variable is similar to $original_local_part$
 (see above), except that it refers to the immediately preceding parent address.
 
 $pid$::
 cindex:[pid (process id),of current process]
+cindex:[$pid$]
 This variable contains the current process id.
 
 $pipe_addresses$::
 cindex:[filter,transport filter]
 cindex:[transport,filter]
-This is not an expansion variable, but is mentioned here
-because the string ``\$pipe_addresses'' is handled specially in the command
-specification for the ^pipe^ transport (chapter <<CHAPpipetransport>>) and in
-transport filters (described under %transport_filter% in chapter
-<<CHAPtransportgeneric>>). It cannot be used in general expansion strings, and
-provokes an ``unknown variable'' error if encountered.
+cindex:[$pipe_addresses$]
+This is not an expansion variable, but is mentioned here because the string
+``\$pipe_addresses'' is handled specially in the command specification for the
+^pipe^ transport (chapter <<CHAPpipetransport>>) and in transport filters
+(described under %transport_filter% in chapter <<CHAPtransportgeneric>>). It
+cannot be used in general expansion strings, and provokes an ``unknown
+variable'' error if encountered.
 
 $primary_hostname$::
-The value set in the configuration file, or read by the
-'uname()' function. If 'uname()' returns a single-component name, Exim
-calls 'gethostbyname()' (or 'getipnodebyname()' where available) in an
-attempt to acquire a fully qualified host name.
-See also $smtp_active_hostname$.
+cindex:[$primary_hostname$]
+This variable contains the value set by %primary_hostname% in the configuration
+file, or read by the 'uname()' function. If 'uname()' returns a
+single-component name, Exim calls 'gethostbyname()' (or 'getipnodebyname()'
+where available) in an attempt to acquire a fully qualified host name. See also
+$smtp_active_hostname$.
+
+
+$prvscheck_address$::
++
+[revisionflag="changed"]
+This variable is used in conjunction with the %prvscheck% expansion item, which
+is described in sections <<SECTexpansionitems>> and <<SECTverifyPRVS>>.
+
+$prvscheck_keynum$::
++
+[revisionflag="changed"]
+This variable is used in conjunction with the %prvscheck% expansion item, which
+is described in sections <<SECTexpansionitems>> and <<SECTverifyPRVS>>.
+
+$prvscheck_result$::
++
+[revisionflag="changed"]
+This variable is used in conjunction with the %prvscheck% expansion item, which
+is described in sections <<SECTexpansionitems>> and <<SECTverifyPRVS>>.
 
 $qualify_domain$::
-The value set for this option in the configuration file.
+cindex:[$qualify_domain$]
+The value set for the %qualify_domain% option in the configuration file.
 
 $qualify_recipient$::
-The value set for this option in the configuration file,
+cindex:[$qualify_recipient$]
+The value set for the %qualify_recipient% option in the configuration file,
 or if not set, the value of $qualify_domain$.
 
 $rcpt_count$::
-When a message is being received by SMTP, this variable
-contains the number of RCPT commands received for the current message. If
-this variable is used in a RCPT ACL, its value includes the current
-command.
+cindex:[$rcpt_count$]
+When a message is being received by SMTP, this variable contains the number of
+RCPT commands received for the current message. If this variable is used in a
+RCPT ACL, its value includes the current command.
 
 $rcpt_defer_count$::
-When a message is being received by SMTP, this variable
-contains the number of RCPT commands in the current message that have
-previously been rejected with a temporary (4##'xx') response.
+cindex:[$rcpt_defer_count$]
+When a message is being received by SMTP, this variable contains the number of
+RCPT commands in the current message that have previously been rejected with a
+temporary (4##'xx') response.
 
 $rcpt_fail_count$::
-When a message is being received by SMTP, this variable
-contains the number of RCPT commands in the current message that have
-previously been rejected with a permanent (5##'xx') response.
+cindex:[$rcpt_fail_count$]
+When a message is being received by SMTP, this variable contains the number of
+RCPT commands in the current message that have previously been rejected with a
+permanent (5##'xx') response.
 
 $received_count$::
-This variable contains the number of 'Received:' header
-lines in the message, including the one added by Exim (so its value is always
-greater than zero). It is available in the DATA ACL, the non-SMTP ACL, and
-while routing and delivering.
+cindex:[$received_count$]
+This variable contains the number of 'Received:' header lines in the message,
+including the one added by Exim (so its value is always greater than zero). It
+is available in the DATA ACL, the non-SMTP ACL, and while routing and
+delivering.
 
 $received_for$::
-If there is only a single recipient address in an incoming
-message, this variable contains that address when the 'Received:' header line
-is being built.
+cindex:[$received_for$]
+If there is only a single recipient address in an incoming message, this
+variable contains that address when the 'Received:' header line is being built.
 The value is copied after recipient rewriting has happened, but before the
 'local_scan()' function is run.
 
 $received_protocol$::
-When a message is being processed, this variable
-contains the name of the protocol by which it was received.
-Most of the names used by Exim are defined by RFCs 821, 2821, and 3848. They
-start with ``smtp'' (the client used HELO) or ``esmtp'' (the client used
-EHLO). This can be followed by ``s'' for secure (encrypted) and/or ``a'' for
-authenticated. Thus, for example, if the protocol is set to ``esmtpsa'', the
-message was received over an encrypted SMTP connection and the client was
-successfully authenticated.
+cindex:[$received_protocol$]
+When a message is being processed, this variable contains the name of the
+protocol by which it was received. Most of the names used by Exim are defined
+by RFCs 821, 2821, and 3848. They start with ``smtp'' (the client used HELO) or
+``esmtp'' (the client used EHLO). This can be followed by ``s'' for secure
+(encrypted) and/or ``a'' for authenticated. Thus, for example, if the protocol
+is set to ``esmtpsa'', the message was received over an encrypted SMTP
+connection and the client was successfully authenticated.
 +
 Exim uses the protocol name ``smtps'' for the case when encryption is
 automatically set up on connection without the use of STARTTLS (see
@@ -10170,12 +10785,18 @@ The %-oMr% option provides a way of specifying a custom protocol name for
 messages that are injected locally by trusted callers. This is commonly used to
 identify messages that are being re-injected after some kind of scanning.
 
+$received_time$::
++
+[revisionflag="changed"]
+cindex:[$received_time$]
+This variable contains the date and time when the current message was received,
+as a number of seconds since the start of the Unix epoch.
 
 $recipient_data$::
-This variable is set after an indexing lookup success in
-an ACL %recipients% condition. It contains the data from the lookup, and the
-value remains set until the next %recipients% test. Thus, you can do things
-like this:
+cindex:[$recipient_data$]
+This variable is set after an indexing lookup success in an ACL %recipients%
+condition. It contains the data from the lookup, and the value remains set
+until the next %recipients% test. Thus, you can do things like this:
 +
 &&&
 `require recipients  = cdb*@;/some/file`
@@ -10188,9 +10809,9 @@ The variable is not set for a lookup that is used as part of the string
 expansion that all such lists undergo before being interpreted.
 
 $recipient_verify_failure$::
-In an ACL, when a recipient verification fails,
-this variable contains information about the failure. It is set to one of the
-following words:
+cindex:[$recipient_verify_failure$]
+In an ACL, when a recipient verification fails, this variable contains
+information about the failure. It is set to one of the following words:
 +
 --
 - ``qualify'': The address was unqualified (no domain), and the message
@@ -10212,6 +10833,7 @@ rejections of MAIL and rejections of RCPT.
 
 
 $recipients$::
+cindex:[$recipients$]
 This variable contains a list of envelope recipients for a
 message. A comma and a space separate the addresses in the replacement text.
 However, the variable is not generally available, to prevent exposure of Bcc
@@ -10225,19 +10847,20 @@ in these two cases:
 
 
 $recipients_count$::
-When a message is being processed, this variable
-contains the number of envelope recipients that came with the message.
-Duplicates are not excluded from the count. While a message is being received
-over SMTP, the number increases for each accepted recipient. It can be
-referenced in an ACL.
+cindex:[$recipients_count$]
+When a message is being processed, this variable contains the number of
+envelope recipients that came with the message. Duplicates are not excluded
+from the count. While a message is being received over SMTP, the number
+increases for each accepted recipient. It can be referenced in an ACL.
 
 $reply_address$::
-When a message is being processed, this variable contains
-the contents of the 'Reply-To:' header line if one exists
-and it is not empty,
-or otherwise the contents of the 'From:' header line.
+cindex:[$reply_address$]
+When a message is being processed, this variable contains the contents of the
+'Reply-To:' header line if one exists and it is not empty, or otherwise the
+contents of the 'From:' header line.
 
 $return_path$::
+cindex:[$return_path$]
 When a message is being delivered, this variable contains the return path --
 the sender field that will be sent as part of the envelope. It is not enclosed
 in <> characters. At the start of routing an address, $return_path$ has the
@@ -10250,10 +10873,12 @@ the incoming envelope sender, and $return_path$ contains the outgoing envelope
 sender.
 
 $return_size_limit$::
+cindex:[$return_size_limit$]
 This is an obsolete name for $bounce_return_size_limit$.
 
 $runrc$::
 cindex:[return code,from %run% expansion]
+cindex:[$runrc$]
 This variable contains the return code from a command that is run by the
 %\$\{run...\}% expansion item. *Warning*: In a router or transport, you cannot
 assume the order in which option values are expanded, except for those
@@ -10262,35 +10887,39 @@ reliably expect to set $runrc$ by the expansion of one option, and use it in
 another.
 
 $self_hostname$::
-When an address is routed to a supposedly remote host that turns out to be the
-local host, what happens is controlled by the
 cindex:[%self% option,value of host name]
-%self% generic router option. One of its values causes the address to be passed
-to another router. When this happens, $self_hostname$ is set to the name of
-the local host that the original router encountered. In other circumstances its
-contents are null.
+cindex:[$self_hostname$]
+When an address is routed to a supposedly remote host that turns out to be the
+local host, what happens is controlled by the %self% generic router option. One
+of its values causes the address to be passed to another router. When this
+happens, $self_hostname$ is set to the name of the local host that the original
+router encountered. In other circumstances its contents are null.
 
 $sender_address$::
-When a message is being processed, this variable contains
-the sender's address that was received in the message's envelope. For bounce
-messages, the value of this variable is the empty string.
-See also $return_path$.
+cindex:[$sender_address$]
+When a message is being processed, this variable contains the sender's address
+that was received in the message's envelope. For bounce messages, the value of
+this variable is the empty string. See also $return_path$.
 
 $sender_address_data$::
+cindex:[$address_data$]
+cindex:[$sender_address_data$]
 If $address_data$ is set when the routers are called from an ACL to verify a
 sender address, the final value is preserved in $sender_address_data$, to
 distinguish it from data from a recipient address. The value does not persist
 after the end of the current ACL statement. If you want to preserve it for
 longer, you can save it in an ACL variable.
 
-
 $sender_address_domain$::
+cindex:[$sender_address_domain$]
 The domain portion of $sender_address$.
 
 $sender_address_local_part$::
+cindex:[$sender_address_local_part$]
 The local part portion of $sender_address$.
 
 $sender_data$::
+cindex:[$sender_data$]
 This variable is set after a lookup success in an ACL %senders% condition or in
 a router %senders% option. It contains the data from the lookup, and the value
 remains set until the next %senders% test. Thus, you can do things like this:
@@ -10306,6 +10935,7 @@ The variable is not set for a lookup that is used as part of the string
 expansion that all such lists undergo before being interpreted.
 
 $sender_fullhost$::
+cindex:[$sender_fullhost$]
 When a message is received from a remote host, this variable contains the host
 name and IP address in a single string. It ends with the IP address in square
 brackets, followed by a colon and a port number if the logging of ports is
@@ -10319,26 +10949,31 @@ the argument of a HELO or EHLO command. This is omitted if it is identical to
 the verified host name or to the host's IP address in square brackets.
 
 $sender_helo_name$::
-When a message is received from a remote host that has
-issued a HELO or EHLO command, the argument of that command is placed
-in this variable. It is also set if HELO or EHLO is used when a message
-is received using SMTP locally via the %-bs% or %-bS% options.
+cindex:[$sender_hslo_name$]
+When a message is received from a remote host that has issued a HELO or EHLO
+command, the argument of that command is placed in this variable. It is also
+set if HELO or EHLO is used when a message is received using SMTP locally via
+the %-bs% or %-bS% options.
 
 $sender_host_address$::
-When a message is received from a remote host, this
-variable contains that host's IP address. For locally submitted messages, it is
-empty.
+cindex:[$sender_host_address$]
+When a message is received from a remote host, this variable contains that
+host's IP address. For locally submitted messages, it is empty.
 
 $sender_host_authenticated$::
+cindex:[$sender_host_authenticated$]
 This variable contains the name (not the public name) of the authenticator
-driver which successfully authenticated the client from which the message was
-received. It is empty if there was no successful authentication.
+driver that successfully authenticated the client from which the message was
+received. It is empty if there was no successful authentication. See also
+$authenticated_id$.
 
 $sender_host_name$::
+cindex:[$sender_host_name$]
 When a message is received from a remote host, this variable contains the
 host's name as obtained by looking up its IP address. For messages received by
 other means, this variable is empty.
 +
+cindex:[$host_lookup_failed$]
 If the host name has not previously been looked up, a reference to
 $sender_host_name$ triggers a lookup (for messages from remote hosts).
 A looked up name is accepted only if it leads back to the original IP address
@@ -10346,6 +10981,7 @@ via a forward lookup. If either the reverse or the forward lookup fails to find
 any data, or if the forward lookup does not yield the original IP address,
 $sender_host_name$ remains empty, and $host_lookup_failed$ is set to ``1''.
 +
+cindex:[$host_lookup_deferred$]
 However, if either of the lookups cannot be completed (for example, there is a
 DNS timeout), $host_lookup_deferred$ is set to ``1'', and
 $host_lookup_failed$ remains set to ``0''.
@@ -10386,26 +11022,35 @@ IP address in an EHLO or HELO command.
 
 
 $sender_host_port$::
-When a message is received from a remote host, this
-variable contains the port number that was used on the remote host.
+cindex:[$sender_host_port$]
+When a message is received from a remote host, this variable contains the port
+number that was used on the remote host.
 
 $sender_ident$::
+cindex:[$sender_ident$]
 When a message is received from a remote host, this variable contains the
 identification received in response to an RFC 1413 request. When a message has
 been received locally, this variable contains the login name of the user that
 called Exim.
 
+$sender_rate_$'xxx'::
++
+[revisionflag="changed"]
+A number of variables whose names begin $sender_rate_$ are set as part of the
+%ratelimit% ACL condition. Details are given in section <<SECTratelimiting>>.
+
 $sender_rcvhost$::
-This is provided specifically for use in 'Received:' headers. It starts with
-either the verified host name (as obtained from a
 cindex:[DNS,reverse lookup]
 cindex:[reverse DNS lookup]
-reverse DNS lookup) or, if there is no verified host name, the IP address in
-square brackets. After that there may be text in parentheses. When the first
-item is a verified host name, the first thing in the parentheses is the IP
-address in square brackets, followed by a colon and a port number if port
-logging is enabled. When the first item is an IP address, the port is recorded
-as ``port='xxxx'##'' inside the parentheses.
+cindex:[$sender_rcvhost$]
+This is provided specifically for use in 'Received:' headers. It starts with
+either the verified host name (as obtained from a reverse DNS lookup) or, if
+there is no verified host name, the IP address in square brackets. After that
+there may be text in parentheses. When the first item is a verified host name,
+the first thing in the parentheses is the IP address in square brackets,
+followed by a colon and a port number if port logging is enabled. When the
+first item is an IP address, the port is recorded as ``port='xxxx'##'' inside
+the parentheses.
 +
 There may also be items of the form ``helo='xxxx'##'' if HELO or EHLO
 was used and its argument was not identical to the real host name or IP
@@ -10414,23 +11059,45 @@ three items are present in the parentheses, a newline and tab are inserted into
 the string, to improve the formatting of the 'Received:' header.
 
 $sender_verify_failure$::
+cindex:[$sender_verify_failure$]
 In an ACL, when a sender verification fails, this variable contains information
 about the failure. The details are the same as for $recipient_verify_failure$.
 
 $smtp_active_hostname$::
+cindex:[$smtp_active_hostname$]
 During an SMTP session, this variable contains the value of the active host
 name, as specified by the %smtp_active_hostname% option. The value of
 $smtp_active_hostname$ is saved with any message that is received, so its value
 can be consulted during routing and delivery.
 
+$smtp_command$::
++
+[revisionflag="changed"]
+cindex:[$smtp_command$]
+During the processing of an incoming SMTP command, this variable contains the
+entire command. This makes it possible to distinguish between HELO and EHLO in
+the HELO ACL, and also to distinguish between commands such as these:
++
+....
+MAIL FROM:<>
+MAIL FROM: <>
+....
++
+For a MAIL command, extra parameters such as SIZE can be inspected. For a RCPT
+command, the address in $smtp_command$ is the original address before any
+rewriting, whereas the values in $local_part$ and $domain$ are taken from the
+address after SMTP-time rewriting.
+
 
 $smtp_command_argument$::
-cindex:[AUTH,argument]
-cindex:[EXPN,argument]
-cindex:[ETRN,argument]
-cindex:[VRFY,argument]
-While an ACL is running to check an AUTH, EHLO, EXPN, ETRN, HELO, or VRFY
-command, this variable contains the argument for the SMTP command.
++
+[revisionflag="changed"]
+cindex:[SMTP command,argument for]
+cindex:[$smtp_command_argument$]
+While an ACL is running to check an SMTP command, this variable contains the
+argument, that is, the text that follows the command name, with leading white
+space removed. Following the introduction of $smtp_command$, this variable is
+somewhat redundant, but is retained for backwards compatibility.
 
 $sn0$ -- $sn9$::
 These variables are copies of the values of the $n0$ -- $n9$ accumulators that
@@ -10446,15 +11113,18 @@ compiled with the content-scanning extension. For details, see section
 
 
 $spool_directory$::
+cindex:[$spool_directory$]
 The name of Exim's spool directory.
 
 $spool_inodes$::
+cindex:[$spool_inodes$]
 The number of free inodes in the disk partition where Exim's spool files are
 being written. The value is recalculated whenever the variable is referenced.
 If the relevant file system does not have the concept of inodes, the value of
 is -1. See also the %check_spool_inodes% option.
 
 $spool_space$::
+cindex:[$spool_space$]
 The amount of free space (as a number of kilobytes) in the disk partition where
 Exim's spool files are being written. The value is recalculated whenever the
 variable is referenced. If the operating system does not have the ability to
@@ -10468,14 +11138,19 @@ See also the %check_spool_space% option.
 
 
 $thisaddress$::
+cindex:[$thisaddress$]
 This variable is set only during the processing of the %foranyaddress% command
-in a filter file. Its use is explained in the description of that command.
+in a filter file. Its use is explained in the description of that command,
+which can be found in the separate document entitled 'Exim's interfaces to mail
+filtering'.
 
 $tls_certificate_verified$::
-This variable is set to ``1'' if a TLS certificate was verified when the message
-was received, and ``0'' otherwise.
+cindex:[$tls_certificate_verified$]
+This variable is set to ``1'' if a TLS certificate was verified when the
+message was received, and ``0'' otherwise.
 
 $tls_cipher$::
+cindex:[$tls_cipher$]
 When a message is received from a remote host over an encrypted SMTP
 connection, this variable is set to the cipher suite that was negotiated, for
 example DES-CBC3-SHA. In other circumstances, in particular, for message
@@ -10483,38 +11158,46 @@ received over unencrypted connections, the variable is empty. See chapter
 <<CHAPTLS>> for details of TLS support.
 
 $tls_peerdn$::
- When a message is received from a remote host over an encrypted SMTP
+cindex:[$tls_peerdn$]
+When a message is received from a remote host over an encrypted SMTP
 connection, and Exim is configured to request a certificate from the client,
 the value of the Distinguished Name of the certificate is made available in the
 $tls_peerdn$ during subsequent processing.
 
 $tod_bsdinbox$::
+cindex:[$tod_bsdinbox$]
 The time of day and date, in the format required for BSD-style mailbox files,
 for example: Thu Oct 17 17:14:09 1995.
 
 $tod_epoch$::
+cindex:[$tod_epoch$]
 The time and date as a number of seconds since the start of the Unix epoch.
 
 $tod_full$::
+cindex:[$tod_full$]
 A full version of the time and date, for example: Wed, 16 Oct 1995 09:51:40
 +0100. The timezone is always given as a numerical offset from UTC, with
 positive values used for timezones that are ahead (east) of UTC, and negative
 values for those that are behind (west).
 
 $tod_log$::
+cindex:[$tod_log$]
 The time and date in the format used for writing Exim's log files, for example:
 1995-10-12 15:32:29, but without a timezone.
 
 $tod_logfile$::
+cindex:[$tod_logfile$]
 This variable contains the date in the format yyyymmdd. This is the format that
 is used for datestamping log files when %log_file_path% contains the `%D`
 flag.
 
 $tod_zone$::
+cindex:[$tod_zone$]
 This variable contains the numerical value of the local timezone, for example:
 -0500.
 
 $tod_zulu$::
+cindex:[$tod_zulu$]
 This variable contains the UTC date and time in ``Zulu'' format, as specified by
 ISO 8601, for example: 20030221154023Z.
 
@@ -10524,13 +11207,16 @@ This variable contains the result of an expansion lookup, extraction operation,
 or external command, as described above.
 
 $version_number$::
+cindex:[$version_number$]
 The version number of Exim.
 
 $warn_message_delay$::
+cindex:[$warn_message_delay$]
 This variable is set only during the creation of a message warning about a
 delivery delay. Details of its use are explained in section <<SECTcustwarn>>.
 
 $warn_message_recipients$::
+cindex:[$warn_message_recipients$]
 This variable is set only during the creation of a message warning about a
 delivery delay. Details of its use are explained in section <<SECTcustwarn>>.
 
@@ -11095,6 +11781,7 @@ Data lookups
 %mysql_servers%                     as it says
 %oracle_servers%                    as it says
 %pgsql_servers%                     as it says
+%sqlite_lock_timeout%               as it says
 --------------------------------------------------------------------------
 
 
@@ -11124,6 +11811,8 @@ Daemon
 [frame="none"]
 `-----------------------------------`-------------------------------------
 %daemon_smtp_ports%                 default ports
+%daemon_startup_retries%            number of times to retry
+%daemon_startup_sleep%              time to sleep between tries
 %extra_local_interfaces%            not necessarily listened on
 %local_interfaces%                  on which to listen, with optional ports
 %pid_file_path%                     override compiled-in value
@@ -11164,22 +11853,25 @@ Policy controls
 ~~~~~~~~~~~~~~~
 [frame="none"]
 `-----------------------------------`-------------------------------------
-%acl_not_smtp%                      set ACL for non-SMTP messages
-%acl_smtp_auth%                     set ACL for AUTH
-%acl_smtp_connect%                  set ACL for connection
-%acl_smtp_data%                     set ACL for DATA
-%acl_smtp_etrn%                     set ACL for ETRN
-%acl_smtp_expn%                     set ACL for EXPN
-%acl_smtp_helo%                     set ACL for EHLO or HELO
-%acl_smtp_mail%                     set ACL for MAIL
-%acl_smtp_mailauth%                 set ACL for AUTH on MAIL command
-%acl_smtp_mime%                     set ACL for MIME parts
-%acl_smtp_predata%                  set ACL for start of data
-%acl_smtp_quit%                     set ACL for QUIT
-%acl_smtp_rcpt%                     set ACL for RCPT
-%acl_smtp_starttls%                 set ACL for STARTTLS
-%acl_smtp_vrfy%                     set ACL for VRFY
+%acl_not_smtp%                      ACL for non-SMTP messages
+%acl_not_smtp_mime%                 ACL for non-SMTP MIME parts
+%acl_smtp_auth%                     ACL for AUTH
+%acl_smtp_connect%                  ACL for connection
+%acl_smtp_data%                     ACL for DATA
+%acl_smtp_etrn%                     ACL for ETRN
+%acl_smtp_expn%                     ACL for EXPN
+%acl_smtp_helo%                     ACL for EHLO or HELO
+%acl_smtp_mail%                     ACL for MAIL
+%acl_smtp_mailauth%                 ACL for AUTH on MAIL command
+%acl_smtp_mime%                     ACL for MIME parts
+%acl_smtp_predata%                  ACL for start of data
+%acl_smtp_quit%                     ACL for QUIT
+%acl_smtp_rcpt%                     ACL for RCPT
+%acl_smtp_starttls%                 ACL for STARTTLS
+%acl_smtp_vrfy%                     ACL for VRFY
 %av_scanner%                        specify virus scanner
+%dns_csa_search_limit%              control CSA parent search depth
+%dns_csa_use_reverse%               en/disable CSA IP reverse search
 %header_maxsize%                    total size of message header
 %header_line_maxsize%               individual header line limit
 %helo_accept_junk_hosts%            allow syntactic junk from these hosts
@@ -11289,7 +11981,7 @@ See also the 'Policy controls' section above.
 %sender_unqualified_hosts%          may send unqualified senders
 %smtp_accept_keepalive%             some TCP/IP magic
 %smtp_accept_max%                   simultaneous incoming connections
-%smtp_accept_max_nommail%           non-mail commands
+%smtp_accept_max_nonmail%           non-mail commands
 %smtp_accept_max_nonmail_hosts%     hosts to which the limit applies
 %smtp_accept_max_per_connection%    messages per connection
 %smtp_accept_max_per_host%          connections from one host
@@ -11378,7 +12070,7 @@ Routing and delivery
 %local_interfaces%                  for routing checks
 %queue_domains%                     no immediate delivery for these
 %queue_only%                        no immediate delivery at all
-%queue_only_file%                   no immediate deliveryif file exists
+%queue_only_file%                   no immediate delivery if file exists
 %queue_only_load%                   no immediate delivery if load is high
 %queue_only_override%               allow command line to override
 %queue_run_in_order%                order of arrival
@@ -11407,6 +12099,7 @@ Bounce and warning messages
 %delay_warning%                     time schedule
 %delay_warning_condition%           condition for warning messages
 %ignore_bounce_errors_after%        discard undeliverable bounces
+%smtp_return_error_details%         give detail on rejections
 %warn_message_file%                 content of warning message
 --------------------------------------------------------------------------
 
@@ -11436,10 +12129,20 @@ oindex:[%acl_not_smtp%]
 ===
 
 cindex:[{ACL},for non-SMTP messages]
-cindex:[non-SMTP messages, ACL for]
+cindex:[non-SMTP messages, ACLs for]
 This option defines the ACL that is run when a non-SMTP message is on the point
 of being accepted. See chapter <<CHAPACL>> for further details.
 
+oindex:[%acl_not_smtp_mime%]
+`..'=
+%acl_not_smtp_mime%, Use: 'main', Type: 'string'!!, Default: 'unset'
+===
+
+[revisionflag="changed"]
+This option defines the ACL that is run for individual MIME parts of non-SMTP
+messages. It operates in exactly the same way as %acl_smtp_mime% operates for
+SMTP messages.
+
 oindex:[%acl_smtp_auth%]
 `..'=
 %acl_smtp_auth%, Use: 'main', Type: 'string'!!, Default: 'unset'
@@ -11574,12 +12277,14 @@ received. See chapter <<CHAPACL>> for further details.
 
 oindex:[%admin_groups%]
 `..'=
-%admin_groups%, Use: 'main', Type: 'string list', Default: 'unset'
+%admin_groups%, Use: 'main', Type: 'string list'!!, Default: 'unset'
 ===
 
+[revisionflag="changed"]
 cindex:[admin user]
-If the current group or any of the supplementary groups of the caller is in
-this colon-separated list, the caller has admin privileges. If all your system
+This option is expanded just once, at the start of Exim's processing. If the
+current group or any of the supplementary groups of an Exim caller is in this
+colon-separated list, the caller has admin privileges. If all your system
 programmers are in a specific group, for example, you can give them all Exim
 admin privileges by putting that group in %admin_groups%. However, this does
 not permit them to read Exim's spool files (whose group owner is the Exim gid).
@@ -11681,6 +12386,7 @@ option is expanded, with a setting like this:
 
   auth_advertise_hosts = ${if eq{$tls_cipher}{}{}{*}}
 
+cindex:[$tls_cipher$]
 If $tls_cipher$ is empty, the session is not encrypted, and the result of
 the expansion is empty, thus matching no hosts. Otherwise, the result of the
 expansion is \*, which matches all hosts.
@@ -11691,14 +12397,18 @@ oindex:[%auto_thaw%]
 %auto_thaw%, Use: 'main', Type: 'time', Default: '0s'
 ===
 
+[revisionflag="changed"]
 cindex:[thawing messages]
 cindex:[unfreezing messages]
 If this option is set to a time greater than zero, a queue runner will try a
-new delivery attempt on any frozen message if this much time has passed since
-it was frozen. This may result in the message being re-frozen if nothing has
-changed since the last attempt. It is a way of saying ``keep on trying, even
-though there are big problems''. See also %timeout_frozen_after% and
-%ignore_bounce_errors_after%.
+new delivery attempt on any frozen message, other than a bounce message, if
+this much time has passed since it was frozen. This may result in the message
+being re-frozen if nothing has changed since the last attempt. It is a way of
+saying ``keep on trying, even though there are big problems''.
+
+*Note*: This is an old option, which predates %timeout_frozen_after% and
+%ignore_bounce_errors_after%. It is retained for compatibility, but it is not
+thought to be very useful any more, and its use should probably be avoided.
 
 
 oindex:[%av_scanner%]
@@ -11901,11 +12611,14 @@ cindex:[spool directory,checking space]
 The four %check_...% options allow for checking of disk resources before a
 message is accepted.
 
+cindex:[$log_inodes$]
+cindex:[$log_space$]
+cindex:[$spool_inodes$]
+cindex:[$spool_space$]
 When any of these options are set, they apply to all incoming messages. If you
-want to apply different checks to different kinds of message, you can do so
-by testing the the variables $log_inodes$, $log_space$,
-$spool_inodes$, and $spool_space$ in an ACL with appropriate additional
-conditions.
+want to apply different checks to different kinds of message, you can do so by
+testing the the variables $log_inodes$, $log_space$, $spool_inodes$, and
+$spool_space$ in an ACL with appropriate additional conditions.
 
 
 %check_spool_space% and %check_spool_inodes% check the spool partition if
@@ -11947,6 +12660,26 @@ This option specifies one or more default SMTP ports on which the Exim daemon
 listens. See chapter <<CHAPinterfaces>> for details of how it is used. For
 backward compatibility, %daemon_smtp_port% (singular) is a synonym.
 
+oindex:[%daemon_startup_retries%]
+`..'=
+%daemon_startup_retries%, Use: 'main', Type: 'integer', Default: '9'
+===
+
+[revisionflag="changed"]
+cindex:[daemon startup,retrying]
+This option, along with %daemon_startup_sleep%, controls the retrying done by
+the daemon at startup when it cannot immediately bind a listening socket
+(typically because the socket is already in use): %daemon_startup_retries%
+defines the number of retries after the first failure, and
+%daemon_startup_sleep% defines the length of time to wait between retries.
+
+oindex:[%daemon_startup_sleep%]
+`..'=
+%daemon_startup_sleep%, Use: 'main', Type: 'time', Default: '30s'
+===
+
+[revisionflag="changed"]
+See %daemon_startup_retries%.
 
 oindex:[%delay_warning%]
 `..'=
@@ -11987,6 +12720,7 @@ oindex:[%delay_warning_condition%]
 %delay_warning_condition%, Use: 'main', Type: 'string'!!, Default: 'see below'
 ===
 
+cindex:[$domain$]
 The string is expanded at the time a warning message might be sent. If all the
 deferred addresses have the same domain, it is set in $domain$ during the
 expansion. Otherwise $domain$ is empty. If the result of the expansion is a
@@ -12086,6 +12820,26 @@ start or end with a hyphen.
 If you set %allow_utf8_domains%, you must modify this pattern, or set the
 option to an empty string.
 
+oindex:[%dns_csa_search_limit%]
+`..'=
+%dns_csa_search_limit%, Use: 'main', Type: 'integer', Default: '5'
+===
+
+[revisionflag="changed"]
+This option controls the depth of parental searching for CSA SRV records in the
+DNS, as described in more detail in section <<SECTverifyCSA>>.
+
+
+oindex:[%dns_csa_use_reverse%]
+`..'=
+%dns_csa_use_reverse%, Use: 'main', Type: 'boolean', Default: 'true'
+===
+
+[revisionflag="changed"]
+This option controls whether or not an IP address, given as a CSA domain, is
+reversed and looked up in the reverse DNS, as described in more detail in
+section <<SECTverifyCSA>>.
+
 
 oindex:[%dns_ipv4_lookup%]
 `..'=
@@ -12183,6 +12937,8 @@ errors_copy = spqr@mydomain   postmaster@mydomain.example :\
                               postmaster@mydomain.example
 ....
 
+cindex:[$domain$]
+cindex:[$local_part$]
 The address list is expanded before use. The expansion variables
 $local_part$ and $domain$ are set from the original recipient of the error
 message, and if there was any wildcard matching in the pattern, the expansion
@@ -12464,17 +13220,25 @@ oindex:[%helo_try_verify_hosts%]
 %helo_try_verify_hosts%, Use: 'main', Type: 'host list'!!, Default: 'unset'
 ===
 
+[revisionflag="changed"]
 cindex:[HELO verifying, optional]
 cindex:[EHLO verifying, optional]
-The RFCs mandate that a server must not reject a message because it doesn't
-like the HELO or EHLO command. By default, Exim just checks the syntax
-of these commands (see %helo_accept_junk_hosts% and %helo_allow_chars%
-above). However, some sites like to be stricter. If the calling host matches
-%helo_try_verify_hosts%, Exim checks that the host name given in the HELO
-or EHLO command either:
+By default, Exim just checks the syntax of HELO and EHLO commands (see
+%helo_accept_junk_hosts% and %helo_allow_chars%). However, some sites like to
+do more extensive checking of the data supplied by these commands. The ACL
+condition `verify = helo` is provided to make this possible. Formerly, it was
+necessary also to set this option (%helo_try_verify_hosts%) to force the check
+to occur. From release 4.53 onwards, this is no longer necessary. If the check
+has not been done before `verify = helo` is encountered, it is done at that
+time. Consequently, this option is obsolete. Its specification is retained here
+for backwards compatibility.
+
+[revisionflag="changed"]
+When an EHLO or HELO command is received, if the calling host matches
+%helo_try_verify_hosts%, Exim checks that the host name given in the HELO or
+EHLO command either:
 
-- is an IP literal matching the calling address of the host (the RFCs
-specifically allow this), or
+- is an IP literal matching the calling address of the host, or
 
 - cindex:[DNS,reverse lookup]
 cindex:[reverse DNS lookup]
@@ -12486,10 +13250,7 @@ available) yields the calling host address.
 
 However, the EHLO or HELO command is not rejected if any of the checks
 fail. Processing continues, but the result of the check is remembered, and can
-be detected later in an ACL by the `verify = helo` condition. If you want
-verification failure to cause rejection of EHLO or HELO, use
-%helo_verify_hosts% instead.
-
+be detected later in an ACL by the `verify = helo` condition.
 
 
 oindex:[%helo_verify_hosts%]
@@ -12497,15 +13258,15 @@ oindex:[%helo_verify_hosts%]
 %helo_verify_hosts%, Use: 'main', Type: 'host list'!!, Default: 'unset'
 ===
 
+[revisionflag="changed"]
 cindex:[HELO verifying, mandatory]
 cindex:[EHLO verifying, mandatory]
-For hosts that match this option, Exim checks the host name given in the
-HELO or EHLO in the same way as for %helo_try_verify_hosts%. If the
-check fails, the HELO or EHLO command is rejected with a 550 error, and
-entries are written to the main and reject logs. If a MAIL command is
-received before EHLO or HELO, it is rejected with a
-503
-error.
+Like %helo_try_verify_hosts%, this option is obsolete, and retained only for
+backwards compatibility. For hosts that match this option, Exim checks the host
+name given in the HELO or EHLO in the same way as for %helo_try_verify_hosts%.
+If the check fails, the HELO or EHLO command is rejected with a 550 error, and
+entries are written to the main and reject logs. If a MAIL command is received
+before EHLO or HELO, it is rejected with a 503 error.
 
 
 oindex:[%hold_domains%]
@@ -12555,6 +13316,8 @@ After a successful reverse lookup, Exim does a forward lookup on the name it
 has obtained, to verify that it yields the IP address that it started with. If
 this check fails, Exim behaves as if the name lookup failed.
 
+cindex:[$host_lookup_failed$]
+cindex:[$sender_host_name$]
 After any kind of failure, the host name (in $sender_host_name$) remains
 unset, and $host_lookup_failed$ is set to the string ``1''. See also
 %dns_again_means_nonexist%, %helo_lookup_domains%, and `verify =
@@ -12849,7 +13612,8 @@ When a message is submitted locally (that is, not over a TCP/IP connection) by
 an untrusted user, Exim removes any existing 'Sender:' header line. If you
 do not want this to happen, you must set %local_sender_retain%, and you must
 also set %local_from_check% to be false (Exim will complain if you do not).
-Section <<SECTthesenhea>> has more details about 'Sender:' processing.
+See also the ACL modifier `control = suppress_local_fixups`. Section
+<<SECTthesenhea>> has more details about 'Sender:' processing.
 
 
 
@@ -12861,6 +13625,7 @@ oindex:[%localhost_number%]
 
 cindex:[host,locally unique number for]
 cindex:[message ids, with multiple hosts]
+cindex:[$localhost_number$]
 Exim's message ids are normally unique only within the local host. If
 uniqueness among a set of hosts is required, each host must set a different
 value for the %localhost_number% option. The string is expanded immediately
@@ -12917,6 +13682,8 @@ oindex:[%log_timezone%]
 ===
 
 cindex:[log,timezone for entries]
+cindex:[$tod_log$]
+cindex:[$tod_zone$]
 By default, the timestamps on log lines are in local time without the
 timezone. This means that if your timezone changes twice a year, the timestamps
 in log lines are ambiguous for an hour when the clocks go back. One way of
@@ -12970,6 +13737,8 @@ oindex:[%message_body_visible%]
 
 cindex:[body of message,visible size]
 cindex:[message body, visible size]
+cindex:[$message_body$]
+cindex:[$message_body_end$]
 This option specifies how much of a message's body is to be included in the
 $message_body$ and $message_body_end$ expansion variables.
 
@@ -12996,17 +13765,16 @@ oindex:[%message_id_header_text%]
 ===
 
 If this variable is set, the string is expanded and used to augment the text of
-the 'Message-id:' header that Exim creates if a
-locally-originated
-incoming message does not have one. The text of this header is required by RFC
-2822 to take the form of an address. By default, Exim uses its internal message
-id as the local part, and the primary host name as the domain. If this option
-is set, it is expanded, and provided the expansion is not forced to fail, and
-does not yield an empty string, the result is inserted into the header
-immediately before the @, separated from the internal message id by a dot. Any
-characters that are illegal in an address are automatically converted into
-hyphens. This means that variables such as $tod_log$ can be used, because
-the spaces and colons will become hyphens.
+the 'Message-id:' header that Exim creates if a locally-originated incoming
+message does not have one. The text of this header is required by RFC 2822 to
+take the form of an address. By default, Exim uses its internal message id as
+the local part, and the primary host name as the domain. If this option is set,
+it is expanded, and provided the expansion is not forced to fail, and does not
+yield an empty string, the result is inserted into the header immediately
+before the @, separated from the internal message id by a dot. Any characters
+that are illegal in an address are automatically converted into hyphens. This
+means that variables such as $tod_log$ can be used, because the spaces and
+colons will become hyphens.
 
 
 oindex:[%message_logs%]
@@ -13090,10 +13858,12 @@ option is available only if Exim has been built with MySQL support.
 
 oindex:[%never_users%]
 `..'=
-%never_users%, Use: 'main', Type: 'string list', Default: 'unset'
+%never_users%, Use: 'main', Type: 'string list'!!, Default: 'unset'
 ===
 
-Local message deliveries are normally run in processes that are setuid to the
+[revisionflag="changed"]
+This option is expanded just once, at the start of Exim's processing. Local
+message deliveries are normally run in processes that are setuid to the
 recipient, and remote deliveries are normally run under Exim's own uid and gid.
 It is usually desirable to prevent any deliveries from running as root, as a
 safety precaution.
@@ -13235,18 +14005,19 @@ oindex:[%primary_hostname%]
 cindex:[name,of local host]
 cindex:[host,name of local]
 cindex:[local host,name of]
-This specifies the name of the current host. It is used in the default EHLO
-or HELO command for outgoing SMTP messages (changeable via the %helo_data%
-option in the ^smtp^ transport),
-and as the default for %qualify_domain%. If it is not set, Exim calls
-'uname()' to find it. If this fails, Exim panics and dies. If the name
-returned by 'uname()' contains only one component, Exim passes it to
-'gethostbyname()' (or 'getipnodebyname()' when available) in order to
-obtain the fully qualified version.
+cindex:[$primary_hostname$]
+This specifies the name of the current host. It is used in the default EHLO or
+HELO command for outgoing SMTP messages (changeable via the %helo_data% option
+in the ^smtp^ transport), and as the default for %qualify_domain%. The value is
+also used by default in some SMTP response messages from an Exim server. This
+can be changed dynamically by setting %smtp_active_hostname%.
 
-The value of $primary_hostname$ is also used by default in some SMTP
-response messages from an Exim server. This can be changed dynamically by
-setting %smtp_active_hostname%.
+If %primary_hostname% is not set, Exim calls 'uname()' to find the host name.
+If this fails, Exim panics and dies. If the name returned by 'uname()' contains
+only one component, Exim passes it to 'gethostbyname()' (or 'getipnodebyname()'
+when available) in order to obtain the fully qualified version. The variable
+$primary_hostname$ contains the host name, whether set explicitly by this
+option, or defaulted.
 
 
 oindex:[%print_topbitchars%]
@@ -13459,6 +14230,12 @@ very large queues and/or very sluggish deliveries. This option does not,
 however, interlock with other processes, so additional queue runners can be
 started by other means, or by killing and restarting the daemon.
 
+[revisionflag="changed"]
+Setting this option to zero does not suppress queue runs; rather, it disables
+the limit, allowing any number of simultaneous queue runner processes to be
+run. If you do not want queue runs to occur, omit the %-q%'xx' setting on the
+daemon's command line.
+
 
 oindex:[%queue_smtp_domains%]
 `..'=
@@ -13515,7 +14292,7 @@ received_header_text = Received: \
     ${if def:received_protocol {with $received_protocol}} \
     ${if def:tls_cipher {($tls_cipher)\n\t}}\
     (Exim $version_number)\n\t\
-    id $message_id\
+    id $message_exim_id\
     ${if def:received_for {\n\tfor $received_for}}
 ....
 
@@ -13919,17 +14696,18 @@ oindex:[%smtp_active_hostname%]
 
 cindex:[host,name in SMTP responses]
 cindex:[SMTP,host name in responses]
+cindex:[$primary_hostname$]
 This option is provided for multi-homed servers that want to masquerade as
 several different hosts. At the start of an SMTP connection, its value is
 expanded and used instead of the value of $primary_hostname$ in SMTP
 responses. For example, it is used as domain name in the response to an
 incoming HELO or EHLO command.
 
-It is also used in HELO commands for callout verification.
-The active hostname is placed in the $smtp_active_hostname$ variable, which
-is saved with any messages that are received. It is therefore available for use
-in routers and transports when the message is later delivered.
-
+cindex:[$smtp_active_hostname$]
+It is also used in HELO commands for callout verification. The active hostname
+is placed in the $smtp_active_hostname$ variable, which is saved with any
+messages that are received. It is therefore available for use in routers and
+transports when the message is later delivered.
 
 If this option is unset, or if its expansion is forced to fail, or if the
 expansion results in an empty string, the value of $primary_hostname$ is
@@ -14034,6 +14812,7 @@ oindex:[%smtp_etrn_command%]
 ===
 
 cindex:[ETRN,command to be run]
+cindex:[$domain$]
 If this option is set, the given command is run whenever an SMTP ETRN
 command is received from a host that is permitted to issue such commands (see
 chapter <<CHAPACL>>). The string is split up into separate arguments which are
@@ -14304,6 +15083,16 @@ as failures in the configuration file.
 By using this option to override the compiled-in path, it is possible to run
 tests of Exim without using the standard spool.
 
+oindex:[%sqlite_lock_timeout%]
+`..'=
+%sqlite_lock_timeout%, Use: 'main', Type: 'time', Default: '5s'
+===
+
+[revisionflag="changed"]
+cindex:[sqlite,lock timeout]
+This option controls the timeout that the ^sqlite^ lookup uses when trying to
+access an SQLite database. See section <<SECTsqlite>> for more details.
+
 
 oindex:[%strip_excess_angle_brackets%]
 `..'=
@@ -14410,6 +15199,7 @@ oindex:[%system_filter_directory_transport%]
 %system_filter_directory_transport%, Use: 'main', Type: 'string'!!, Default: 'unset'
 ===
 
+cindex:[$address_file$]
 This sets the name of the transport driver that is to be used when the
 %save% command in a system message filter specifies a path ending in ``/'',
 implying delivery of each message into a separate file in some directory.
@@ -14442,6 +15232,7 @@ oindex:[%system_filter_pipe_transport%]
 ===
 
 cindex:[^pipe^ transport,for system filter]
+cindex:[$address_pipe$]
 This specifies the transport driver that is to be used when a %pipe% command is
 used in a system filter. During the delivery, the variable $address_pipe$
 contains the pipe command.
@@ -14700,32 +15491,34 @@ certificates.
 
 oindex:[%trusted_groups%]
 `..'=
-%trusted_groups%, Use: 'main', Type: 'string list', Default: 'unset'
+%trusted_groups%, Use: 'main', Type: 'string list'!!, Default: 'unset'
 ===
 
+[revisionflag="changed"]
 cindex:[trusted group]
 cindex:[group,trusted]
-If this option is set, any process that is running in one of the listed groups,
-or which has one of them as a supplementary group, is trusted.
-The groups can be specified numerically or by name.
-See section <<SECTtrustedadmin>> for details of what trusted callers are
-permitted to do. If neither %trusted_groups% nor %trusted_users% is set, only
-root and the Exim user are trusted.
+This option is expanded just once, at the start of Exim's processing. If this
+option is set, any process that is running in one of the listed groups, or
+which has one of them as a supplementary group, is trusted. The groups can be
+specified numerically or by name. See section <<SECTtrustedadmin>> for details
+of what trusted callers are permitted to do. If neither %trusted_groups% nor
+%trusted_users% is set, only root and the Exim user are trusted.
 
 
 oindex:[%trusted_users%]
 `..'=
-%trusted_users%, Use: 'main', Type: 'string list', Default: 'unset'
+%trusted_users%, Use: 'main', Type: 'string list'!!, Default: 'unset'
 ===
 
+[revisionflag="changed"]
 cindex:[trusted user]
 cindex:[user,trusted]
-If this option is set, any process that is running as one of the listed users
-is trusted.
-The users can be specified numerically or by name.
-See section <<SECTtrustedadmin>> for details of what trusted callers are
-permitted to do. If neither %trusted_groups% nor %trusted_users% is set, only
-root and the Exim user are trusted.
+This option is expanded just once, at the start of Exim's processing. If this
+option is set, any process that is running as one of the listed users is
+trusted. The users can be specified numerically or by name. See section
+<<SECTtrustedadmin>> for details of what trusted callers are permitted to do.
+If neither %trusted_groups% nor %trusted_users% is set, only root and the Exim
+user are trusted.
 
 oindex:[%unknown_login%]
 `..'=
@@ -14733,6 +15526,7 @@ oindex:[%unknown_login%]
 ===
 
 cindex:[uid (user id),unknown caller]
+cindex:[$caller_uid$]
 This is a specialized feature for use in unusual configurations. By default, if
 the uid of the caller of Exim cannot be looked up using 'getpwuid()', Exim
 gives up. The %unknown_login% option can be used to set a login name to be
@@ -14771,6 +15565,7 @@ to declare that a message should never generate any bounces. For example:
 
   exim -f '<>' user@domain.example
 
+cindex:[$sender_ident$]
 The %untrusted_set_sender% option allows you to permit untrusted users to set
 other envelope sender addresses in a controlled way. When it is set, untrusted
 users are allowed to set envelope sender addresses that match any of the
@@ -14827,8 +15622,8 @@ The pattern can be seen by running
 It checks only up to the hours and minutes, and allows for a 2-digit or 4-digit
 year in the second case. The first word after ``From'' is matched in the regular
 expression by a parenthesized subpattern. The default value for
-%uucp_from_sender% is ``$1'', which therefore just uses this first word (``ph10''
-in the example above) as the message's sender. See also
+%uucp_from_sender% is ``$1'', which therefore just uses this first word
+(``ph10'' in the example above) as the message's sender. See also
 %ignore_fromline_hosts%.
 
 
@@ -14890,22 +15685,24 @@ oindex:[%address_data%]
 %address_data%, Use: 'routers', Type: 'string'!!, Default: 'unset'
 ===
 
+[revisionflag="changed"]
 cindex:[router,data attached to address]
 The string is expanded just before the router is run, that is, after all the
 precondition tests have succeeded. If the expansion is forced to fail, the
-router declines. Other expansion failures cause delivery of the address to be
-deferred.
+router declines, the value of %address_data% remains unchanged, and the %more%
+option controls what happens next. Other expansion failures cause delivery of
+the address to be deferred.
 
+cindex:[$address_data$]
 When the expansion succeeds, the value is retained with the address, and can be
 accessed using the variable $address_data$ in the current router, subsequent
 routers, and the eventual transport.
 
 *Warning*: if the current or any subsequent router is a ^redirect^ router
-that runs a user's filter file, the contents of $address_data$ are
-accessible in the filter. This is not normally a problem, because such data is
-usually either not confidential or it ``belongs'' to the current user, but if you
-do put confidential data into $address_data$ you need to remember this
-point.
+that runs a user's filter file, the contents of $address_data$ are accessible
+in the filter. This is not normally a problem, because such data is usually
+either not confidential or it ``belongs'' to the current user, but if you do
+put confidential data into $address_data$ you need to remember this point.
 
 Even if the router declines or passes, the value of $address_data$ remains
 with the address, though it can be changed by another %address_data% setting
@@ -14929,8 +15726,10 @@ lookups (though Exim does cache lookups).
 The %address_data% facility is also useful as a means of passing information
 from one router to another, and from a router to a transport. In addition, if
 
-$address_data$ is set by a router when verifying a recipient address from an
-ACL, it remains available for use in the rest of the ACL statement. After
+cindex:[$sender_address_data$]
+cindex:[$address_data$]
+When $address_data$ is set by a router when verifying a recipient address from
+an ACL, it remains available for use in the rest of the ACL statement. After
 verifying a sender, the value is transferred to $sender_address_data$.
 
 
@@ -14992,6 +15791,9 @@ this option true. For individual router options that contain address or local
 part lists (for example, %local_parts%), case-sensitive matching can be turned
 on by ``+caseful'' as a list item. See section <<SECTcasletadd>> for more details.
 
+cindex:[$local_part$]
+cindex:[$original_local_part$]
+cindex:[$parent_local_part$]
 The value of the $local_part$ variable is forced to lower case while a
 router is running unless %caseful_local_part% is set. When a router assigns
 an address to a transport, the value of $local_part$ when the transport runs
@@ -15014,6 +15816,7 @@ oindex:[%check_local_user%]
 cindex:[local user, checking in router]
 cindex:[router,checking for local user]
 cindex:[_/etc/passwd_]
+cindex:[$home$]
 When this option is true, Exim checks that the local part of the recipient
 address (with affixes removed if relevant) is the name of an account on the
 local system. The check is done by calling the 'getpwnam()' function rather
@@ -15108,12 +15911,12 @@ oindex:[%domains%]
 ===
 
 cindex:[router,restricting to specific domains]
+cindex:[$domain_data$]
 If this option is set, the router is skipped unless the current domain matches
 the list. If the match is achieved by means of a file lookup, the data that the
 lookup returned for the domain is placed in $domain_data$ for use in string
-expansions of the driver's private options.
-See section <<SECTrouprecon>> for a list of the order in which preconditions
-are evaluated.
+expansions of the driver's private options. See section <<SECTrouprecon>> for a
+list of the order in which preconditions are evaluated.
 
 
 
@@ -15170,6 +15973,7 @@ no longer gives rise to a bounce message; the error is discarded. If the
 address is delivered to a remote host, the return path is set to `<>`, unless
 overridden by the %return_path% option on the transport.
 
+cindex:[$address_data$]
 If for some reason you want to discard local errors, but use a non-empty
 MAIL command for remote delivery, you can preserve the original return
 path in $address_data$ in the router, and reinstate it in the transport by
@@ -15235,14 +16039,21 @@ oindex:[%fallback_hosts%]
 %fallback_hosts%, Use: 'routers', Type: 'string list', Default: 'unset'
 ===
 
+[revisionflag="changed"]
 cindex:[router,fallback hosts]
 cindex:[fallback,hosts specified on router]
 String expansion is not applied to this option. The argument must be a
-colon-separated list of host names or IP addresses. If a router queues an
-address for a remote transport, this host list is associated with the address,
-and used instead of the transport's fallback host list. If %hosts_randomize%
-is set on the transport, the order of the list is randomized for each use. See
-the %fallback_hosts% option of the ^smtp^ transport for further details.
+colon-separated list of host names or IP addresses. The list separator can be
+changed (see section <<SECTlistconstruct>>), and a port can be specified with
+each name or address. In fact, the format of each item is exactly the same as
+defined for the list of hosts in a ^manualroute^ router (see section
+<<SECTformatonehostitem>>).
+
+If a router queues an address for a remote transport, this host list is
+associated with the address, and used instead of the transport's fallback host
+list. If %hosts_randomize% is set on the transport, the order of the list is
+randomized for each use. See the %fallback_hosts% option of the ^smtp^
+transport for further details.
 
 
 oindex:[%group%]
@@ -15283,9 +16094,13 @@ The %headers_add% option is expanded after %errors_to%, but before
 expansion is forced to fail, the option has no effect. Other expansion failures
 are treated as configuration errors.
 
-*Warning*: The %headers_add% option cannot be used for a ^redirect^
+*Warning 1*: The %headers_add% option cannot be used for a ^redirect^
 router that has the %one_time% option set.
 
+[revisionflag="changed"]
+*Warning 2*: If the %unseen% option is set on the router, all header additions
+are deleted when the address is passed on to subsequent routers.
+
 
 
 
@@ -15306,9 +16121,12 @@ The %headers_remove% option is expanded after %errors_to% and %headers_add%,
 but before %transport%. If the expansion is forced to fail, the option has no
 effect. Other expansion failures are treated as configuration errors.
 
-*Warning*: The %headers_remove% option cannot be used for a ^redirect^
+*Warning 1*: The %headers_remove% option cannot be used for a ^redirect^
 router that has the %one_time% option set.
 
+[revisionflag="changed"]
+*Warning 2*: If the %unseen% option is set on the router, all header removal
+requests are deleted when the address is passed on to subsequent routers.
 
 
 
@@ -15344,6 +16162,7 @@ addresses. Because, like all host lists, the value of %ignore_target_hosts%
 is expanded before use as a list, it is possible to make it dependent on the
 domain that is being routed.
 
+cindex:[$host_address$]
 During its expansion, $host_address$ is set to the IP address that is being
 checked.
 
@@ -15371,32 +16190,38 @@ oindex:[%local_part_prefix%]
 
 cindex:[router,prefix for local part]
 cindex:[prefix,for local part; used in router]
-If this option is set, the router is skipped unless the local part
-starts with one of the given strings, or %local_part_prefix_optional% is
-true.
-See section <<SECTrouprecon>> for a list of the order in which preconditions
-are evaluated.
+If this option is set, the router is skipped unless the local part starts with
+one of the given strings, or %local_part_prefix_optional% is true. See section
+<<SECTrouprecon>> for a list of the order in which preconditions are evaluated.
 
 The list is scanned from left to right, and the first prefix that matches is
 used. A limited form of wildcard is available; if the prefix begins with an
 asterisk, it matches the longest possible sequence of arbitrary characters at
 the start of the local part. An asterisk should therefore always be followed by
 some character that does not occur in normal local parts.
-
 cindex:[multiple mailboxes]
 cindex:[mailbox,multiple]
 Wildcarding can be used to set up multiple user mailboxes, as described in
 section <<SECTmulbox>>.
 
+[revisionflag="changed"]
+cindex:[$local_part$]
+cindex:[$local_part_prefix$]
 During the testing of the %local_parts% option, and while the router is
 running, the prefix is removed from the local part, and is available in the
-expansion variable $local_part_prefix$. If the router accepts the address,
-this remains true during subsequent delivery.
-In particular, the local part that is transmitted in the RCPT command
-for LMTP, SMTP, and BSMTP deliveries has the prefix removed by default. This
-behaviour can be overridden by setting %rcpt_include_affixes% true on the
+expansion variable $local_part_prefix$. When a message is being delivered, if
+the router accepts the address, this remains true during subsequent delivery by
+a transport. In particular, the local part that is transmitted in the RCPT
+command for LMTP, SMTP, and BSMTP deliveries has the prefix removed by default.
+This behaviour can be overridden by setting %rcpt_include_affixes% true on the
 relevant transport.
 
+[revisionflag="changed"]
+When an address is being verified, %local_part_prefix% affects only the
+behaviour of the router. If the callout feature of verification is in use, this
+means that the full address, including the prefix, will be used during the
+callout.
+
 The prefix facility is commonly used to handle local parts of the form
 %owner-something%. Another common use is to support local parts of the form
 %real-username% to bypass a user's _.forward_ file -- helpful when trying to
@@ -15465,6 +16290,7 @@ example:
 
   local_parts = dbm;/usr/local/specials/$domain
 
+cindex:[$local_part_data$]
 If the match is achieved by a lookup, the data that the lookup returned
 for the local part is placed in the variable $local_part_data$ for use in
 expansions of the router's private options. You might use this option, for
@@ -15506,12 +16332,10 @@ result causes an error, and delivery is deferred. If the expansion is forced to
 fail, the default value for the option (true) is used. Other failures cause
 delivery to be deferred.
 
-If this option is set false, and the router is run, but declines to handle the
-address, no further routers are tried, routing fails, and the address is
-bounced.
-cindex:[%self% option]
-However, if the router explicitly passes an address to the following router by
-means of the setting
+If this option is set false, and the router declines to handle the address, no
+further routers are tried, routing fails, and the address is bounced.
+cindex:[%self% option] However, if the router explicitly passes an address to
+the following router by means of the setting
 
   self = pass
 
@@ -15519,6 +16343,11 @@ or otherwise, the setting of %more% is ignored. Also, the setting of %more%
 does not affect the behaviour if one of the precondition tests fails. In that
 case, the address is always passed to the next router.
 
+[revisionflag="changed"]
+Note that %address_data% is not considered to be a precondition. If its
+expansion is forced to fail, the router declines, and the value of %more%
+controls what happens next.
+
 
 
 oindex:[%pass_on_timeout%]
@@ -15697,6 +16526,7 @@ oindex:[%router_home_directory%]
 
 cindex:[router,home directory for]
 cindex:[home directory,for router]
+cindex:[$home$]
 This option sets a home directory for use while the router is running. (Compare
 %transport_home_directory%, which sets a home directory for later
 transporting.) In particular, if used on a ^redirect^ router, this option
@@ -15774,6 +16604,7 @@ The router passes the address to the next router, or to the router named in the
 cindex:[%more% option]
 This overrides %no_more%.
 +
+cindex:[$self_hostname$]
 During subsequent routing and delivery, the variable $self_hostname$ contains
 the name of the local host that the router encountered. This can be used to
 distinguish between different cases for hosts with multiple names. The
@@ -15836,6 +16667,7 @@ is inadequate or broken. Because this is an extremely uncommon requirement, the
 code to support this option is not included in the Exim binary unless
 SUPPORT_TRANSLATE_IP_ADDRESS=yes is set in _Local/Makefile_.
 
+cindex:[$host_address$]
 The %translate_ip_address% string is expanded for every IP address generated
 by the router, with the generated address set in $host_address$. If the
 expansion is forced to fail, no action is taken.
@@ -15932,11 +16764,11 @@ oindex:[%unseen%]
 
 cindex:[router,carrying on after success]
 The result of string expansion for this option must be a valid boolean value,
-that is, one of the strings ``yes'', ``no'', ``true'', or ``false''. Any other result
-causes an error, and delivery is deferred. If the expansion is forced to fail,
-the default value for the option (false) is used. Other failures cause delivery
-to be deferred.
-
+that is, one of the strings ``yes'', ``no'', ``true'', or ``false''. Any other
+result causes an error, and delivery is deferred. If the expansion is forced to
+fail, the default value for the option (false) is used. Other failures cause
+delivery to be deferred.
+
 When this option is set true, routing does not cease if the router accepts the
 address. Instead, a copy of the incoming address is passed to the next router,
 overriding a false setting of %more%. There is little point in setting %more%
@@ -15944,21 +16776,22 @@ false if %unseen% is always true, but it may be useful in cases when the value
 of %unseen% contains expansion items (and therefore, presumably, is sometimes
 true and sometimes false).
 
+[revisionflag="changed"]
 cindex:[copy of message (%unseen% option)]
 The %unseen% option can be used to cause copies of messages to be delivered to
 some other destination, while also carrying out a normal delivery. In effect,
 the current address is made into a ``parent'' that has two children -- one that
 is delivered as specified by this router, and a clone that goes on to be routed
-further.
-
-Header lines added to the address (or specified for removal) by this router or
-by previous routers affect the ``unseen'' copy of the message only. The clone
-that continues to be processed by further routers starts with no added headers
-and none specified for removal.
+further. For this reason, %unseen% may not be combined with the %one_time%
+option in a ^redirect^ router.
 
-However, any data that was set by the %address_data% option in the current or
-previous routers is passed on. Setting this option has a similar effect to the
-%unseen% command qualifier in filter files.
+*Warning*: Header lines added to the address (or specified for removal) by this
+router or by previous routers affect the ``unseen'' copy of the message only.
+The clone that continues to be processed by further routers starts with no
+added headers and none specified for removal. However, any data that was set by
+the %address_data% option in the current or previous routers is passed on.
+Setting the %unseen% option has a similar effect to the %unseen% command
+qualifier in filter files.
 
 
 
@@ -16345,6 +17178,10 @@ is set and a lookup of 'klingon.dictionary' fails,
 and %search_parents% options can cause some widening to be undertaken inside
 the DNS resolver.
 
+[revisionflag="changed"]
+%widen_domains% is not applied to sender addresses when verifying, unless
+%rewrite_headers% is false (not the default).
+
 
 
 Effect of qualify_single and search_parents
@@ -16560,6 +17397,7 @@ include a transport. The combination of a pattern and its data is called a
 generic %transport% option must specify a transport, unless the router is being
 used purely for verification (see %verify_only%).
 
+cindex:[$host$]
 In the case of verification, matching the domain pattern is sufficient for the
 router to accept the address. When actually routing an address for delivery,
 an address that matches a domain pattern is queued for the associated
@@ -16695,7 +17533,9 @@ Routing rules in route_list
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~
 The value of %route_list% is a string consisting of a sequence of routing
 rules, separated by semicolons. If a semicolon is needed in a rule, it can be
-entered as two semicolons. Empty rules are ignored. The format of each rule is
+entered as two semicolons. Alternatively, the list separator can be changed as
+described (for colon-separated lists) in section <<SECTlistconstruct>>.
+Empty rules are ignored. The format of each rule is
 
   <domain pattern>  <list of hosts>  <options>
 
@@ -16754,17 +17594,24 @@ be enclosed in quotes if it contains white space.
 
 Format of the list of hosts
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~
+[revisionflag="changed"]
 A list of hosts, whether obtained via %route_data% or %route_list%, is always
 separately expanded before use. If the expansion fails, the router declines.
 The result of the expansion must be a colon-separated list of names and/or
-IP addresses. IP addresses are not enclosed in brackets.
+IP addresses, optionally also including ports. The format of each item in the
+list is described in the next section. The list separator can be changed as
+described in section <<SECTlistconstruct>>.
 
 If the list of hosts was obtained from a %route_list% item, the following
 variables are set during its expansion:
 
 - cindex:[numerical variables ($1$ $2$  etc),in ^manualroute^ router]
 If the domain was matched against a regular expression, the numeric variables
-$1$, $2$, etc. may be set.
+$1$, $2$, etc. may be set. For example:
+
+....
+      route_list = ^domain(\d+)   host-$1.text.example
+....
 
 - $0$ is always set to the entire domain.
 
@@ -16772,11 +17619,46 @@ $1$, $2$, etc. may be set.
 
 - cindex:[$value$]
 If the pattern that matched the domain was a lookup item, the data that was
-looked up is available in the expansion variable $value$.
+looked up is available in the expansion variable $value$. For example:
+
+....
+      route_list = lsearch;;/some/file.routes  $value
+....
+
+Note the doubling of the semicolon in the pattern that is necessary because
+semicolon is the default route list separator.
+
+
+
+[[SECTformatonehostitem]]
+Format of one host item
+~~~~~~~~~~~~~~~~~~~~~~~
+[revisionflag="changed"]
+Each item in the list of hosts is either a host name or an IP address,
+optionally with an attached port number. When no port is given, an IP address
+is not enclosed in brackets. When a port is specified, it overrides the port
+specification on the transport. The port is separated from the name or address
+by a colon. This leads to some complications:
 
+[revisionflag="changed"]
+- Because colon is the default separator for the list of hosts, either
+the colon that specifies a port must be doubled, or the list separator must
+be changed. The following two examples have the same effect:
++
+  route_list = * "host1.tld::1225 : host2.tld::1226"
+  route_list = * "<+ host1.tld:1225 + host2.tld:1226"
+
+[revisionflag="changed"]
+- When IPv6 addresses are involved, it gets worse, because they contain
+colons of their own. To make this case easier, it is permitted to
+enclose an IP address (either v4 or v6) in square brackets if a port
+number follows. For example:
++
+  route_list = * "</ [10.1.1.1]:1225 / [::1]:1226"
 
 
 
+[[SECThostshowused]]
 How the list of hosts is used
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 When an address is routed to an ^smtp^ transport by ^manualroute^, each of
@@ -16792,6 +17674,12 @@ records in the DNS. For example:
 
   route_list = *  x.y.z:p.q.r/MX:e.f.g
 
+[revisionflag="changed"]
+If this feature is used with a port specifier, the port must come last. For
+example:
+
+     route_list = *  dom1.tld/mx::1225
+
 If the %hosts_randomize% option is set, the order of the items in the list is
 randomized before any lookups are done. Exim then scans the list; for any name
 that is not followed by `/MX` it looks up an IP address. If this turns out to
@@ -16879,6 +17767,7 @@ function called.
 If no IP address for a host can be found, what happens is controlled by the
 %host_find_failed% option.
 
+cindex:[$host$]
 When an address is routed to a local transport, IP addresses are not looked up.
 The host list is passed to the transport in the $host$ variable.
 
@@ -16986,6 +17875,8 @@ save_in_file:
       batch_pipe
 ....
 +
+cindex:[$domain$]
+cindex:[$host$]
 The first of these just passes the domain in the $host$ variable, which
 doesn't achieve much (since it is also in $domain$), but the second does a
 file lookup to find a value to pass, causing the router to decline to handle
@@ -17142,9 +18033,10 @@ The list of hosts and the lookup type are needed only if the transport is an
 ^smtp^ transport that does not itself supply a list of hosts.
 
 The format of the list of hosts is the same as for the ^manualroute^ router.
-As well as host names and IP addresses, it may contain names followed by
-`/MX` to specify sublists of hosts that are obtained by looking up MX
-records.
+As well as host names and IP addresses with optional port numbers, as described
+in section <<SECTformatonehostitem>>, it may contain names followed by `/MX` to
+specify sublists of hosts that are obtained by looking up MX records (see
+section <<SECThostshowused>>).
 
 If the lookup type is not specified, Exim behaves as follows when trying to
 find an IP address for each host: First, a DNS lookup is done. If this yields
@@ -17152,6 +18044,7 @@ anything other than HOST_NOT_FOUND, that result is used. Otherwise, Exim
 goes on to try a call to 'getipnodebyname()' or 'gethostbyname()', and the
 result of the lookup is the result of that call.
 
+cindex:[$address_data$]
 If the DATA field is set, its value is placed in the $address_data$
 variable. For example, this return line
 
@@ -17304,17 +18197,19 @@ next newline character is ignored.
 
 If an item is entirely enclosed in double quotes, these are removed. Otherwise
 double quotes are retained because some forms of mail address require their use
-(but never to enclose the entire address). In the following description, ``item''
-refers to what remains after any surrounding double quotes have been removed.
+(but never to enclose the entire address). In the following description,
+``item'' refers to what remains after any surrounding double quotes have been
+removed.
 
+cindex:[$local_part$]
 *Warning*: If you use an Exim expansion to construct a redirection address,
 and the expansion contains a reference to $local_part$, you should make use
-of the %quote% expansion operator, in case the local part contains special
-characters. For example, to redirect all mail for the domain
+of the %quote_local_part% expansion operator, in case the local part contains
+special characters. For example, to redirect all mail for the domain
 'obsolete.example', retaining the existing local part, you could use this
 setting:
 
-  data = ${quote:$local_part}@newdomain.example
+  data = ${quote_local_part:$local_part}@newdomain.example
 
 
 
@@ -17496,6 +18391,7 @@ default.
 cindex:[EXPN error text, display of]
 The text is not included in the response to an EXPN command.
 +
+cindex:[$acl_verify_message$]
 In an ACL, an explicitly provided message overrides the default, but the
 default message is available in the variable $acl_verify_message$ and can
 therefore be included in a custom message if this is desired. Exim sends a 451
@@ -17763,12 +18659,12 @@ oindex:[%file_transport%]
 %file_transport%, Use: 'redirect', Type: 'string'!!, Default: 'unset'
 ===
 
+cindex:[$address_file$]
 A ^redirect^ router sets up a direct delivery to a file when a path name not
 ending in a slash is specified as a new ``address''. The transport used is
 specified by this option, which, after expansion, must be the name of a
-configured transport.
-This should normally be an ^appendfile^ transport.
-When it is running, the file name is in $address_file$.
+configured transport. This should normally be an ^appendfile^ transport. When
+it is running, the file name is in $address_file$.
 
 
 oindex:[%forbid_blackhole%]
@@ -17806,14 +18702,27 @@ set. It applies to Sieve filters as well as to Exim filters, but if true, it
 locks out the Sieve's ``keep'' facility.
 
 
+oindex:[%forbid_filter_dlfunc%]
+`..'=
+%forbid_filter_dlfunc%, Use: 'redirect', Type: 'boolean', Default: 'false'
+===
+
+[revisionflag="changed"]
+cindex:[filter,locking out certain features]
+If this option is true, string expansions in Exim filters are not allowed to
+make use of the %dlfunc% expansion facility to run dynamically loaded
+functions.
+
+
 oindex:[%forbid_filter_existstest%]
 `..'=
 %forbid_filter_existstest%, Use: 'redirect', Type: 'boolean', Default: 'false'
 ===
 
-cindex:[filter,locking out certain features]
+[revisionflag="changed"]
+cindex:[expansion,statting a file]
 If this option is true, string expansions in Exim filters are not allowed to
-make use of the %exists% condition.
+make use of the %exists% condition or the %stat% expansion item.
 
 
 oindex:[%forbid_filter_logwrite%]
@@ -17841,7 +18750,7 @@ oindex:[%forbid_filter_perl%]
 %forbid_filter_perl%, Use: 'redirect', Type: 'boolean', Default: 'false'
 ===
 
-This option is available only if Exim is built with embedded Perl support. If
+This option has an effect only if Exim is built with embedded Perl support. If
 it is true, string expansions in Exim filter files are not allowed to make use
 of the embedded Perl support.
 
@@ -17994,29 +18903,32 @@ cindex:[forward file,one-time expansion]
 cindex:[mailing lists,one-time expansion]
 cindex:[address redirection,one-time expansion]
 Sometimes the fact that Exim re-evaluates aliases and reprocesses redirection
-files each time it tries to deliver a message causes a problem
-when one or more of the generated addresses fails be delivered at the first
-attempt. The problem is not one of duplicate delivery -- Exim is clever enough
-to handle that -- but of what happens when the redirection list changes during
-the time that the message is on Exim's queue. This is particularly true in the
-case of mailing lists, where new subscribers might receive copies of messages
-that were posted before they subscribed.
-
-If %one_time% is set and any addresses generated by the router fail to
-deliver at the first attempt, the failing addresses are added to the message as
-``top level'' addresses, and the parent address that generated them is marked
-``delivered''. Thus, redirection does not happen again at the next
-delivery attempt.
+files each time it tries to deliver a message causes a problem when one or more
+of the generated addresses fails be delivered at the first attempt. The problem
+is not one of duplicate delivery -- Exim is clever enough to handle that -- but
+of what happens when the redirection list changes during the time that the
+message is on Exim's queue. This is particularly true in the case of mailing
+lists, where new subscribers might receive copies of messages that were posted
+before they subscribed.
+
+If %one_time% is set and any addresses generated by the router fail to deliver
+at the first attempt, the failing addresses are added to the message as ``top
+level'' addresses, and the parent address that generated them is marked
+``delivered''. Thus, redirection does not happen again at the next delivery
+attempt.
 
-*Warning 1*: This means that any header line addition or removal that is
-specified by this router would be lost if delivery did not succeed at the
-first attempt. For this reason, the %headers_add% and %headers_remove%
-generic options are not permitted when %one_time% is set.
+*Warning 1*: Any header line addition or removal that is specified by this
+router would be lost if delivery did not succeed at the first attempt. For this
+reason, the %headers_add% and %headers_remove% generic options are not
+permitted when %one_time% is set.
 
 *Warning 2*: To ensure that the router generates only addresses (as opposed
 to pipe or file deliveries or auto-replies) %forbid_file%, %forbid_pipe%,
 and %forbid_filter_reply% are forced to be true when %one_time% is set.
 
+[revisionflag="changed"]
+*Warning 3*: The %unseen% generic router option may not be set with %one_time%.
+
 The original top-level address is remembered with each of the generated
 addresses, and is output in any log messages. However, any intermediate parent
 addresses are not recorded. This makes a difference to the log only if
@@ -18054,12 +18966,12 @@ oindex:[%pipe_transport%]
 %pipe_transport%, Use: 'redirect', Type: 'string'!!, Default: 'unset'
 ===
 
+cindex:[$address_pipe$]
 A ^redirect^ router sets up a direct delivery to a pipe when a string starting
 with a vertical bar character is specified as a new ``address''. The transport
 used is specified by this option, which, after expansion, must be the name of a
-configured transport.
-This should normally be a ^pipe^ transport.
-When the transport is run, the pipe command is in $address_pipe$.
+configured transport. This should normally be a ^pipe^ transport. When the
+transport is run, the pipe command is in $address_pipe$.
 
 
 oindex:[%qualify_domain%]
@@ -18067,6 +18979,7 @@ oindex:[%qualify_domain%]
 %qualify_domain%, Use: 'redirect', Type: 'string'!!, Default: 'unset'
 ===
 
+cindex:[$qualify_recipient$]
 If this option is set and an unqualified address (one without a domain) is
 generated, it is qualified with the domain specified by expanding this string,
 instead of the global setting in %qualify_recipient%. If the expansion fails,
@@ -18123,17 +19036,40 @@ subject to address rewriting. Otherwise, they are treated like new addresses
 and are rewritten according to the global rewriting rules.
 
 
+oindex:[%sieve_subaddress%]
+`..'=
+%sieve_subaddress%, Use: 'redirect', Type: 'string'!!, Default: 'unset'
+===
+
+[revisionflag="changed"]
+The value of this option is passed to a Sieve filter to specify the
+:subaddress part of an address.
+
+
+oindex:[%sieve_useraddress%]
+`..'=
+%sieve_useraddress%, Use: 'redirect', Type: 'string'!!, Default: 'unset'
+===
+
+[revisionflag="changed"]
+The value of this option is passed to a Sieve filter to specify the :user part
+of an address. However, if it is unset, the entire original local part
+(including any prefix or suffix) is used for :user.
+
+
 
 oindex:[%sieve_vacation_directory%]
 `..'=
 %sieve_vacation_directory%, Use: 'redirect', Type: 'string'!!, Default: 'unset'
 ===
 
+[revisionflag="changed"]
 cindex:[Sieve filter,vacation directory]
 To enable the ``vacation'' extension for Sieve filters, you must set
 %sieve_vacation_directory% to the directory where vacation databases are held
 (do not put anything else in that directory), and ensure that the
-%reply_transport% option refers to an ^autoreply^ transport.
+%reply_transport% option refers to an ^autoreply^ transport. Each user needs
+their own directory; Exim will create it if necessary.
 
 
 
@@ -18367,13 +19303,16 @@ directory to _/_ before running a local transport.
 
 Expansion variables derived from the address
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+cindex:[$domain$]
+cindex:[$local_part$]
+cindex:[$original_domain$]
 Normally a local delivery is handling a single address, and in that case the
-variables such as $domain$ and $local_part$ are set during local
-deliveries. However, in some circumstances more than one address may be handled
-at once (for example, while writing batch SMTP for onward transmission by some
-other means). In this case, the variables associated with the local part are
-never set, $domain$ is set only if all the addresses have the same
-domain, and $original_domain$ is never set.
+variables such as $domain$ and $local_part$ are set during local deliveries.
+However, in some circumstances more than one address may be handled at once
+(for example, while writing batch SMTP for onward transmission by some other
+means). In this case, the variables associated with the local part are never
+set, $domain$ is set only if all the addresses have the same domain, and
+$original_domain$ is never set.
 
 
 
@@ -18579,6 +19518,7 @@ oindex:[%home_directory%]
 ===
 
 cindex:[transport,home directory for]
+cindex:[$home$]
 This option specifies a home directory setting for the transport, overriding
 any value that may be set by the router. The home directory is placed in
 $home$ while expanding the transport's private options. It is also used as
@@ -18644,6 +19584,10 @@ is delivered with
 
   RCPT TO:<xyz@some.domain>
 
+[revisionflag="changed"]
+This is also the case when an ACL-time callout is being used to verify a
+recipient address.
+
 If %rcpt_include_affixes% is set true, the whole local part is included in
 the RCPT command. This option applies to BSMTP deliveries by the
 ^appendfile^ and ^pipe^ transports as well as to the ^lmtp^ and ^smtp^
@@ -18690,6 +19634,7 @@ SMTP MAIL command. If you set %return_path% for a local transport, the
 only effect is to change the address that is placed in the 'Return-path:'
 header line, if one is added to the message (see the next option).
 
+cindex:[$return_path$]
 The expansion can refer to the existing value via $return_path$. This is
 either the message's envelope sender, or an address set by the
 %errors_to% option on a router. If the expansion is forced to fail, no
@@ -18778,29 +19723,35 @@ at transport time. It should not be confused with mail filtering as set up by
 individual users or via a system filter.
 
 When the message is about to be written out, the command specified by
-%transport_filter% is started up in a separate process, and the entire
-message, including the header lines, is passed to it on its standard input
-(this in fact is done from a third process, to avoid deadlock).
-The command must be specified as an absolute path.
+%transport_filter% is started up in a separate process, and the entire message,
+including the header lines, is passed to it on its standard input (this in fact
+is done from a third process, to avoid deadlock). The command must be specified
+as an absolute path.
 
 The lines of the message that are written to the transport filter are
-terminated by newline (``\n'').
-
-The message is passed to the filter before any SMTP-specific processing, such
-as turning ``\n'' into ``\r\n'' and escaping lines beginning with a dot, and
-also before any processing implied by the settings of %check_string% and
-%escape_string% in the ^appendfile^ or ^pipe^ transports.
+terminated by newline (``\n''). The message is passed to the filter before any
+SMTP-specific processing, such as turning ``\n'' into ``\r\n'' and escaping
+lines beginning with a dot, and also before any processing implied by the
+settings of %check_string% and %escape_string% in the ^appendfile^ or ^pipe^
+transports.
 
 The standard error for the filter process is set to the same destination as its
 standard output; this is read and written to the message's ultimate
-destination.
+destination. The filter can perform any transformations it likes, but of course
+should take care not to break RFC 2822 syntax. A demonstration Perl script is
+provided in _util/transport-filter.pl_; this makes a few arbitrary
+modifications just to show the possibilities. Exim does not check the result,
+except to test for a final newline when SMTP is in use. All messages
+transmitted over SMTP must end with a newline, so Exim supplies one if it is
+missing.
 
-The filter can perform any transformations it likes, but of course should take
-care not to break RFC 2822 syntax. A demonstration Perl script is provided in
-_util/transport-filter.pl_; this makes a few arbitrary modifications just to
-show the possibilities. Exim does not check the result, except to test for a
-final newline when SMTP is in use. All messages transmitted over SMTP must end
-with a newline, so Exim supplies one if it is missing.
+[revisionflag="changed"]
+cindex:[content scanning,per user]
+A transport filter can be used to provide content-scanning on a per-user basis
+at delivery time if the only required effect of the scan is to modify the
+message. For example, a content scan could insert a new header line containing
+a spam score. This could be interpreted by a filter in the user's MUA. It is
+not possible to discard a message at this stage.
 
 cindex:[SMTP,SIZE]
 A problem might arise if the filter increases the size of a message that is
@@ -18811,6 +19762,7 @@ more, the server might reject the message. This can be worked round by setting
 the %size_addition% option on the ^smtp^ transport, either to allow for
 additions to the message, or to disable the use of SIZE altogether.
 
+cindex:[$pipe_addresses$]
 The value of the %transport_filter% option is the command string for starting
 the filter, which is run directly from Exim, not under a shell. The string is
 parsed by Exim in the same way as a command string for the ^pipe^ transport:
@@ -18850,10 +19802,15 @@ oindex:[%transport_filter_timeout%]
 %transport_filter_timeout%, Use: 'transports', Type: 'time', Default: '5m'
 ===
 
+[revisionflag="changed"]
 cindex:[transport filter, timeout]
 When Exim is reading the output of a transport filter, it a applies a timeout
-that can be set by this option. Exceeding the timeout is treated as a
-temporary delivery failure.
+that can be set by this option. Exceeding the timeout is normally treated as a
+temporary delivery failure. However, if a transport filter is used with a
+^pipe^ transport, a timeout in the transport filter is treated in the same way
+as a timeout in the pipe command itself. By default, a timeout is a hard error,
+but if the ^pipe^ transport's %timeout_defer% option is set true, it becomes a
+temporary error.
 
 
 
@@ -18929,10 +19886,12 @@ When more than one address is routed to a transport that has a %batch_max%
 value greater than one, the addresses are delivered in a batch (that is, in a
 single run of the transport), subject to certain conditions:
 
-- If any of the transport's options contain a reference to $local_part$, no
+- cindex:[$local_part$]
+If any of the transport's options contain a reference to $local_part$, no
 batching is possible.
 
-- If any of the transport's options contain a reference to $domain$, only
+- cindex:[$domain$]
+If any of the transport's options contain a reference to $domain$, only
 addresses with the same domain are batched.
 
 - cindex:[customizing,batching condition]
@@ -18965,6 +19924,7 @@ given in section <<SECTbatchSMTP>>. The ^lmtp^ transport does not have a
 %use_bsmtp% option, because it always delivers using the SMTP protocol.
 
 cindex:[^pipe^ transport,with multiple addresses]
+cindex:[$pipe_addresses$]
 If you are not using BSMTP, but are using a ^pipe^ transport, you can include
 $pipe_addresses$ as part of the command. This is not a true variable; it is
 a bit of magic that causes each of the recipient addresses to be inserted into
@@ -19033,6 +19993,8 @@ the %directory% option specifies a directory, in which a new file containing
 the message is created. Only one of these two options can be set, and for
 normal deliveries to mailboxes, one of them 'must' be set.
 
+cindex:[$address_file$]
+cindex:[$local_part$]
 However, ^appendfile^ is also used for delivering messages to files or
 directories whose names (or parts of names) are obtained from alias,
 forwarding, or filtering operations (for example, a %save% command in a user's
@@ -19262,6 +20224,7 @@ oindex:[%directory_file%]
 ===
 
 cindex:[base62]
+cindex:[$inode$]
 When %directory% is set, but neither %maildir_format% nor %mailstore_format%
 is set, ^appendfile^ delivers each message into a file whose name is obtained
 by expanding this string. The default value generates a unique name from the
@@ -19703,16 +20666,21 @@ become quite noticeable, especially on systems that have large block sizes.
 Nevertheless, it seems best to stick to the 'used' figure, because this is
 the obvious value which users understand most easily.
 
+[revisionflag="changed"]
 The value of the option is expanded, and must then be a numerical value
-(decimal point allowed), optionally followed by one of the letters K or M. The
-expansion happens while Exim is running as root, before it changes uid for the
-delivery. This means that files which are inaccessible to the end user can be
-used to hold quota values that are looked up in the expansion. When delivery
-fails because this quota is exceeded, the handling of the error is as for
-system quota failures.
+(decimal point allowed), optionally followed by one of the letters K, M, or G,
+for kilobytes, megabytes, or gigabytes. If Exim is running on a system with
+large file support (Linux and FreeBSD have this), mailboxes larger than 2G can
+be handled.
 
 *Note*: A value of zero is interpreted as ``no quota''.
 
+The expansion happens while Exim is running as root, before it changes uid for
+the delivery. This means that files that are inaccessible to the end user can
+be used to hold quota values that are looked up in the expansion. When delivery
+fails because this quota is exceeded, the handling of the error is as for
+system quota failures.
+
 By default, Exim's quota checking mimics system quotas, and restricts the
 mailbox to the specified maximum size, though the value is not accurate to the
 last byte, owing to separator lines and additional headers that may get added
@@ -19775,11 +20743,16 @@ the file length to the file name. For example:
   maildir_tag = ,S=$message_size
   quota_size_regex = ,S=(\d+)
 
+[revisionflag="changed"]
+An alternative to $message_size$ is $message_linecount$, which contains the
+number of lines in the message.
+
 The regular expression should not assume that the length is at the end of the
 file name (even though %maildir_tag% puts it there) because maildir MUAs
 sometimes add other information onto the ends of message file names.
 
 
+
 oindex:[%quota_warn_message%]
 `..'=
 %quota_warn_message%, Use: 'appendfile', Type: 'string'!!, Default: 'see below'
@@ -19822,11 +20795,16 @@ For example:
 If %quota% is not set, a setting of %quota_warn_threshold% that ends with a
 percent sign is ignored.
 
+[revisionflag="changed"]
 The warning message itself is specified by the %quota_warn_message% option,
-and it must start with a 'To:' header line containing the recipient(s). A
-'Subject:' line should also normally be supplied. The %quota% option does not
-have to be set in order to use this option; they are independent of one
-another except when the threshold is specified as a percentage.
+and it must start with a 'To:' header line containing the recipient(s) of the
+warning message. These do not necessarily have to include the recipient(s) of
+the original message. A 'Subject:' line should also normally be supplied. You
+can include any other header lines that you want.
+
+The %quota% option does not have to be set in order to use this option; they
+are independent of one another except when the threshold is specified as a
+percentage.
 
 
 oindex:[%use_bsmtp%]
@@ -20170,12 +21148,13 @@ tag is added to its name. However, if adding the tag takes the length of the
 name to the point where the test 'stat()' call fails with ENAMETOOLONG,
 the tag is dropped and the maildir file is created with no tag.
 
+cindex:[$message_size$]
 Tags can be used to encode the size of files in their names; see
-%quota_size_regex% above for an example. The expansion of %maildir_tag%
-happens after the message has been written. The value of the $message_size$
-variable is set to the number of bytes actually written. If the expansion is
-forced to fail, the tag is ignored, but a non-forced failure causes delivery to
-be deferred. The expanded tag may contain any printing characters except ``/''.
+%quota_size_regex% above for an example. The expansion of %maildir_tag% happens
+after the message has been written. The value of the $message_size$ variable is
+set to the number of bytes actually written. If the expansion is forced to
+fail, the tag is ignored, but a non-forced failure causes delivery to be
+deferred. The expanded tag may contain any printing characters except ``/''.
 Non-printing characters in the string are ignored; if the resulting string is
 empty, it is ignored. If it starts with an alphanumeric character, a leading
 colon is inserted.
@@ -20216,7 +21195,8 @@ If the %mailstore_format% option is true, each message is written as two files
 in the given directory. A unique base name is constructed from the message id
 and the current delivery process, and the files that are written use this base
 name plus the suffixes _.env_ and _.msg_. The _.env_ file contains the
-message's envelope, and the _.msg_ file contains the message itself.
+message's envelope, and the _.msg_ file contains the message itself. The base
+name is placed in the variable $mailstore_basename$.
 
 During delivery, the envelope is first written to a file with the suffix
 _.tmp_. The _.msg_ file is then written, and when it is complete, the
@@ -20232,9 +21212,11 @@ There can be more than one recipient only if the %batch_max% option is set
 greater than one. Finally, %mailstore_suffix% is expanded and the result
 appended to the file, followed by a newline if it does not end with one.
 
+[revisionflag="changed"]
 If expansion of %mailstore_prefix% or %mailstore_suffix% ends with a forced
 failure, it is ignored. Other expansion errors are treated as serious
-configuration errors, and delivery is deferred.
+configuration errors, and delivery is deferred. The variable
+$mailstore_basename$ is available for use during these expansions.
 
 
 
@@ -20306,7 +21288,7 @@ message is generated for each address that is passed to it.
 
 Non-printing characters are not permitted in the header lines generated for the
 message that ^autoreply^ creates, with the exception of newlines that are
-immediately followed by whitespace. If any non-printing characters are found,
+immediately followed by white space. If any non-printing characters are found,
 the transport defers.
 Whether characters with the top bit set count as printing characters or not is
 controlled by the %print_topbitchars% global option.
@@ -20316,6 +21298,7 @@ If any of the generic options for manipulating headers (for example,
 the original message that is included in the generated message when
 %return_message% is set. They do not apply to the generated message itself.
 
+cindex:[$sender_address$]
 If the ^autoreply^ transport receives return code 2 from Exim when it submits
 the message, indicating that there were no recipients, it does not treat this
 as an error. This means that autoreplies sent to $sender_address$ when this
@@ -20577,12 +21560,23 @@ oindex:[%command%]
 %command%, Use: 'lmtp', Type: 'string'!!, Default: 'unset'
 ===
 
-This option must be set if %socket% is not set.
-The string is a command which is run in a separate process. It is split up into
-a command name and list of arguments, each of which is separately expanded (so
-expansion cannot change the number of arguments). The command is run directly,
-not via a shell. The message is passed to the new process using the standard
-input and output to operate the LMTP protocol.
+This option must be set if %socket% is not set. The string is a command which
+is run in a separate process. It is split up into a command name and list of
+arguments, each of which is separately expanded (so expansion cannot change the
+number of arguments). The command is run directly, not via a shell. The message
+is passed to the new process using the standard input and output to operate the
+LMTP protocol.
+
+oindex:[%ignore_quota%]
+`..'=
+%ignore_quota%, Use: 'lmtp', Type: 'boolean', Default: 'false'
+===
+
+[revisionflag="changed"]
+cindex:[LMTP,ignoring quota errors]
+If this option is set true, the string `IGNOREQUOTA` is added to RCPT commands,
+provided that the LMTP server has advertised support for IGNOREQUOTA in its
+response to the LHLO command.
 
 
 oindex:[%socket%]
@@ -20635,18 +21629,21 @@ delivery mechanism (such as UUCP). Another is the use by individual users to
 automatically process their incoming messages. The ^pipe^ transport can be
 used in one of the following ways:
 
-- A router routes one address to a transport in the normal way, and the transport
-is configured as a ^pipe^ transport. In this case, $local_part$ contains
-the local part of the address (as usual), and the command that is run is
-specified by the %command% option on the transport.
+- cindex:[$local_part$]
+A router routes one address to a transport in the normal way, and the
+transport is configured as a ^pipe^ transport. In this case, $local_part$
+contains the local part of the address (as usual), and the command that is run
+is specified by the %command% option on the transport.
 
-- If the %batch_max% option is set greater than 1 (the default), the transport
+- cindex:[$pipe_addresses$]
+If the %batch_max% option is set greater than 1 (the default), the transport
 can be called upon to handle more than one address in a single run. In this
 case, $local_part$ is not set (because it is not unique). However, the
 pseudo-variable $pipe_addresses$ (described in section <<SECThowcommandrun>>
 below) contains all the addresses that are being handled.
 
-- A router redirects an address directly to a pipe command (for example, from an
+- cindex:[$address_pipe$]
+A router redirects an address directly to a pipe command (for example, from an
 alias or forward file). In this case, $local_part$ contains the local part
 that was redirected, and $address_pipe$ contains the text of the pipe
 command itself. The %command% option on the transport is ignored.
@@ -20657,11 +21654,11 @@ deliver messages over pipes using the LMTP interactive protocol. This is
 implemented by the ^lmtp^ transport.
 
 In the case when ^pipe^ is run as a consequence of an entry in a local user's
-_.forward_ file, the command runs under the uid and gid of that user. In
-other cases, the uid and gid have to be specified explicitly, either on the
-transport or on the router that handles the address. Current and ``home''
-directories are also controllable. See chapter <<CHAPenvironment>> for details of
-the local delivery environment.
+_.forward_ file, the command runs under the uid and gid of that user. In other
+cases, the uid and gid have to be specified explicitly, either on the transport
+or on the router that handles the address. Current and ``home'' directories are
+also controllable. See chapter <<CHAPenvironment>> for details of the local
+delivery environment.
 
 
 
@@ -20739,6 +21736,7 @@ interact with external quoting.
 
 cindex:[transport,filter]
 cindex:[filter,transport filter]
+cindex:[$pipe_addresses$]
 Special handling takes place when an argument consists of precisely the text
 `\$pipe_addresses\}`. This is not a general expansion variable; the only
 place this string is recognized is when it appears as an argument for a pipe or
@@ -20787,7 +21785,7 @@ environment.
 `LOCAL_PART_PREFIX `   see below
 `LOCAL_PART_SUFFIX `   see below
 `LOGNAME           `   see below
-`MESSAGE_ID        `   the message's id
+`MESSAGE_ID        `   Exim's local ID for the message
 `PATH              `   as specified by the %path% option below
 `QUALIFY_DOMAIN    `   the sender qualification domain
 `RECIPIENT         `   the complete recipient address
@@ -20934,11 +21932,13 @@ oindex:[%ignore_status%]
 
 If this option is true, the status returned by the subprocess that is set up to
 run the command is ignored, and Exim behaves as if zero had been returned.
-Otherwise, a non-zero status
-or termination by signal
-causes an error return from the transport unless the status value is one of
-those listed in %temp_errors%; these cause the delivery to be deferred and
-tried again later.
+Otherwise, a non-zero status or termination by signal causes an error return
+from the transport unless the status value is one of those listed in
+%temp_errors%; these cause the delivery to be deferred and tried again later.
+
+[revisionflag="changed"]
+*Note*: This option does not apply to timeouts, which do not return a status.
+See the %timeout_defer% option for how timeouts are handled.
 
 
 oindex:[%log_defer_output%]
@@ -21034,7 +22034,7 @@ The suffix can be suppressed by setting
 
 oindex:[%path%]
 `..'=
-%path%, Use: 'pipe', Type: 'string', Default: `/usr/bin`
+%path%, Use: 'pipe', Type: 'string', Default: `/bin:/usr/bin`
 ===
 
 This option specifies the string that is set up in the PATH environment
@@ -21126,11 +22126,23 @@ oindex:[%timeout%]
 ===
 
 If the command fails to complete within this time, it is killed. This normally
-causes the delivery to fail. A zero time interval specifies no timeout. In
-order to ensure that any subprocesses created by the command are also killed,
-Exim makes the initial process a process group leader, and kills the whole
-process group on a timeout. However, this can be defeated if one of the
-processes starts a new process group.
+causes the delivery to fail (but see %timeout_defer%). A zero time interval
+specifies no timeout. In order to ensure that any subprocesses created by the
+command are also killed, Exim makes the initial process a process group leader,
+and kills the whole process group on a timeout. However, this can be defeated
+if one of the processes starts a new process group.
+
+oindex:[%timeout_defer%]
+`..'=
+%timeout_defer%, Use: 'pipe', Type: 'boolean', Default: 'false'
+===
+
+[revisionflag="changed"]
+A timeout in a ^pipe^ transport, either in the command that the transport runs,
+or in a transport filter that is associated with it, is by default treated as a
+hard error, and the delivery fails. However, if %timeout_defer% is set true,
+both kinds of timeout become temporary errors, causing the delivery to be
+deferred.
 
 
 oindex:[%umask%]
@@ -21179,6 +22191,7 @@ oindex:[%use_shell%]
 %use_shell%, Use: 'pipe', Type: 'boolean', Default: 'false'
 ===
 
+cindex:[$pipe_addresses$]
 If this option is set, it causes the command to be passed to _/bin/sh_
 instead of being run directly from the transport, as described in section
 <<SECThowcommandrun>>. This is less secure, but is needed in some situations
@@ -21479,15 +22492,21 @@ oindex:[%fallback_hosts%]
 %fallback_hosts%, Use: 'smtp', Type: 'string list', Default: 'unset'
 ===
 
+[revisionflag="changed"]
 cindex:[fallback,hosts specified on transport]
 String expansion is not applied to this option. The argument must be a
-colon-separated list of host names or IP addresses. Fallback hosts can also be
-specified on routers, which associate them with the addresses they process. As
-for the %hosts% option without %hosts_override%, %fallback_hosts% specified
-on the transport is used only if the address does not have its own associated
-fallback host list. Unlike %hosts%, a setting of %fallback_hosts% on an
-address is not overridden by %hosts_override%. However, %hosts_randomize%
-does apply to fallback host lists.
+colon-separated list of host names or IP addresses, optionally also including
+port numbers, though the separator can be changed, as described in section
+<<SECTlistconstruct>>. Each individual item in the list is the same as an item
+in a %route_list% setting for the ^manualroute^ router, as described in section
+<<SECTformatonehostitem>>.
+
+Fallback hosts can also be specified on routers, which associate them with the
+addresses they process. As for the %hosts% option without %hosts_override%,
+%fallback_hosts% specified on the transport is used only if the address does
+not have its own associated fallback host list. Unlike %hosts%, a setting of
+%fallback_hosts% on an address is not overridden by %hosts_override%. However,
+%hosts_randomize% does apply to fallback host lists.
 
 If Exim is unable to deliver to any of the hosts for a particular address, and
 the errors are not permanent rejections, the address is put on a separate
@@ -21544,23 +22563,33 @@ oindex:[%hosts%]
 ===
 
 Hosts are associated with an address by a router such as ^dnslookup^, which
-finds the hosts by looking up the address domain in the DNS. However, addresses
-can be passed to the ^smtp^ transport by any router, and not all of them can
-provide an associated host list. The %hosts% option specifies a list of hosts
-which are used if the address being processed does not have any hosts
-associated with it. The hosts specified by %hosts% are also used, whether or
-not the address has its own hosts, if %hosts_override% is set.
+finds the hosts by looking up the address domain in the DNS, or by
+^manualroute^, which has lists of hosts in its configuration. However,
+email addresses can be passed to the ^smtp^ transport by any router, and not
+all of them can provide an associated list of hosts.
+
+The %hosts% option specifies a list of hosts to be used if the address being
+processed does not have any hosts associated with it. The hosts specified by
+%hosts% are also used, whether or not the address has its own hosts, if
+%hosts_override% is set.
 
+[revisionflag="changed"]
 The string is first expanded, before being interpreted as a colon-separated
-list of host names or IP addresses. If the expansion fails, delivery is
-deferred. Unless the failure was caused by the inability to complete a lookup,
-the error is logged to the panic log as well as the main log. Host names are
-looked up either by searching directly for address records in the DNS or by
-calling 'gethostbyname()'
-(or 'getipnodebyname()' when available),
-depending on the setting of the %gethostbyname% option. When Exim is compiled
-with IPv6 support, if a host that is looked up in the DNS has both IPv4 and
-IPv6 addresses, both types of address are used.
+list of host names or IP addresses, possibly including port numbers. The
+separator may be changed to something other than colon, as described in section
+<<SECTlistconstruct>>. Each individual item in the list is the same as an item
+in a %route_list% setting for the ^manualroute^ router, as described in section
+<<SECTformatonehostitem>>. However, note that the `/MX` facility of the
+^manualroute^ router is not available here.
+
+If the expansion fails, delivery is deferred. Unless the failure was caused by
+the inability to complete a lookup, the error is logged to the panic log as
+well as the main log. Host names are looked up either by searching directly for
+address records in the DNS or by calling 'gethostbyname()' (or
+'getipnodebyname()' when available), depending on the setting of the
+%gethostbyname% option. When Exim is compiled with IPv6 support, if a host that
+is looked up in the DNS has both IPv4 and IPv6 addresses, both types of address
+are used.
 
 During delivery, the hosts are tried in order, subject to their retry status,
 unless %hosts_randomize% is set.
@@ -21713,6 +22742,8 @@ oindex:[%interface%]
 
 cindex:[bind IP address]
 cindex:[IP address,binding]
+cindex:[$host$]
+cindex:[$host_address$]
 This option specifies which interface to bind to when making an outgoing SMTP
 call. The variables $host$ and $host_address$ refer to the host to which a
 connection is about to be made during the expansion of the string. Forced
@@ -21747,6 +22778,18 @@ call properly. The keepalive mechanism takes several hours to detect
 unreachable hosts.
 
 
+oindex:[%lmtp_ignore_quota%]
+`..'=
+%lmtp_ignore_quota%, Use: 'smtp', Type: 'boolean', Default: 'false'
+===
+
+[revisionflag="changed"]
+cindex:[LMTP,ignoring quota errors]
+If this option is set true when the %protocol% option is set to ``lmtp'', the
+string `IGNOREQUOTA` is added to RCPT commands, provided that the LMTP server
+has advertised support for IGNOREQUOTA in its response to the LHLO command.
+
+
 oindex:[%max_rcpt%]
 `..'=
 %max_rcpt%, Use: 'smtp', Type: 'integer', Default: '100'
@@ -21764,6 +22807,7 @@ oindex:[%multi_domain%]
 %multi_domain%, Use: 'smtp', Type: 'boolean', Default: 'true'
 ===
 
+cindex:[$domain$]
 When this option is set, the ^smtp^ transport can handle a number of addresses
 containing a mixture of different domains provided they all resolve to the same
 list of hosts. Turning the option off restricts the transport to handling only
@@ -21875,6 +22919,8 @@ oindex:[%tls_certificate%]
 
 cindex:[TLS client certificate, location of]
 cindex:[certificate for client, location of]
+cindex:[$host$]
+cindex:[$host_address$]
 The value of this option must be the absolute path to a file which contains the
 client's certificate, for use when sending a message over an encrypted
 connection. The values of $host$ and $host_address$ are set to the name
@@ -21904,6 +22950,8 @@ oindex:[%tls_privatekey%]
 ===
 
 cindex:[TLS client private key, location of]
+cindex:[$host$]
+cindex:[$host_address$]
 The value of this option must be the absolute path to a file which contains the
 client's private key, for use when sending a message over an encrypted
 connection. The values of $host$ and $host_address$ are set to the name
@@ -21920,6 +22968,8 @@ oindex:[%tls_require_ciphers%]
 
 cindex:[TLS,requiring specific ciphers]
 cindex:[cipher,requiring specific]
+cindex:[$host$]
+cindex:[$host_address$]
 The value of this option must be a list of permitted cipher suites, for use
 when setting up an outgoing encrypted connection. (There is a global option of
 the same name for controlling incoming connections.) The values of $host$ and
@@ -21954,6 +23004,8 @@ oindex:[%tls_verify_certificates%]
 
 cindex:[TLS,server certificate verification]
 cindex:[certificate,verification of server]
+cindex:[$host$]
+cindex:[$host_address$]
 The value of this option must be the absolute path to a file containing
 permitted server certificates, for use when setting up an encrypted connection.
 Alternatively, if you are using OpenSSL, you can set
@@ -22115,6 +23167,7 @@ cindex:[{ACL},rewriting addresses in]
 Configured address rewriting can take place at several different stages of a
 message's processing.
 
+cindex:[$sender_address$]
 At the start of an ACL for MAIL, the sender address may have been rewritten
 by a special SMTP-time rewrite rule (see section <<SECTrewriteS>>), but no
 ordinary rewrite rules have yet been applied. If, however, the sender address
@@ -22124,6 +23177,8 @@ rewritten address. This also applies if sender verification happens in a
 RCPT ACL. Otherwise, when the sender address is not verified, it is
 rewritten as soon as a message's header lines have been received.
 
+cindex:[$domain$]
+cindex:[$local_part$]
 Similarly, at the start of an ACL for RCPT, the current recipient's address
 may have been rewritten by a special SMTP-time rewrite rule, but no ordinary
 rewrite rules have yet been applied to it. However, the behaviour is different
@@ -22218,6 +23273,8 @@ address in 'To:' must not assume that the message's address in 'From:' has (or
 has not) already been rewritten. However, a rewrite of 'From:' may assume that
 the envelope sender has already been rewritten.
 
+cindex:[$domain$]
+cindex:[$local_part$]
 The variables $local_part$ and $domain$ can be used in the replacement
 string to refer to the address that is being rewritten. Note that lookup-driven
 rewriting can be done by a rule of the form
@@ -22235,7 +23292,9 @@ cindex:[address list,in a rewriting pattern]
 The source pattern in a rewriting rule is any item which may appear in an
 address list (see section <<SECTaddresslist>>). It is in fact processed as a
 single-item address list, which means that it is expanded before being tested
-against the address.
+against the address. As always, if you use a regular expression as a pattern,
+you must take care to escape dollar and backslash characters, or use the `\N`
+facility to suppress string expansion within the regular expression.
 
 Domains in patterns should be given in lower case. Local parts in patterns are
 case-sensitive. If you want to do case-insensitive matching of local parts, you
@@ -22298,6 +23357,8 @@ rewriting rules are scanned. For example,
 specifies that 'hatta@lookingglass.fict.example' is never to be rewritten in
 'From:' headers.
 
+cindex:[$domain$]
+cindex:[$local_part$]
 If the replacement string is not a single asterisk, it is expanded, and must
 yield a fully qualified address. Within the expansion, the variables
 $local_part$ and $domain$ refer to the address that is being rewritten.
@@ -22365,6 +23426,8 @@ before any other processing; even before syntax checking. The pattern is
 required to be a regular expression, and it is matched against the whole of the
 data for the command, including any surrounding angle brackets.
 
+cindex:[$domain$]
+cindex:[$local_part$]
 This form of rewrite rule allows for the handling of addresses that are not
 compliant with RFCs 2821 and 2822 (for example, ``bang paths'' in batched SMTP
 input). Because the input is not required to be a syntactically valid address,
@@ -22568,8 +23631,8 @@ expressions work in address lists.
 
 
 
-Choosing which retry rule to use
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+Choosing which retry rule to use for address errors
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 When Exim is looking for a retry rule after a routing attempt has failed (for
 example, after a DNS timeout), each line in the retry configuration is tested
 against the complete address only if %retry_use_local_part% is set for the
@@ -22591,12 +23654,15 @@ response for a recipient address, the whole address is used when searching the
 retry rules. The rule that is found is used to create a retry time for the
 failing address.
 
-For a temporary error that is not related to an individual address,
-(for example, a connection timeout), each line in the retry configuration is
-checked twice. First, the name of the remote host is used as a domain name
-(preceded by ``\*@'' when matching a regular expression). If this does not match
-the line, the domain from the email address is tried in a similar fashion. For
-example, suppose the MX records for 'a.b.c.example' are
+
+Choosing which retry rule to use for host errors
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+For a temporary error that is not related to an individual address (for
+example, a connection timeout), each line in the retry configuration is checked
+twice. First, the name of the remote host is used as a domain name (preceded by
+``\*@'' when matching a regular expression). If this does not match the line,
+the domain from the email address is tried in a similar fashion. For example,
+suppose the MX records for 'a.b.c.example' are
 
   a.b.c.example  MX  5  x.y.z.example
                  MX  6  p.q.r.example
@@ -22607,18 +23673,28 @@ and the retry rules are
   p.q.r.example    *      F,24h,30m;
   a.b.c.example    *      F,4d,45m;
 
-and a delivery to the host 'x.y.z.example' fails. The first rule matches
-neither the host nor the domain, so Exim looks at the second rule. This does
-not match the host, but it does match the domain, so it is used to calculate
-the retry time for the host 'x.y.z.example'. Meanwhile, Exim tries to deliver
-to 'p.q.r.example'. If this fails, the first retry rule is used, because it
-matches the host.
+and a delivery to the host 'x.y.z.example' suffers a connection failure. The
+first rule matches neither the host nor the domain, so Exim looks at the second
+rule. This does not match the host, but it does match the domain, so it is used
+to calculate the retry time for the host 'x.y.z.example'. Meanwhile, Exim tries
+to deliver to 'p.q.r.example'. If this also suffers a host error, the first
+retry rule is used, because it matches the host.
 
-In other words, failures to deliver to host 'p.q.r.example' use the first
-rule to determine retry times, but for all the other hosts for the domain
+In other words, temporary failures to deliver to host 'p.q.r.example' use the
+first rule to determine retry times, but for all the other hosts for the domain
 'a.b.c.example', the second rule is used. The second rule is also used if
 routing to 'a.b.c.example' suffers a temporary failure.
 
+[revisionflag="changed"]
+*Note*: the host name is used when matching the patterns, not its IP address.
+However, if a message is routed directly to an IP address without the use of a
+host name, for example, if a ^manualroute^ router contains a setting such as:
+
+  route_list = *.a.example  192.168.34.23
+
+then the ``host name'' that is used when searching for a retry rule is the
+textual form of the IP address.
+
 
 Retry rules for specific errors
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -22727,13 +23803,20 @@ form:
 The retry timings themselves are then the fourth item. For example:
 
 ....
-*   *   senders=:   F,1h,30m
+*   rcpt_4xx   senders=:   F,1h,30m
 ....
 
-matches all temporary errors for bounce messages sent to any host. If the
-address list contains white space, it must be enclosed in quotes. For example:
+matches 4##'xx' errors for bounce messages sent to any host. If the address
+list contains white space, it must be enclosed in quotes. For example:
 
-  a.domain  timeout  senders="xb.dom : yc.dom"  G,8h,10m,1.5
+  a.domain  auth_failed  senders="xb.dom : yc.dom"  G,8h,10m,1.5
+
+[revisionflag="changed"]
+*Warning*: This facility can be unhelpful if it is used for host errors (those
+that do not depend on the recipient). The reason is that the sender is used
+only to match the retry rule. Once the rule has been found for a host error,
+its contents are used to set a retry time for the host, and this will apply to
+all messages, not just those with specific senders.
 
 When testing retry rules using %-brt%, you can supply a sender using the %-f%
 command line option, like this:
@@ -22762,6 +23845,9 @@ time that the first failure for the domain (combined with the local part if
 relevant) was detected, not from the time the message was received.
 
 cindex:[retry,algorithms]
+cindex:[retry,fixed intervals]
+cindex:[retry,increasing intervals]
+cindex:[retry,random intervals]
 The available algorithms are:
 
 - 'F': retry at fixed intervals. There is a single time parameter specifying
@@ -22771,6 +23857,15 @@ the interval.
 specifies a starting value for the interval, and the second a multiplier, which
 is used to increase the size of the interval at each retry.
 
+[revisionflag="changed"]
+- 'H': retry at randomized intervals. The arguments are as for 'G'. For each
+retry, the previous interval is multiplied by the factor in order to get a
+maximum for the next interval. The mininum interval is the first argument of
+the parameter, and an actual interval is chosen randomly between them. Such a
+rule has been found to be helpful in cluster configurations when all the
+members of the cluster restart at once, and may therefore synchronize their
+queue processing times.
+
 When computing the next retry time, the algorithm definitions are scanned in
 order until one whose cutoff time has not yet passed is reached. This is then
 used to compute a new retry time that is later than the current time. In the
@@ -23017,15 +24112,16 @@ controlled by build-time definitions. The following are currently available,
 included by setting
 
   AUTH_CRAM_MD5=yes
+  AUTH_CYRUS_SASL=yes
   AUTH_PLAINTEXT=yes
   AUTH_SPA=yes
 
 in _Local/Makefile_, respectively. The first of these supports the CRAM-MD5
-authentication mechanism (RFC 2195), and the second can be configured to
-support the PLAIN authentication mechanism (RFC 2595) or the LOGIN mechanism,
-which is not formally documented, but used by several MUAs. The third
-authenticator supports Microsoft's 'Secure Password Authentication'
-mechanism.
+authentication mechanism (RFC 2195), and the second provides an interface to
+the Cyrus SASL authentication library. The third can be configured to support
+the PLAIN authentication mechanism (RFC 2595) or the LOGIN mechanism, which is
+not formally documented, but used by several MUAs. The fourth authenticator
+supports Microsoft's 'Secure Password Authentication' mechanism.
 
 The authenticators are configured using the same syntax as other drivers (see
 section <<SECTfordricon>>). If no authenticators are required, no authentication
@@ -23117,6 +24213,7 @@ oindex:[%server_set_id%]
 %server_set_id%, Use: 'authenticators', Type: 'string'!!, Default: 'unset'
 ===
 
+cindex:[$authenticated_id$]
 When an Exim server successfully authenticates a client, this string is
 expanded using data from the authentication, and preserved for any incoming
 messages in the variable $authenticated_id$. It is also included in the log
@@ -23156,11 +24253,12 @@ than EHLO), the use of AUTH= is a syntax error.
 
 - If the value of the AUTH= parameter is ``<>'', it is ignored.
 
-- If %acl_smtp_mailauth% is defined, the ACL it specifies is run. While it is
-running, the value of $authenticated_sender$ is set to the value obtained
-from the AUTH= parameter. If the ACL does not yield ``accept'', the value of
-$authenticated_sender$ is deleted. The %acl_smtp_mailauth% ACL may not
-return ``drop'' or ``discard''. If it defers, a temporary error code (451) is given
+- cindex:[$authenticated_sender$]
+If %acl_smtp_mailauth% is defined, the ACL it specifies is run. While it is
+running, the value of $authenticated_sender$ is set to the value obtained from
+the AUTH= parameter. If the ACL does not yield ``accept'', the value of
+$authenticated_sender$ is deleted. The %acl_smtp_mailauth% ACL may not return
+``drop'' or ``discard''. If it defers, a temporary error code (451) is given
 for the MAIL command.
 
 - If %acl_smtp_mailauth% is not defined, the value of the AUTH= parameter
@@ -23182,6 +24280,7 @@ hosts to which Exim authenticates as a client. Do not confuse this value with
 $authenticated_id$, which is a string obtained from the authentication
 process, and which is not usually a complete email address.
 
+cindex:[$sender_address$]
 Whenever an AUTH= value is ignored, the incident is logged. The ACL for
 MAIL, if defined, is run after AUTH= is accepted or ignored. It can
 therefore make use of $authenticated_sender$. The converse is not true: the
@@ -23225,6 +24324,7 @@ such as:
 
   server_advertise_condition = ${if eq{$tls_cipher}{}{no}{yes}}
 
+cindex:[$tls_cipher$]
 If the session is encrypted, $tls_cipher$ is not empty, and so the expansion
 yields ``yes'', which allows the advertisement to happen.
 
@@ -23251,12 +24351,14 @@ the appropriate authentication protocol, and authentication either succeeds or
 fails. If there is no matching advertised mechanism, the AUTH command is
 rejected with a 504 error.
 
+cindex:[$received_protocol$]
+cindex:[$sender_host_authenticated$]
 When a message is received from an authenticated host, the value of
-$received_protocol$ is set to ``esmtpa'' instead of ``esmtp'', and
-$sender_host_authenticated$ contains the name (not the public name) of the
-authenticator driver that successfully authenticated the client from which the
-message was received. This variable is empty if there was no successful
-authentication.
+$received_protocol$ is set to ``esmtpa'' or ``esmtpsa'' instead of ``esmtp'' or
+``esmtps'', and $sender_host_authenticated$ contains the name (not the public
+name) of the authenticator driver that successfully authenticated the client
+from which the message was received. This variable is empty if there was no
+successful authentication.
 
 
 
@@ -23323,7 +24425,9 @@ of these options, Exim (as a client) tries to authenticate as follows:
 authentication mechanisms announced by the server for one whose name
 matches the public name of the authenticator.
 
-- When it finds one that matches, it runs the authenticator's client code.
+- cindex:[$host$]
+cindex:[$host_address$]
+When it finds one that matches, it runs the authenticator's client code.
 The variables $host$ and $host_address$ are available for any string
 expansions that the client might do. They are set to the server's name and
 IP address. If any expansion is forced to fail, the authentication attempt
@@ -23418,15 +24522,15 @@ expansion variables $1$, $2$, etc. If there are more strings in
 command, the remaining prompts are used to obtain more data. Each response from
 the client may be a list of NUL-separated strings.
 
-Once a sufficient number of data strings have been received,
-%server_condition% is expanded.
-If the expansion is forced to fail, authentication fails. Any other expansion
-failure causes a temporary error code to be returned.
-If the result of a successful expansion is an empty string, ``0'', ``no'', or
-``false'', authentication fails. If the result of the expansion is ``1'', ``yes'', or
-``true'', authentication succeeds and the generic %server_set_id% option is
-expanded and saved in $authenticated_id$. For any other result, a temporary
-error code is returned, with the expanded string as the error text.
+cindex:[$authenticated_id$]
+Once a sufficient number of data strings have been received, %server_condition%
+is expanded. If the expansion is forced to fail, authentication fails. Any
+other expansion failure causes a temporary error code to be returned. If the
+result of a successful expansion is an empty string, ``0'', ``no'', or
+``false'', authentication fails. If the result of the expansion is ``1'',
+``yes'', or ``true'', authentication succeeds and the generic %server_set_id%
+option is expanded and saved in $authenticated_id$. For any other result, a
+temporary error code is returned, with the expanded string as the error text.
 
 *Warning*: If you use a lookup in the expansion to find the user's
 password, be sure to make the authentication fail if the user is unknown.
@@ -23677,10 +24781,10 @@ name, authentication fails.
     server_secret = ${if eq{$1}{ph10}{secret}fail}
     server_set_id = $1
 
+cindex:[$authenticated_id$]
 If authentication succeeds, the setting of %server_set_id% preserves the user
-name in $authenticated_id$.
-A more tyical configuration might look up the secret string in a file, using
-the user name as the key. For example:
+name in $authenticated_id$. A more tyical configuration might look up the
+secret string in a file, using the user name as the key. For example:
 
   lookup_cram:
     driver = cram_md5
@@ -23717,6 +24821,8 @@ This option must be set for the authenticator to work as a client. Its value is
 expanded and the result used as the secret string when computing the response.
 
 
+cindex:[$host$]
+cindex:[$host_address$]
 Different user names and secrets can be used for different servers by referring
 to $host$ or $host_address$ in the options.
 
@@ -23883,10 +24989,13 @@ cindex:[numerical variables ($1$ $2$ etc),in ^spa^ authenticator]
 This option is expanded, and the result must be the cleartext password for the
 authenticating user, whose name is at this point in $1$. For example:
 
-  spa:
-    driver = spa
-    public_name = NTLM
-    server_password = ${lookup{$1}lsearch{/etc/exim/spa_clearpass}}
+....
+spa:
+  driver = spa
+  public_name = NTLM
+  server_password = ${lookup{$1}lsearch{/etc/exim/spa_clearpass}\
+                    {$value}fail}
+....
 
 If the expansion is forced to fail, authentication fails. Any other expansion
 failure causes a temporary error code to be returned.
@@ -23964,7 +25073,7 @@ also need to understand the basic concepts of encryption at a managerial level,
 and in particular, the way that public keys, private keys, and certificates are
 used.
 
-RFC 2487 defines how SMTP connections can make use of encryption. Once a
+RFC 3207 defines how SMTP connections can make use of encryption. Once a
 connection is established, the client issues a STARTTLS command. If the
 server accepts this, the client and the server negotiate an encryption
 mechanism. If the negotiation succeeds, the data that subsequently passes
@@ -24042,23 +25151,8 @@ name of a directory (for OpenSSL it can be either).
 facility for varying its Diffie-Hellman parameters. I understand that this has
 changed, but Exim has not been updated to provide this facility.
 
-- GnuTLS uses RSA and D-H parameters that take a substantial amount of
-time to compute. It is unreasonable to re-compute them for every TLS
-session. Therefore, Exim keeps this data in a file in its spool
-directory, called _gnutls-params_. The file is owned by the Exim user and is
-readable only by its owner. Every Exim process that start up GnuTLS reads the
-RSA and D-H parameters from this file. If the file does not exist, the first
-Exim process that needs it computes the data and writes it to a temporary file
-which is renamed once it is complete. It does not matter if several Exim
-processes do this simultaneously (apart from wasting a few resources). Once a
-file is in place, new Exim processes immediately start using it.
-+
-For maximum security, the parameters that are stored in this file should be
-recalculated periodically, the frequency depending on your paranoia level.
-Arranging this is easy; just delete the file when you want new values to be
-computed.
-
-- Distinguished Name (DN) strings reported by the OpenSSL library use a slash for
+- cindex:[$tls_peerdn$]
+Distinguished Name (DN) strings reported by the OpenSSL library use a slash for
 separating fields; GnuTLS uses commas, in accordance with RFC 2253. This
 affects the value of the $tls_peerdn$ variable.
 
@@ -24071,7 +25165,59 @@ underscores for GnuTLS when processing lists of cipher suites in the
 option).
 
 - The %tls_require_ciphers% options operate differently, as described in the
-following sections.
+sections <<SECTreqciphssl>> and <<SECTreqciphgnu>>.
+
+
+GnuTLS parameter computation
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+GnuTLS uses RSA and D-H parameters that take a substantial amount of time to
+compute. It is unreasonable to re-compute them for every TLS session.
+Therefore, Exim keeps this data in a file in its spool directory, called
+_gnutls-params_. The file is owned by the Exim user and is readable only by its
+owner. Every Exim process that start up GnuTLS reads the RSA and D-H parameters
+from this file. If the file does not exist, the first Exim process that needs
+it computes the data and writes it to a temporary file which is renamed once it
+is complete. It does not matter if several Exim processes do this
+simultaneously (apart from wasting a few resources). Once a file is in place,
+new Exim processes immediately start using it.
+
+[revisionflag="changed"]
+For maximum security, the parameters that are stored in this file should be
+recalculated periodically, the frequency depending on your paranoia level.
+Arranging this is easy in principle; just delete the file when you want new
+values to be computed. However, there may be a problem. The calculation of new
+parameters needs random numbers, and these are obtained from _/dev/random_. If
+the system is not very active, _/dev/random_ may delay returning data until
+enough randomness (entropy) is available. This may cause Exim to hang for a
+substantial amount of time, causing timeouts on incoming connections.
+
+[revisionflag="changed"]
+The solution is to generate the parameters externally to Exim. They are stored
+in _gnutls-params_ in PEM format, which means that they can be generated
+externally using the ^certtool^ command that is part of GnuTLS.
+
+[revisionflag="changed"]
+To replace the parameters with new ones, instead of deleting the file
+and letting Exim re-create it, you can generate new parameters using
+^certtool^ and, when this has been done, replace Exim's cache file by
+renaming. The relevant commands are something like this:
+
+[revisionflag="changed"]
+....
+# rm -f new-params
+# touch new-params
+# chown exim:exim new-params
+# chmod 0400 new-params
+# certtool --generate-privkey --bits 512 >new-params
+# echo "" >>new-params
+# certtool --generate-dh-params --bits 1024 >> new-params
+# mv new-params gnutls-params
+....
+
+[revisionflag="changed"]
+If Exim never has to generate the parameters itself, the possibility of
+stalling is removed.
 
 
 
@@ -24238,6 +25384,7 @@ forced to fail, Exim behaves as if the option is not set.
 
 cindex:[cipher,logging]
 cindex:[log,TLS cipher]
+cindex:[$tls_cipher$]
 The variable $tls_cipher$ is set to the cipher suite that was negotiated for
 an incoming TLS connection. It is included in the 'Received:' header of an
 incoming message (by default -- you can, of course, change this), and it is
@@ -24291,6 +25438,7 @@ fact that no certificate was verified, and vary their actions accordingly. For
 example, you can insist on a certificate before accepting a message for
 relaying, but not when the message is destined for local delivery.
 
+cindex:[$tls_peerdn$]
 When a client supplies a certificate (whether it verifies or not), the value of
 the Distinguished Name of the certificate is made available in the variable
 $tls_peerdn$ during subsequent processing of the message.
@@ -24374,6 +25522,8 @@ list of permitted cipher suites. If either of these checks fails, delivery to
 the current host is abandoned, and the ^smtp^ transport tries to deliver to
 alternative hosts, if any.
 
+cindex:[$host$]
+cindex:[$host_address$]
 All the TLS options in the ^smtp^ transport are expanded before use, with
 $host$ and $host_address$ containing the name and address of the server to
 which the client is connected. Forced failure of an expansion causes Exim to
@@ -24646,16 +25796,20 @@ content-scanning extension. For details, see chapter <<CHAPexiscan>>.
 The QUIT ACL
 ~~~~~~~~~~~~
 cindex:[QUIT, ACL for]
-The ACL for the SMTP QUIT command is anomalous, in that the
-outcome of the ACL does not affect the response code to QUIT,
-which is always 221. Thus, the ACL does not in fact control any access.
-For this reason, the only verbs that are permitted are %accept% and %warn%.
+The ACL for the SMTP QUIT command is anomalous, in that the outcome of the ACL
+does not affect the response code to QUIT, which is always 221. Thus, the ACL
+does not in fact control any access. For this reason, the only verbs that are
+permitted are %accept% and %warn%.
 
 This ACL can be used for tasks such as custom logging at the end of an SMTP
 session. For example, you can use ACL variables in other ACLs to count
 messages, recipients, etc., and log the totals at QUIT time using one or
 more %logwrite% modifiers on a %warn% verb.
 
+[revisionflag="changed"]
+*Warning*: only the $acl_c$'x' variables can be used for this, because the
+$acl_m$'x' variables are reset at the end of each incoming message.
+
 You do not need to have a final %accept%, but if you do, you can use a
 %message% modifier to specify custom text that is sent as part of the 221
 response to QUIT.
@@ -24774,30 +25928,36 @@ configuration file.
 Data for message ACLs
 ~~~~~~~~~~~~~~~~~~~~~
 cindex:[{ACL},data for message ACL]
-When a MAIL or RCPT ACL, or either of the DATA ACLs, is running,
-the variables that contain information about the host and the message's sender
-(for example, $sender_host_address$ and $sender_address$) are set, and
-can be used in ACL statements. In the case of RCPT (but not MAIL or
-DATA), $domain$ and $local_part$ are set from the argument address.
+cindex:[$domain$]
+cindex:[$local_part$]
+cindex:[$sender_address$]
+cindex:[$sender_host_address$]
+When a MAIL or RCPT ACL, or either of the DATA ACLs, is running, the variables
+that contain information about the host and the message's sender (for example,
+$sender_host_address$ and $sender_address$) are set, and can be used in ACL
+statements. In the case of RCPT (but not MAIL or DATA), $domain$ and
+$local_part$ are set from the argument address.
 
 When an ACL for the AUTH parameter of MAIL is running, the variables that
 contain information about the host are set, but $sender_address$ is not yet
 set. Section <<SECTauthparamail>> contains a discussion of this parameter and
 how it is used.
 
+cindex:[$message_size$]
 The $message_size$ variable is set to the value of the SIZE parameter on
 the MAIL command at MAIL, RCPT and pre-data time, or to -1 if
 that parameter is not given. The value is updated to the true message size by
 the time the final DATA ACL is run (after the message data has been
 received).
 
-The $rcpt_count$ variable increases by one for each RCPT command
-received. The $recipients_count$ variable increases by one each time a
-RCPT command is accepted, so while an ACL for RCPT is being processed,
-it contains the number of previously accepted recipients. At DATA time (for
-both the DATA ACLs), $rcpt_count$ contains the total number of RCPT
-commands, and $recipients_count$ contains the total number of accepted
-recipients.
+cindex:[$rcpt_count$]
+cindex:[$recipients_count$]
+The $rcpt_count$ variable increases by one for each RCPT command received. The
+$recipients_count$ variable increases by one each time a RCPT command is
+accepted, so while an ACL for RCPT is being processed, it contains the number
+of previously accepted recipients. At DATA time (for both the DATA ACLs),
+$rcpt_count$ contains the total number of RCPT commands, and $recipients_count$
+contains the total number of accepted recipients.
 
 
 
@@ -24807,6 +25967,7 @@ recipients.
 Data for non-message ACLs
 ~~~~~~~~~~~~~~~~~~~~~~~~~
 cindex:[{ACL},data for non-message ACL]
+cindex:[$smtp_command_argument$]
 When an ACL is being run for AUTH, EHLO, ETRN, EXPN, HELO, STARTTLS, or VRFY,
 the remainder of the SMTP command line is placed in $smtp_command_argument$.
 This can be tested using a %condition% condition. For example, here is an ACL
@@ -24949,6 +26110,7 @@ If an identical log line is requested several times in the same message, only
 one copy is actually written to the log. If you want to force duplicates to be
 written, use the %logwrite% modifier instead.
 +
+cindex:[$acl_verify_message$]
 When one of the %warn% conditions is an address verification that fails, the
 text of the verification failure message is in $acl_verify_message$. If you
 want this logged, you must set it up explicitly. For example:
@@ -25001,13 +26163,26 @@ Condition and modifier processing
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 cindex:[{ACL},conditions; processing]
 cindex:[{ACL},modifiers; processing]
-An exclamation mark preceding a condition negates its result. For example,
+An exclamation mark preceding a condition negates its result. For example:
 
   deny   domains = *.dom.example
         !verify = recipient
 
-causes the ACL to return ``deny'' if the recipient domain ends in
-'dom.example' and the recipient address cannot be verified.
+[revisionflag="changed"]
+causes the ACL to return ``deny'' if the recipient domain ends in 'dom.example'
+and the recipient address cannot be verified. Sometimes negation can be used on
+the right-hand side of a condition. For example, these two statements are
+equivalent:
+
+[revisionflag="changed"]
+....
+deny  hosts = !192.168.3.4
+deny !hosts =  192.168.3.4
+....
+
+[revisionflag="changed"]
+However, for many conditions (%verify% being a good example), only left-hand
+side negation of the whole condition is possible.
 
 The arguments of conditions and modifiers are expanded. A forced failure
 of an expansion causes a condition to be ignored, that is, it behaves as if the
@@ -25188,6 +26363,7 @@ message. For example, the $dnslist_$<'xxx'> variables are set after a DNS
 black list lookup succeeds. If the expansion of %log_message% fails, or if the
 result is an empty string, the modifier is ignored.
 +
+cindex:[$acl_verify_message$]
 If you want to use a %warn% statement to log the result of an address
 verification, you can use $acl_verify_message$ to include the verification
 error message.
@@ -25246,13 +26422,14 @@ is expanded, backslash escapes are processed anyway. If the message contains
 newlines, this gives rise to a multi-line SMTP response. Like %log_message%,
 the contents of %message% are not expanded until after a condition has failed.
 +
+cindex:[$acl_verify_message$]
 If %message% is used on a statement that verifies an address, the message
 specified overrides any message that is generated by the verification process.
 However, the original message is available in the variable
-$acl_verify_message$, so you can incorporate it into your message if you
-wish. In particular, if you want the text from %:fail:% items in ^redirect^
-routers to be passed back as part of the SMTP response, you should either not
-use a %message% modifier, or make use of $acl_verify_message$.
+$acl_verify_message$, so you can incorporate it into your message if you wish.
+In particular, if you want the text from %:fail:% items in ^redirect^ routers
+to be passed back as part of the SMTP response, you should either not use a
+%message% modifier, or make use of $acl_verify_message$.
 
 *set*~<'acl_name'>~=~<'value'>::
 cindex:[%set%, ACL modifier]
@@ -25273,6 +26450,7 @@ See below.
 *control~=~caselower_local_part*::
 cindex:[{ACL},case of local part in]
 cindex:[case of local parts]
+cindex:[$local_part$]
 These two controls are permitted only in the ACL specified by %acl_smtp_rcpt%
 (that is, during RCPT processing). By default, the contents of $local_part$ are
 lower cased before ACL processing. If ``caseful_local_part'' is specified, any
@@ -25321,6 +26499,18 @@ before the first synchronization check. The expected use is to turn off the
 synchronization checks for badly-behaved hosts that you nevertheless need to
 work with.
 
+
+[revisionflag="changed"]
+*control~=~fakedefer/*<'message'>::
+cindex:[fake defer]
+cindex:[defer,fake]
+This control works in exactly the same way as %fakereject% (described below)
+except that it causes an SMTP 450 response after the message data instead of a
+550 response. You must take care when using %fakedefer% because it causes the
+messages to be duplicated when the sender retries. Therefore, you should not
+use %fakedefer% if the message is to be delivered normally.
+
+
 *control~=~fakereject/*<'message'>::
 cindex:[fake rejection]
 cindex:[rejection, fake]
@@ -25412,6 +26602,46 @@ the available options for this control are described there. The control applies
 only to the current message, not to any subsequent ones that may be received in
 the same SMTP connection.
 
+[revisionflag="changed"]
+*control~=~suppress_local_fixups*::
+cindex:[submission fixups,suppressing]
+This control applies to locally submitted (non TCP/IP) messages, and is the
+complement of `control = submission`. It disables the fixups that are normally
+applied to locally-submitted messages. Specifically:
++
+--
+[revisionflag="changed"]
+- Any 'Sender:' header line is left alone (in this respect, it is a
+dynamic version of %local_sender_retain%).
+
+[revisionflag="changed"]
+- No 'Message-ID:', 'From:', or 'Date:' header lines are added.
+
+[revisionflag="changed"]
+- There is no check that 'From:' corresponds to the actual sender.
+--
++
+[revisionflag="changed"]
+This feature may be useful when a remotely-originated message is accepted,
+passed to some scanning program, and then re-submitted for delivery.
+
+[revisionflag="changed"]
+All four possibilities for message fixups can be specified:
+
+[revisionflag="changed"]
+- Locally submitted, fixups applied: the default.
+
+[revisionflag="changed"]
+- Locally submitted, no fixups applied: use `control = suppress_local_fixups`.
+
+[revisionflag="changed"]
+- Remotely submitted, no fixups applied: the default.
+
+[revisionflag="changed"]
+- Remotely submitted, fixups applied: use `control = submission`.
+
+
+
 
 
 [[SECTaddheadwarn]]
@@ -25460,14 +26690,16 @@ end up in reverse order.
 added in an ACL. It does NOT work for header lines that are added in a
 system filter or in a router or transport.
 
+[revisionflag="changed"]
 cindex:[header lines,added; visibility of]
-Header lines that are added by an ACL at MAIL or RCPT time are not
-visible in string expansions in ACLs for subsequent RCPT commands or in the
+Header lines that are added by an ACL at MAIL or RCPT time are not visible in
+string expansions in ACLs for subsequent RCPT commands or in the
 %acl_smtp_predata% ACL. However, they are visible in string expansions in the
-ACL that is run after DATA is complete (the %acl_smtp_data% ACL). This is
-also true for header lines that are added in the %acl_smtp_predata% ACL.
-If a message is rejected after DATA, all added header lines are included in
-the entry that is written to the reject log.
+ACL that is run after DATA is complete (the %acl_smtp_data% ACL). This is also
+true for header lines that are added in the %acl_smtp_predata% ACL. However,
+header lines that are added in the %acl_smtp_data% itself are not visible
+during that ACL. If a message is rejected after DATA, all added header lines
+are included in the entry that is written to the reject log.
 
 If you want to preserve data between MAIL, RCPT, and the
 %acl_smtp_predata% ACLs, you can use ACL variables, as described in section
@@ -25546,6 +26778,11 @@ content-scanning extension, and it is allowed only the the ACL defined by
 %acl_smtp_mime%. It causes the current MIME part to be decoded into a file. For
 details, see chapter <<CHAPexiscan>>.
 
+*demime~=~*<'extension~list'>::
+cindex:[%demime%, ACL condition]
+This condition is available only when Exim is compiled with the
+content-scanning extension. Its use is described in section <<SECTdemimecond>>.
+
 *dnslists~=~*<'list~of~domain~names~and~other~data'>::
 cindex:[%dnslists%, ACL condition]
 cindex:[DNS list,in ACL]
@@ -25561,6 +26798,7 @@ different variants of this condition to describe briefly here. See sections
 cindex:[%domains%, ACL condition]
 cindex:[domain,ACL checking]
 cindex:[{ACL},testing a recipient domain]
+cindex:[$domain_data$]
 This condition is relevant only after a RCPT command. It checks that the domain
 of the recipient address is in the domain list. If percent-hack processing is
 enabled, it is done before this test is done. If the check succeeds with a
@@ -25604,6 +26842,7 @@ The default action on failing to find the host name is to assume that the host
 is not in the list, so the first %accept% statement fails. The second statement
 can then check the IP address.
 +
+cindex:[$host_data$]
 If a %hosts% condition is satisfied by means of a lookup, the result
 of the lookup is made available in the $host_data$ variable. This
 allows you, for example, to set up a statement like this:
@@ -25617,11 +26856,12 @@ which gives a custom error message for each denied host.
 cindex:[%local_parts%, ACL condition]
 cindex:[local part,ACL checking]
 cindex:[{ACL},testing a local part]
+cindex:[$local_part_data$]
 This condition is relevant only after a RCPT command. It checks that the local
 part of the recipient address is in the list. If percent-hack processing is
 enabled, it is done before this test. If the check succeeds with a lookup, the
-result of the lookup is placed in $local_part_data$ until the next
-%local_parts% test.
+result of the lookup is placed in $local_part_data$, which remains set until
+the next %local_parts% test.
 
 *malware~=~*<'option'>::
 cindex:[%malware%, ACL condition]
@@ -25639,6 +26879,12 @@ content-scanning extension, and it is allowed only the the ACL defined by
 %acl_smtp_mime%. It causes the current MIME part to be scanned for a match with
 any of the regular expressions. For details, see chapter <<CHAPexiscan>>.
 
+[revisionflag="changed"]
+*ratelimit~=~*<'parameters'>::
+cindex:[rate limiting]
+This condition can be used to limit the rate at which a user or host submits
+messages. Details are given in section <<SECTratelimiting>>.
+
 *recipients~=~*<'address~list'>::
 cindex:[%recipients%, ACL condition]
 cindex:[recipient,ACL checking]
@@ -25650,14 +26896,16 @@ recipient address against a list of recipients.
 cindex:[%regex%, ACL condition]
 cindex:[{ACL},testing by regex matching]
 This condition is available only when Exim is compiled with the
-content-scanning extension. It causes the incoming message to be scanned for a
-match with any of the regular expressions. For details, see chapter
-<<CHAPexiscan>>.
+content-scanning extension, and is available only in the DATA, MIME, and
+non-SMTP ACLs. It causes the incoming message to be scanned for a match with
+any of the regular expressions. For details, see chapter <<CHAPexiscan>>.
 
 *sender_domains~=~*<'domain~list'>::
 cindex:[%sender_domains%, ACL condition]
 cindex:[sender,ACL checking]
 cindex:[{ACL},testing a sender domain]
+cindex:[$domain$]
+cindex:[$sender_address_domain$]
 This condition tests the domain of the sender of the message against the given
 domain list. *Note*: the domain of the sender address is in
 $sender_address_domain$. It is 'not' put in $domain$ during the testing of this
@@ -25665,6 +26913,10 @@ condition. This is an exception to the general rule for testing domain lists.
 It is done this way so that, if this condition is used in an ACL for a RCPT
 command, the recipient's domain (which is in $domain$) can be used to influence
 the sender checking.
++
+[revisionflag="changed"]
+*Note*: it is a bad idea to use this condition on its own as a control on
+relaying, because sender addresses are easily, and commonly, forged.
 
 *senders~=~*<'address~list'>::
 cindex:[%senders%, ACL condition]
@@ -25674,6 +26926,10 @@ This condition tests the sender of the message against the given list. To test
 for a bounce message, which has an empty sender, set
 
   senders = :
++
+[revisionflag="changed"]
+*Note*: it is a bad idea to use this condition on its own as a control on
+relaying, because sender addresses are easily, and commonly, forged.
 
 *spam~=~*<'username'>::
 cindex:[%spam%, ACL condition]
@@ -25693,6 +26949,13 @@ certificate was received from the client, and the certificate was verified. The
 server requests a certificate only if the client matches %tls_verify_hosts% or
 %tls_try_verify_hosts% (see chapter <<CHAPTLS>>).
 
+[revisionflag="changed"]
+*verify~=~csa*::
+cindex:[CSA verification]
+This condition checks whether the sending host (the client) is authorized to
+send email. Details of how this works are given in section
+<<SECTverifyCSA>>.
+
 *verify~=~header_sender/*<'options'>::
 cindex:[%verify%, ACL condition]
 cindex:[{ACL},verifying sender in the header]
@@ -25739,6 +27002,7 @@ ploy used to be to send syntactically invalid headers such as
 and this condition can be used to reject such messages, though they are not as
 common as they used to be.
 
+[revisionflag="changed"]
 *verify~=~helo*::
 cindex:[%verify%, ACL condition]
 cindex:[{ACL},verifying HELO/EHLO]
@@ -25747,16 +27011,36 @@ cindex:[EHLO,verifying]
 cindex:[verifying,EHLO]
 cindex:[verifying,HELO]
 This condition is true if a HELO or EHLO command has been received from the
-client host, and its contents have been verified. Verification of these
-commands does not happen by default. See the description of the
-%helo_verify_hosts% and %helo_try_verify_hosts% options for details of how to
-request it.
+client host, and its contents have been verified. It there has been no previous
+attempt to verify the the HELO/EHLO contents, it is carried out when this
+condition is encountered. See the description of the %helo_verify_hosts% and
+%helo_try_verify_hosts% options for details of how to request verification
+independently of this condition.
+
+[revisionflag="changed"]
+*verify~=~not_blind*::
+cindex:[verifying,not blind]
+cindex:[bcc recipients,verifying none]
+This condition checks that there are no blind (bcc) recipients in the message.
+Every envelope recipient must appear either in a 'To:' header line or in a
+'Cc:' header line for this condition to be true. Local parts are checked
+case-sensitively; domains are checked case-insensitively. If 'Resent-To:' or
+'Resent-Cc:' header lines exist, they are also checked. This condition can be
+used only in a DATA or non-SMTP ACL.
++
+[revisionflag="changed"]
+There are, of course, many legitimate messages that make use of blind
+(bcc) recipients. This check should not be used on its own for blocking
+messages.
+
+
 
 *verify~=~recipient/*<'options'>::
 cindex:[%verify%, ACL condition]
 cindex:[{ACL},verifying recipient]
 cindex:[recipient,verifying]
 cindex:[verifying,recipient]
+cindex:[$address_data$]
 This condition is relevant only after a RCPT command. It verifies the current
 recipient. Details of address verification are given later, starting at section
 <<SECTaddressverification>>. After a recipient has been verified, the value of
@@ -25790,6 +27074,8 @@ message has been received (the %acl_smtp_data% or %acl_not_smtp% ACLs). If the
 message's sender is empty (that is, this is a bounce message), the condition is
 true. Otherwise, the sender address is verified.
 +
+cindex:[$address_data$]
+cindex:[$sender_address_data$]
 If there is data in the $address_data$ variable at the end of routing, its
 value is placed in $sender_address_data$ at the end of verification. This
 value can be used in subsequent conditions and modifiers in the same ACL
@@ -25881,7 +27167,7 @@ By default, the IP address that is used in a DNS list lookup is the IP address
 of the calling host. However, you can specify another IP address by listing it
 after the domain name, introduced by a slash. For example:
 
-  deny dnslists = black.list.tls/192.168.1.2
+  deny dnslists = black.list.tld/192.168.1.2
 
 This feature is not very helpful with explicit IP addresses; it is intended for
 use with IP addresses that are looked up, for example, the IP addresses of the
@@ -26017,6 +27303,9 @@ Some DNS lists may return more than one address record.
 Variables set from DNS lists
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 cindex:[DNS list,variables set from]
+cindex:[$dnslist_domain$]
+cindex:[$dnslist_text$]
+cindex:[$dnslist_value$]
 When an entry is found in a DNS list, the variable $dnslist_domain$
 contains the name of the domain that matched, $dnslist_value$ contains the
 data from the entry, and $dnslist_text$ contains the contents of any
@@ -26168,6 +27457,165 @@ You can exclude IPv6 addresses from DNS lookups by making use of a suitable
 
 
 
+[[SECTratelimiting]]
+Rate limiting senders
+~~~~~~~~~~~~~~~~~~~~~
+[revisionflag="changed"]
+cindex:[rate limiting,client sending]
+cindex:[limiting client sending rates]
+oindex:[%smpt_ratelimit_*%]
+The %ratelimit% ACL condition can be used to measure and control the rate at
+which clients can send email. This is more powerful than the %smtp_ratelimit_*%
+options, because those options control the rate of commands in a single SMTP
+session only, whereas the %ratelimit% condition works across all connections
+(concurrent and sequential) from the same client host. There's a script in
+_util/ratelimit.pl_ which extracts sending rates from log files, to assist with
+choosing appropriate settings when deploying the %ratelimit% ACL condition.
+The syntax of the %ratelimit% condition is:
+
+[revisionflag="changed"]
+&&&
+`ratelimit =` <'m'> `/` <'p'> `/` <'options'> `/` <'key'>
+&&&
+
+[revisionflag="changed"]
+If the average client sending rate is less than 'm' messages per time
+period 'p' then the condition is false; otherwise it is true.
+
+[revisionflag="changed"]
+The parameter 'p' is the smoothing time constant, in the form of an Exim
+time interval, for example, `8h` for eight hours. A larger time constant means
+that it takes Exim longer to forget a client's past behaviour. The parameter
+'m' is the maximum number of messages that a client is permitted to send in a
+fast burst. By increasing both 'm' and 'p' but keeping 'm/p' constant, you can
+allow a client to send more messages in a burst without changing its overall
+sending rate limit. Conversely, if 'm' and 'p' are both small, messages must be
+sent at an even rate.
+
+[revisionflag="changed"]
+The key is used to look up the data for calculating the client's average
+sending rate. This data is stored in a database maintained by Exim in its spool
+directory, alongside the retry and other hints databases. You can limit the
+sending rate of each authenticated user, independent of the computer they are
+sending from, by setting the key to $authenticated_id$. The default key is
+$sender_host_address$, which applies the limit to the client host, independent
+of the sender.
+
+[revisionflag="changed"]
+Internally, Exim includes the smoothing constant 'p' and the options in the
+lookup key because they alter the meaning of the stored data. This is not true
+for the limit 'm', so you can alter the configured maximum rate and Exim will
+still remember clients' past behaviour, but if you alter the other ratelimit
+parameters Exim forgets past behaviour.
+
+[revisionflag="changed"]
+Each %ratelimit% condition can have up to two options. The first option
+specifies what Exim measures the rate of, and the second specifies how Exim
+handles excessively fast clients. The options are separated by a slash, like
+the other parameters.
+
+[revisionflag="changed"]
+The %per_conn% option limits the client's connection rate. The %per_mail%
+option limits the client's rate of sending messages. This is the default if
+none of the %per_*% options is specified.
+
+[revisionflag="changed"]
+The %per_byte% option limits the sender's email bandwidth. Note that it is best
+to use this option in the DATA ACL; if it is used in an earlier ACL it relies
+on the SIZE parameter on the MAIL command, which may be inaccurate or
+completely missing. You can follow the limit 'm' in the configuration with K,
+M, or G to specify limits in kilobytes, megabytes, or gigabytes, respectively.
+
+[revisionflag="changed"]
+The %per_cmd% option causes Exim to recompute the rate every time the condition
+is processed. This can be used to limit the SMTP command rate. The alias
+%per_rcpt% is provided for use in the RCPT ACL instead of %per_cmd% to make it
+clear that the effect is to limit the rate at which recipients are accepted.
+Note that in this case the rate limiting engine will see a message with many
+recipients as a large high-speed burst.
+
+[revisionflag="changed"]
+If a client's average rate is greater than the maximum, the rate limiting
+engine can react in two possible ways, depending on the presence of the
+%strict% or %leaky% options. This is independent of the other counter-measures
+(such as rejecting the message) that may be specified by the rest of the ACL.
+The default mode is leaky, which avoids a sender's over-aggressive retry rate
+preventing it from getting any email through.
+
+[revisionflag="changed"]
+The %strict% option means that the client's recorded rate is always updated.
+The effect of this is that Exim measures the client's average rate of attempts
+to send email, which can be much higher than the maximum. If the client is over
+the limit it will be subjected to counter-measures until it slows down below
+the maximum rate. The smoothing period determines the time it takes for a high
+sending rate to decay exponentially to 37% of its peak value, which means that
+you can work out the time (the number of smoothing periods) that a client is
+subjected to counter-measures after an over-limit burst with this formula:
+
+  ln(peakrate/maxrate)
+
+[revisionflag="changed"]
+The %leaky% option means that the client's recorded rate is not updated if it
+is above the limit. The effect of this is that Exim measures the client's
+average rate of successfully sent email, which cannot be greater than the
+maximum. If the client is over the limit it will suffer some counter-measures,
+but it will still be able to send email at the configured maximum rate,
+whatever the rate of its attempts.
+
+[revisionflag="changed"]
+As a side-effect, the %ratelimit% condition sets the expansion variable
+$sender_rate$ to the client's computed rate, $sender_rate_limit$ to the
+configured value of 'm', and $sender_rate_period$ to the configured value of
+'p'.
+
+[revisionflag="changed"]
+Exim's other ACL facilities are used to define what counter-measures are taken
+when the rate limit is exceeded. This might be anything from logging a warning
+(for example, while measuring existing sending rates in order to define
+policy), through time delays to slow down fast senders, up to rejecting the
+message. For example:
+
+[revisionflag="changed"]
+....
+# Log all senders' rates
+warn
+  ratelimit = 0 / 1h / strict
+  log_message = Sender rate $sender_rate / $sender_rate_period
+
+# Slow down fast senders
+warn
+  ratelimit = 100 / 1h / per_rcpt / strict
+  delay     = ${eval: $sender_rate - $sender_rate_limit }s
+
+# Keep authenticated users under control
+deny
+  ratelimit = 100 / 1d / strict / $authenticated_id
+
+# System-wide rate limit
+defer
+  message = Sorry, too busy. Try again later.
+  ratelimit = 10 / 1s / $primary_hostname
+
+# Restrict incoming rate from each host, with a default
+# set using a macro and special cases looked up in a table.
+defer
+  message = Sender rate exceeds $sender_rate_limit \
+            messages per $sender_rate_period
+  ratelimit = ${lookup {$sender_host_address} \
+                cdb {DB/ratelimits.cdb} \
+                {$value} {RATELIMIT} }
+....
+
+[revisionflag="changed"]
+*Warning*: if you have a busy server with a lot of %ratelimit% tests,
+especially with the %per_rcpt% option, you may suffer from a performance
+bottleneck caused by locking on the ratelimit hints database. Apart from
+making your ACLs less complicated, you can reduce the problem by using a
+RAM disk for Exim's hints directory (usually _/var/spool/exim/db/_). However
+this means that Exim will lose its hints data after a reboot (including retry
+hints, the callout cache, and ratelimit data).
+
+
 
 [[SECTaddressverification]]
 Address verification
@@ -26199,13 +27647,34 @@ normally returns ``defer''. However, if you include %defer_ok% in the options,
 the condition is forced to be true instead. Note that this is a main
 verification option as well as a suboption for callouts.
 
-- The %no_details% option is covered in section <<SECTsenaddver>>, which discusses
-the reporting of sender address verification failures.
+- The %no_details% option is covered in section <<SECTsenaddver>>, which
+discusses the reporting of sender address verification failures.
+
+[revisionflag="changed"]
+- The %success_on_redirect% option causes verification always to succeed
+immediately after a successful redirection. By default, if a redirection
+generates just one address, that address is also verified. See further
+discussion in section <<SECTredirwhilveri>>.
 
+[revisionflag="changed"]
 cindex:[verifying address, differentiating failures]
-After an address verification failure, $sender_verify_failure$ or
-$recipient_verify_failure$ (as appropriate) contains one of the following
-words:
+cindex:[$recipient_verify_failure$]
+cindex:[$sender_verify_failure$]
+cindex:[$acl_verify_message$]
+After an address verification failure, $acl_verify_message$ contains the error
+message that is associated with the failure. It can be preserved by coding like
+this:
+
+  warn  !verify = sender
+         set acl_m0 = $acl_verify_message
+
+[revisionflag="changed"]
+If you are writing your own custom rejection message or log message when
+denying access, you can use this variable to include information about the
+verification failure.
+
+In addition, $sender_verify_failure$ or $recipient_verify_failure$ (as
+appropriate) contains one of the following words:
 
 - %qualify%: The address was unqualified (no domain), and the message
 was neither local nor came from an exempted host.
@@ -26220,7 +27689,6 @@ connection, HELO, or MAIL).
 
 - %postmaster%: The postmaster check in a callout was rejected.
 
-
 The main use of these variables is expected to be to distinguish between
 rejections of MAIL and rejections of RCPT in callouts.
 
@@ -26230,25 +27698,33 @@ rejections of MAIL and rejections of RCPT in callouts.
 [[SECTcallver]]
 Callout verification
 ~~~~~~~~~~~~~~~~~~~~
+[revisionflag="changed"]
 cindex:[verifying address, by callout]
 cindex:[callout,verification]
 cindex:[SMTP,callout verification]
 For non-local addresses, routing verifies the domain, but is unable to do any
 checking of the local part. There are situations where some means of verifying
 the local part is desirable. One way this can be done is to make an SMTP
-'callback' to the sending host (for a sender address) or a 'callforward' to
-a subsequent host (for a recipient address), to see if the host accepts the
-address. We use the term 'callout' to cover both cases. This facility should
-be used with care, because it can add a lot of resource usage to the cost of
-verifying an address. However, Exim does cache the results of callouts, which
-helps to reduce the cost. Details of caching are in the next section.
+'callback' to a delivery host for the sender address or a 'callforward' to a
+subsequent host for a recipient address, to see if the host accepts the
+address. We use the term 'callout' to cover both cases. Note that for a sender
+address, the callback is not to the client host that is trying to deliver the
+message, but to one of the hosts that accepts incoming mail for the sender's
+domain.
+
+[revisionflag="changed"]
+Exim does not do callouts by default. If you want them to happen, you must
+request them by setting appropriate options on the %verify% condition, as
+described below. This facility should be used with care, because it can add a
+lot of resource usage to the cost of verifying an address. However, Exim does
+cache the results of callouts, which helps to reduce the cost. Details of
+caching are in section <<SECTcallvercache>>.
 
 Recipient callouts are usually used only between hosts that are controlled by
 the same administration. For example, a corporate gateway host could use
-callouts to check for valid recipients on an internal mailserver.
-A successful callout does not guarantee that a real delivery to the address
-would succeed; on the other hand, a failing callout does guarantee that
-a delivery would fail.
+callouts to check for valid recipients on an internal mailserver. A successful
+callout does not guarantee that a real delivery to the address would succeed;
+on the other hand, a failing callout does guarantee that a delivery would fail.
 
 If the %callout% option is present on a condition that verifies an address, a
 second stage of verification occurs if the address is successfully routed to
@@ -26337,6 +27813,16 @@ When this parameter is present, failure to contact any host, or any other kind
 of temporary error, is treated as success by the ACL. However, the cache is not
 updated in this circumstance.
 
+[revisionflag="changed"]
+*fullpostmaster*::
+cindex:[callout,full postmaster check]
+This operates like the %postmaster% option (see below), but if the check for
+'postmaster@domain' fails, it tries just 'postmaster', without a domain, in
+accordance with the specification in RFC 2821. The RFC states that the
+unqualified address 'postmaster' should be accepted.
+
+
+
 *mailfrom~=~*<'email~address'>::
 cindex:[callout,sender when verifying header]
 When verifying addresses in header lines using the %header_sender% verification
@@ -26376,9 +27862,10 @@ When this parameter is given, the callout cache is neither read nor updated.
 cindex:[callout,postmaster; checking]
 When this parameter is set, a sucessful callout check is followed by a similar
 check for the local part 'postmaster' at the same domain. If this address is
-rejected, the callout fails. The result of the postmaster check is recorded in
-a cache record; if it is a failure, this is used to fail subsequent callouts
-for the domain without a connection being made, until the cache record expires.
+rejected, the callout fails (but see %fullpostmaster% above). The result of the
+postmaster check is recorded in a cache record; if it is a failure, this is
+used to fail subsequent callouts for the domain without a connection being
+made, until the cache record expires.
 
 *postmaster_mailfrom~=~*<'email~address'>::
 The postmaster check uses an empty sender in the MAIL command by default.
@@ -26419,9 +27906,12 @@ This parameter applies to recipient callouts only. For example:
 
   deny  !verify = recipient/callout=use_postmaster
 +
-It causes a non-empty postmaster address to be used in the MAIL command
-when performing the callout. The local part of the address is `postmaster`
-and the domain is the contents of $qualify_domain$.
+[revisionflag="changed"]
+cindex:[$qualify_domain$]
+It causes a non-empty postmaster address to be used in the MAIL command when
+performing the callout for the recipient, and also for a ``random'' check if
+that is configured. The local part of the address is `postmaster` and the
+domain is the contents of $qualify_domain$.
 
 *use_sender*::
 This option applies to recipient callouts only. For example:
@@ -26536,7 +28026,7 @@ example:
 
 
 
-
+[[SECTredirwhilveri]]
 Redirection while verifying
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~
 cindex:[verifying,redirection while]
@@ -26544,7 +28034,7 @@ cindex:[address redirection,while verifying]
 A dilemma arises when a local address is redirected by aliasing or forwarding
 during verification: should the generated addresses themselves be verified,
 or should the successful expansion of the original address be enough to verify
-it? Exim takes the following pragmatic approach:
+it? By default, Exim takes the following pragmatic approach:
 
 - When an incoming address is redirected to just one child address, verification
 continues with the child address, and if that fails to verify, the original
@@ -26565,6 +28055,221 @@ redirection generates more than one address, the behaviour is more like a
 mailing list, where the existence of the alias itself is sufficient for
 verification to succeed.
 
+[revisionflag="changed"]
+It is possible, however, to change the default behaviour so that all successful
+redirections count as successful verifications, however many new addresses are
+generated. This is specified by the %success_on_redirect% verification option.
+For example:
+
+[revisionflag="changed"]
+  require verify = recipient/success_on_redirect/callout=10s
+
+[revisionflag="changed"]
+In this example, verification succeeds if a router generates a new address, and
+the callout does not occur, because no address was routed to a remote host.
+
+
+
+
+
+[[SECTverifyCSA]]
+Client SMTP authorization (CSA)
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+[revisionflag="changed"]
+cindex:[CSA,verifying]
+Client SMTP Authorization is a system that allows a site to advertise
+which machines are and are not permitted to send email. This is done by placing
+special SRV records in the DNS; these are looked up using the client's HELO
+domain. At the time of writing, CSA is still an Internet Draft. Client SMTP
+Authorization checks in Exim are performed by the ACL condition:
+
+  verify = csa
+
+[revisionflag="changed"]
+This fails if the client is not authorized. If there is a DNS problem, or if no
+valid CSA SRV record is found, or if the client is authorized, the condition
+succeeds. These three cases can be distinguished using the expansion variable
+$csa_status$, which can take one of the values ``fail'', ``defer'',
+``unknown'', or ``ok''. The condition does not itself defer because that would
+be likely to cause problems for legitimate email.
+
+[revisionflag="changed"]
+The error messages produced by the CSA code include slightly more
+detail. If $csa_status$ is ``defer'', this may be because of problems
+looking up the CSA SRV record, or problems looking up the CSA target
+address record. There are four reasons for $csa_status$ being ``fail'':
+
+[revisionflag="changed"]
+- The client's host name is explicitly not authorized.
+
+[revisionflag="changed"]
+- The client's IP address does not match any of the CSA target IP addresses.
+
+[revisionflag="changed"]
+- The client's host name is authorized but it has no valid target IP addresses
+(for example, the target's addresses are IPv6 and the client is using IPv4).
+
+[revisionflag="changed"]
+- The client's host name has no CSA SRV record but a parent domain has asserted
+that all subdomains must be explicitly authorized.
+
+[revisionflag="changed"]
+The %csa% verification condition can take an argument which is the domain to
+use for the DNS query. The default is:
+
+  verify = csa/$sender_helo_name
+
+[revisionflag="changed"]
+This implementation includes an extension to CSA. If the query domain
+is an address literal such as [192.0.2.95], or if it is a bare IP
+address, Exim searches for CSA SRV records in the reverse DNS as if
+the HELO domain was (for example) '95.2.0.192.in-addr.arpa'. Therefore it is
+meaningful to say:
+
+  verify = csa/$sender_host_address
+
+[revisionflag="changed"]
+In fact, this is the check that Exim performs if the client does not say HELO.
+This extension can be turned off by setting the main configuration option
+%dns_csa_use_reverse% to be false.
+
+[revisionflag="changed"]
+If a CSA SRV record is not found for the domain itself, a search
+is performed through its parent domains for a record which might be
+making assertions about subdomains. The maximum depth of this search is limited
+using the main configuration option %dns_csa_search_limit%, which is 5 by
+default. Exim does not look for CSA SRV records in a top level domain, so the
+default settings handle HELO domains as long as seven
+('hostname.five.four.three.two.one.com'). This encompasses the vast majority of
+legitimate HELO domains.
+
+[revisionflag="changed"]
+The 'dnsdb' lookup also has support for CSA. Although 'dnsdb' also supports
+direct SRV lookups, this is not sufficient because of the extra parent domain
+search behaviour of CSA, and (as with PTR lookups) 'dnsdb' also turns IP
+addresses into lookups in the reverse DNS space. The result of a successful
+lookup such as:
+
+[revisionflag="changed"]
+....
+${lookup dnsdb {csa=$sender_helo_name}}
+....
+
+[revisionflag="changed"]
+has two space-separated fields: an authorization code and a target host name.
+The authorization code can be ``Y'' for yes, ``N'' for no, ``X'' for explicit
+authorization required but absent, or ``?'' for unknown.
+
+
+
+
+[[SECTverifyPRVS]]
+Bounce address tag validation
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+[revisionflag="changed"]
+cindex:[BATV,verifying]
+Bounce address tag validation (BATV) is a scheme whereby the envelope senders
+of outgoing messages have a cryptographic, timestamped ``tag'' added to them.
+Genuine incoming bounce messages should therefore always be addressed to
+recipients that have a valid tag. This scheme is a way of detecting unwanted
+bounce messages caused by sender address forgeries (often called ``collateral
+spam''), because the recipients of such messages will not include valid tags.
+
+[revisionflag="changed"]
+There are two expansion items to help with the implementation of the BATV
+``prvs'' (private signature) scheme in an Exim configuration. This scheme signs
+the original envelope sender address by using a simple shared key to add a hash
+of the address and some time-based randomizing information. The %prvs%
+expansion item creates a signed address, and the %prvscheck% expansion item
+checks one. The syntax of these expansion items is described in section
+<<SECTexpansionitems>>.
+
+[revisionflag="changed"]
+As an example, suppose the secret per-address keys are stored in an MySQL
+database. A query to look up the key for an address could be defined as a macro
+like this:
+
+[revisionflag="changed"]
+....
+PRVSCHECK_SQL = ${lookup mysql{SELECT secret FROM batv_prvs \
+                WHERE sender='${quote_mysql:$prvscheck_address}'\
+                }{$value}}
+....
+
+[revisionflag="changed"]
+Suppose also that the senders who make use of BATV are defined by an address
+list called %batv_senders%. Then, in the ACL for RCPT commands, you could
+use this:
+
+[revisionflag="changed"]
+....
+# Bounces: drop unsigned addresses for BATV senders
+deny message = This address does not send an unsigned reverse path.
+     senders = :
+     recipients = +batv_senders
+
+# Bounces: In case of prvs-signed address, check signature.
+deny message = Invalid reverse path signature.
+     senders = :
+     condition  = ${prvscheck {$local_part@$domain}\
+                  {PRVSCHECK_SQL}{1}}
+     !condition = $prvscheck_result
+....
+
+[revisionflag="changed"]
+The first statement rejects recipients for bounce messages that are addressed
+to plain BATV sender addresses, because it is known that BATV senders do not
+send out messages with plain sender addresses. The second statement rejects
+recipients that are prvs-signed, but with invalid signatures (either because
+the key is wrong, or the signature has timed out).
+
+[revisionflag="changed"]
+A non-prvs-signed address is not rejected by the second statement, because the
+%prvscheck% expansion yields an empty string if its first argument is not a
+prvs-signed address, thus causing the %condition% condition to be false. If the
+first argument is a syntactically valid prvs-signed address, the yield is the
+third string (in this case ``1''), whether or not the cryptographic and timeout
+checks succeed. The $prvscheck_result$ variable contains the result of the
+checks (empty for failure, ``1'' for success).
+
+[revisionflag="changed"]
+Of course, when you accept a prvs-signed address, you have to ensure that the
+routers accept it and deliver it correctly. The easiest way to handle this is
+to use a ^redirect^ router to remove the signature with a configuration along
+these lines:
+
+[revisionflag="changed"]
+....
+batv_redirect:
+  driver = redirect
+  data = ${prvscheck {$local_part@$domain}{PRVSCHECK_SQL}}
+....
+
+[revisionflag="changed"]
+This works because, if the third argument of %prvscheck% is empty, the result
+of the expansion of a prvs-signed address is the decoded value of the original
+address. This router should probably be the first of your routers that handles
+local addresses.
+
+[revisionflag="changed"]
+To create BATV-signed addresses in the first place, a transport of this form
+can be used:
+
+[revisionflag="changed"]
+....
+external_smtp_batv:
+  driver = smtp
+  return_path = ${prvs {$return_path} \
+                       {${lookup mysql{SELECT \
+                       secret FROM batv_prvs WHERE \
+                       sender='${quote_mysql:$sender_address}'} \
+                       {$value}fail}}}
+....
+
+[revisionflag="changed"]
+If no key can be found for the existing return path, no signing takes place.
+
+
 
 
 [[SECTrelaycontrol]]
@@ -26577,7 +28282,6 @@ An MTA is said to 'relay' a message if it receives it from some host and
 delivers it directly to another host as a result of a remote address contained
 within it. Redirecting a local address via an alias or forward file and then
 passing the message on to another host is not relaying,
-
 cindex:[``percent hack'']
 but a redirection as a result of the ``percent hack'' is.
 
@@ -26657,19 +28361,29 @@ results of the tests will eventually appear on your terminal.
 ////////////////////////////////////////////////////////////////////////////
 
 [[CHAPexiscan]]
-Content scanning
-----------------
-cindex:[content scanning]
-The content-scanning extension of Exim, formerly known as ``exiscan'', was
-originally implemented as a patch by Tom Kistner. The code was integrated into
-the main source for Exim release 4.50, and Tom continues to maintain it. Most
-of the wording of this chapter is taken from Tom's specification.
-
-If you want to include the content-scanning features when you compile Exim, you
-need to arrange for WITH_CONTENT_SCAN to be defined in your
+Content scanning at ACL time
+----------------------------
+cindex:[content scanning,at ACL time]
+The extension of Exim to include content scanning at ACL time, formerly known
+as ``exiscan'', was originally implemented as a patch by Tom Kistner. The code
+was integrated into the main source for Exim release 4.50, and Tom continues to
+maintain it. Most of the wording of this chapter is taken from Tom's
+specification.
+
+[revisionflag="changed"]
+It is also possible to scan the content of messages at other times. The
+'local_scan()' function (see chapter <<CHAPlocalscan>>) allows for content
+scanning after all the ACLs have run. A transport filter can be used to scan
+messages at delivery time (see the %transport_filter% option, described in
+chapter <<CHAPtransportgeneric>>).
+
+If you want to include the ACL-time content-scanning features when you compile
+Exim, you need to arrange for WITH_CONTENT_SCAN to be defined in your
 _Local/Makefile_. When you do that, the Exim binary is built with:
 
-- An additional ACL (%acl_smtp_mime%) that is run for all MIME parts.
+[revisionflag="changed"]
+- Two additional ACLs (%acl_smtp_mime% and %acl_not_smtp_mime%) that are run for
+all MIME parts for SMTP and non-SMTP messages, respectively.
 
 - Additional ACL conditions and modifiers: %decode%, %malware%, %mime_regex%,
 %regex%, and %spam%. These can be used in the ACL that is run at the end of
@@ -26750,10 +28464,11 @@ the path to the daemon's UNIX socket. The default is shown in this example:
 %clamd%::
 cindex:[virus scanners,clamd]
 This daemon-type scanner is GPL and free. You can get it at
-*http://www.clamav.net/[]*. Clamd does not seem to unpack MIME containers, so
-it is recommended to unpack MIME attachments in the MIME ACL. It takes one
-option: either the path and name of a UNIX socket file, or a hostname or IP
-number, and a port, separated by space, as in the second of these examples:
+*http://www.clamav.net/[]*. Some older versions of clamd do not seem to unpack
+MIME containers, so it used to be recommended to unpack MIME attachments in the
+MIME ACL. This no longer believed to be necessary. One option is required:
+either the path and name of a UNIX socket file, or a hostname or IP number, and
+a port, separated by space, as in the second of these examples:
 
   av_scanner = clamd:/opt/clamd/socket
   av_scanner = clamd:192.168.2.100 1234
@@ -26801,7 +28516,7 @@ av_scanner = cmdline:\
 cindex:[virus scanners,DrWeb]
 The DrWeb daemon scanner (*http://www.sald.com/[]*) interface takes one
 argument, either a full path to a UNIX socket, or an IP address and port
-separated by whitespace, as in these examples:
+separated by white space, as in these examples:
 
   av_scanner = drweb:/var/run/drwebd.sock
   av_scanner = drweb:192.168.2.20 31337
@@ -26859,14 +28574,16 @@ the option.
 End of list
 ///
 
+[revisionflag="changed"]
 When %av_scanner% is correctly set, you can use the %malware% condition in the
-DATA ACL. The %av_scanner% option is expanded each time %malware% is
-called. This makes it possible to use different scanners. See further below for
-an example. The %malware% condition caches its results, so when you use it
-multiple times for the same message, the actual scanning process is only
-carried out once. However, using expandable items in %av_scanner% disables
-this caching, in which case each use of the %malware% condition causes a new
-scan of the message.
+DATA ACL. *Note*: you cannot use the %malware% condition in the MIME ACL.
+
+The %av_scanner% option is expanded each time %malware% is called. This makes
+it possible to use different scanners. See further below for an example. The
+%malware% condition caches its results, so when you use it multiple times for
+the same message, the actual scanning process is only carried out once.
+However, using expandable items in %av_scanner% disables this caching, in which
+case each use of the %malware% condition causes a new scan of the message.
 
 The %malware% condition takes a right-hand argument that is expanded before
 use. It can then be one of
@@ -26957,7 +28674,6 @@ address/port pair:
 
   spamd_address = /var/run/spamd_socket
 
-
 You can have multiple %spamd% servers to improve scalability. These can reside
 on other hardware reachable over the network. To specify multiple %spamd%
 servers, put multiple address/port pairs in the %spamd_address% option,
@@ -26969,15 +28685,17 @@ spamd_address = 192.168.2.10 783 : \
                 192.168.2.12 783
 ....
 
-Up to 32 %spamd% servers are supported. The servers are
-queried in a random fashion. When a server fails to respond
-to the connection attempt, all other servers are tried
-until one succeeds. If no server responds, the %spam%
+Up to 32 %spamd% servers are supported. The servers are queried in a random
+fashion. When a server fails to respond to the connection attempt, all other
+servers are tried until one succeeds. If no server responds, the %spam%
 condition defers.
 
 *Warning*: It is not possible to use the UNIX socket connection method with
 multiple %spamd% servers.
 
+
+Calling SpamAssassin from an Exim ACL
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 Here is a simple example of the use of the %spam% condition in a DATA ACL:
 
   deny message = This message was classified as SPAM
@@ -26986,14 +28704,27 @@ Here is a simple example of the use of the %spam% condition in a DATA ACL:
 The right-hand side of the %spam% condition specifies the username that
 SpamAssassin should scan for. If you do not want to scan for a particular user,
 but rather use the SpamAssassin system-wide default profile, you can scan for
-an unknown user, or simply use ``nobody''. However, you must put something on the
-right-hand side.
+an unknown user, or simply use ``nobody''. However, you must put something on
+the right-hand side.
 
 The username allows you to use per-domain or per-user antispam profiles. The
 right-hand side is expanded before being used, so you can put lookups or
 conditions there. When the right-hand side evaluates to ``0'' or ``false'', no
 scanning is done and the condition fails immediately.
 
+[revisionflag="changed"]
+Scanning with SpamAssassin uses a lot of resources. If you scan every message,
+large ones may cause significant performance degredation. As most spam messages
+are quite small, it is recommended that you do not scan the big ones. For
+example:
+
+[revisionflag="changed"]
+....
+deny message = This message was classified as SPAM
+     condition = ${if < {$message_size}{10K}}
+     spam = nobody
+....
+
 The %spam% condition returns true if the threshold specified in the user's
 SpamAssassin profile has been matched or exceeded. If you want to use the
 %spam% condition for its side effects (see the variables below), you can make
@@ -27070,24 +28801,39 @@ condition:
 [[SECTscanmimepart]]
 Scanning MIME parts
 ~~~~~~~~~~~~~~~~~~~
+[revisionflag="changed"]
 cindex:[content scanning,MIME parts]
 cindex:[MIME content scanning]
 cindex:[%acl_smtp_mime%]
-The %acl_smtp_mime% global option defines an ACL that is called once for each
-MIME part of a message, including multipart types, in the sequence of their
-position in the message.
+The %acl_smtp_mime% global option specifies an ACL that is called once for each
+MIME part of an SMTP message, including multipart types, in the sequence of
+their position in the message. Similarly, the %acl_not_smtp_mime% option
+specifies an ACL that is used for the MIME parts of non-SMTP messages. These
+options may both refer to the same ACL if you want the same processing in both
+cases.
+
+[revisionflag="changed"]
+These ACLs are called (possibly many times) just before the %acl_smtp_data% ACL
+in the case of an SMTP message, or just before a non-SMTP message is accepted.
+However, a MIME ACL is called only if the message contains a 'MIME-Version:'
+header line. When a call to a MIME ACL does not yield ``accept'', ACL
+processing is aborted and the appropriate result code is sent to the client. In
+the case of an SMTP message, the %acl_smtp_data% ACL is not called when this
+happens.
 
-This ACL is called (possibly many times) just before the %acl_smtp_data% ACL,
-but only if the message has a 'MIME-Version:' header. When a call to the MIME
-ACL does not yield ``accept'', ACL processing is aborted and the appropriate
-result code is sent to the remote client. The %acl_smtp_data% ACL is not
-called in this circumstance.
+[revisionflag="changed"]
+You cannot use the %malware% or %spam% conditions in a MIME ACL; these can only
+be used in the DATA or non-SMTP ACLs. However, you can use the %regex%
+condition to match against the raw MIME part. You can also use the %mime_regex%
+condition to match against the decoded MIME part (see section
+<<SECTscanregex>>).
 
-At the start of the MIME ACL, a number of variables are set from the header
+At the start of a MIME ACL, a number of variables are set from the header
 information for the relevant MIME part. These are described below. The contents
 of the MIME part are not by default decoded into a disk file except for MIME
-parts whose content-type is ``message/rfc822''. If you want to decode a MIME part
-into a disk file, you can use the %decode% modifier. The general syntax is:
+parts whose content-type is ``message/rfc822''. If you want to decode a MIME
+part into a disk file, you can use the %decode% modifier. The general syntax
+is:
 
   decode = [/<path>/]<filename>
 
@@ -27300,11 +29046,12 @@ The demime condition
 cindex:[content scanning,MIME checking]
 cindex:[MIME content scanning]
 The %demime% ACL condition provides MIME unpacking, sanity checking and file
-extension blocking. It uses a simpler interface to MIME decoding than the MIME
-ACL functionality, but provides no additional facilities. Please note that this
-condition is deprecated and kept only for for backward compatibility. You must
-set the WITH_OLD_DEMIME option in _Local/Makefile_ at build time to be
-able to use the %demime% condition.
+extension blocking. It is usable only in the DATA and non-SMTP ACLs. The
+%demime% condition uses a simpler interface to MIME decoding than the MIME ACL
+functionality, but provides no additional facilities. Please note that this
+condition is deprecated and kept only for backward compatibility. You must set
+the WITH_OLD_DEMIME option in _Local/Makefile_ at build time to be able to use
+the %demime% condition.
 
 The %demime% condition unpacks MIME containers in the message. It detects
 errors in MIME containers and can match file extensions found in the message
@@ -27331,14 +29078,18 @@ zero (``0''), no demimeing is done and the condition is false.
 The %demime% condition set the following variables:
 
 $demime_errorlevel$::
+cindex:[$demime_errorlevel$]
 When an error is detected in a MIME container, this variable contains the
 severity of the error, as an integer number. The higher the value, the more
-severe the error. If this variable is unset or zero, no error occurred.
+severe the error (the current maximum value is 3). If this variable is unset or
+zero, no error occurred.
 
 $demime_reason$::
+cindex:[$demime_reason$]
 When $demime_errorlevel$ is greater than zero, this variable contains a
 human-readable text string describing the MIME error that occurred.
 
+cindex:[$found_extension$]
 $found_extension$::
 When the %demime% condition is true, this variable contains the file extension
 it found.
@@ -27490,6 +29241,7 @@ string at the end of the function. The value it points to on entry is NULL.
 The function must return an %int% value which is one of the following macros:
 
 `LOCAL_SCAN_ACCEPT`::
+cindex:[$local_scan_data$]
 The message is accepted. If you pass back a string of text, it is saved with
 the message, and made available in the variable $local_scan_data$. No
 newlines are permitted (if there are any, they are turned into spaces) and the
@@ -27904,7 +29656,7 @@ match the specification, the function does nothing.
 
 *BOOL~header_testname(header_line~{star}hdr,~uschar~{star}name,~int~length,~BOOL~notdel)*::
 This function tests whether the given header has the given name. It is not just
-a string comparison, because whitespace is permitted between the name and the
+a string comparison, because white space is permitted between the name and the
 colon. If the %notdel% argument is true, a false return is forced for all
 ``deleted'' headers; otherwise they are not treated specially. For example:
 
@@ -27956,12 +29708,13 @@ expected to be
 
   lss_match_host(sender_host_name, sender_host_address, ...)
 +
-An empty address field matches an empty item in the host list. If the
-host name is NULL, the name corresponding to $sender_host_address$ is
-automatically looked up if a host name is required to match an item in the
-list. The return values are as for 'lss_match_domain()', but in addition,
-'lss_match_host()' returns ERROR in the case when it had to look up a host
-name, but the lookup failed.
+cindex:[$sender_host_address$]
+An empty address field matches an empty item in the host list. If the host name
+is NULL, the name corresponding to $sender_host_address$ is automatically
+looked up if a host name is required to match an item in the list. The return
+values are as for 'lss_match_domain()', but in addition, 'lss_match_host()'
+returns ERROR in the case when it had to look up a host name, but the lookup
+failed.
 
 *void~log_write(unsigned~int~selector,~int~which,~char~{star}format,~...)*::
 This function writes to Exim's log files. The first argument should be zero (it
@@ -28155,6 +29908,8 @@ If you want your filter to do something only once per message, you can make use
 of the %first_delivery% condition in an %if% command in the filter to prevent
 it happening on retries.
 
+cindex:[$domain$]
+cindex:[$local_part$]
 *Warning*: Because the system filter runs just once, variables that are
 specific to individual recipient addresses, such as $local_part$ and
 $domain$, are not set, and the ``personal'' condition is not meaningful. If you
@@ -28226,6 +29981,7 @@ which users' filter files can refer.
 
 Additional variable for system filters
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+cindex:[$recipients$]
 The expansion variable $recipients$, containing a list of all the recipients
 of the message (separated by commas and white space), is available in system
 filters. It is not available in users' filters for privacy reasons.
@@ -28403,6 +30159,8 @@ address if its delivery failed.
 [[SECTperaddfil]]
 Per-address filtering
 ~~~~~~~~~~~~~~~~~~~~~
+cindex:[$domain$]
+cindex:[$local_part$]
 In contrast to the system filter, which is run just once per message for each
 delivery attempt, it is also possible to set up a system-wide filtering
 operation that runs once for each recipient address. In this case, variables
@@ -28468,24 +30226,27 @@ that there are appropriate entries in your ACLs.
 [[SECTsubmodnon]]
 Submission mode for non-local messages
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+[revisionflag="changed"]
 cindex:[message,submission]
 cindex:[submission mode]
-Processing that happens automatically for locally-originated messages can also
-be requested for other messages. The term ``submission mode'' is used to describe
-this state. Submisssion mode is set by the modifier
+Processing that happens automatically for locally-originated messages (unless
+%suppress_local_fixups% is set) can also be requested for messages that are
+received over TCP/IP. The term ``submission mode'' is used to describe this
+state. Submisssion mode is set by the modifier
 
   control = submission
 
-in a MAIL, RCPT, or pre-data ACL for an incoming SMTP message (see
-sections <<SECTACLmodi>> and <<SECTcontrols>>). This makes Exim treat the message
-as a local submission, and is normally used when the source of the message is
-known to be an MUA running on a client host (as opposed to an MTA). For
-example, to set submission mode for messages originating on the IPv4 loopback
-interface, you could include the following in the MAIL ACL:
+in a MAIL, RCPT, or pre-data ACL for an incoming message (see sections
+<<SECTACLmodi>> and <<SECTcontrols>>). This makes Exim treat the message as a
+local submission, and is normally used when the source of the message is known
+to be an MUA running on a client host (as opposed to an MTA). For example, to
+set submission mode for messages originating on the IPv4 loopback interface,
+you could include the following in the MAIL ACL:
 
   warn  hosts = 127.0.0.1
         control = submission
 
+cindex:[%sender_retain%]
 There are some options that can be used when setting submission mode. A slash
 is used to separate options. For example:
 
@@ -28499,16 +30260,57 @@ sender. With this setting, Exim still fixes up messages by adding 'Date:' and
 'Message-ID:' header lines if they are missing, but makes no attempt to check
 sender authenticity in header lines.
 
-A submission mode setting may also specify a domain to be used when generating
-a 'From:' or 'Sender:' header. For example:
+When %sender_retain% is not set, a submission mode setting may specify a domain
+to be used when generating a 'From:' or 'Sender:' header line. For example:
 
   control = submission/domain=some.domain
 
+[revisionflag="changed"]
 The domain may be empty. How this value is used is described in sections
-<<SECTthefrohea>> and <<SECTthesenhea>>.
+<<SECTthefrohea>> and <<SECTthesenhea>>. There is also a %name% option that
+allows you to specify the user's full name for inclusion in a created
+'Sender:' or 'From:' header line. For example:
 
+[revisionflag="changed"]
+....
+accept authenticated = *
+       control = submission/domain=wonderland.example/\
+                            name=${lookup {$authenticated_id} \
+                                   lsearch {/etc/exim/namelist}}
+....
 
+[revisionflag="changed"]
+Because the name may contain any characters, including slashes, the %name%
+option must be given last. The remainder of the string is used as the name. For
+the example above, if _/etc/exim/namelist_ contains:
+
+[revisionflag="changed"]
+....
+bigegg:  Humpty Dumpty
+....
 
+[revisionflag="changed"]
+then when the sender has authenticated as 'bigegg', the generated 'Sender:'
+line would be:
+
+[revisionflag="changed"]
+....
+Sender: Humpty Dumpty <bigegg@wonderland.example>
+....
+
+[revisionflag="changed"]
+cindex:[return path,in submission mode]
+By default, submission mode forces the return path to the same address as is
+used to create the 'Sender:' header. However, if %sender_retain% is specified,
+the return path is also left unchanged.
+
+[revisionflag="changed"]
+*Note*: the changes caused by submission mode take effect after the predata
+ACL. This means that any sender checks performed before the fix-ups use the
+untrusted sender address specified by the user, not the trusted sender address
+specified by submission mode. Although this might be slightly unexpected, it
+does mean that you can configure ACL checks to spot that a user is trying to
+spoof another's address.
 
 
 [[SECTlineendings]]
@@ -28687,11 +30489,11 @@ existing 'Bcc:' is not removed.
 
 The Date: header line
 ~~~~~~~~~~~~~~~~~~~~~
+[revisionflag="changed"]
 cindex:['Date:' header line]
-If a locally-generated
-or submission-mode
-message has no 'Date:' header line, Exim adds one, using the current date and
-time.
+If a locally-generated or submission-mode message has no 'Date:' header line,
+Exim adds one, using the current date and time, unless the
+%suppress_local_fixups% control has been specified.
 
 
 The Delivery-date: header line
@@ -28731,9 +30533,11 @@ one if either of the following conditions is true:
 - The envelope sender address is not empty (that is, this is not a bounce
 message). The added header line copies the envelope sender address.
 
-- The SMTP session is authenticated and $authenticated_id$ is not empty.
+- cindex:[$authenticated_id$]
+The SMTP session is authenticated and $authenticated_id$ is not empty.
 
-.. If no domain is specified by the submission control, the local part is
+.. cindex:[$qualify_domain$]
+If no domain is specified by the submission control, the local part is
 $authenticated_id$ and the domain is $qualify_domain$.
 
 .. If a non-empty domain is specified by the submission control, the local